c-typeck.c (build_function_call): Set fundecl = function again.

2005-06-20  Daniel Berlin  <dberlin@dberlin.org>

	* c-typeck.c (build_function_call): Set fundecl = function again.
	* tree-ssa-alias.c (find_used_portions): Address taking causes the
	entire variable to be used.
	* tree-ssa-structalias.c (do_structure_copy): Fix handling of
	unknown size variables, and structure copies from addressof
	operations.  Simplify how we do *a = *b type structure copies.
	(init_base_vars): Add ANYTHING = &ANYTHING constraint the right
	way.  READONLY's address is not taken by default.
	INTEGER dereference should point to anything.
	(create_variable_info_for): It's okay for the first field to not start
	at 0.

From-SVN: r101227
This commit is contained in:
Daniel Berlin 2005-06-21 00:59:17 +00:00 committed by Daniel Berlin
parent 83fbfe42c2
commit a5eadacc35
5 changed files with 121 additions and 18 deletions

View File

@ -1,3 +1,17 @@
2005-06-20 Daniel Berlin <dberlin@dberlin.org>
* c-typeck.c (build_function_call): Set fundecl = function again.
* tree-ssa-alias.c (find_used_portions): Address taking causes the
entire variable to be used.
* tree-ssa-structalias.c (do_structure_copy): Fix handling of
unknown size variables, and structure copies from addressof
operations. Simplify how we do *a = *b type structure copies.
(init_base_vars): Add ANYTHING = &ANYTHING constraint the right
way. READONLY's address is not taken by default.
INTEGER dereference should point to anything.
(create_variable_info_for): It's okay for the first field to not start
at 0.
2005-06-20 Kaz Kojima <kkojima@gcc.gnu.org>
config/sh/linux.h (FUNCTION_PROFILER): Constify a char*.

View File

@ -1990,6 +1990,7 @@ build_function_call (tree function, tree params)
return tem;
name = DECL_NAME (function);
fundecl = function;
}
function = default_function_array_conversion (function);

View File

@ -0,0 +1,31 @@
typedef struct JSObject JSObject;
typedef struct JSObjectMap *(*JSNewObjectMapOp) (JSObject *obj);
typedef JSObject *(*JSGetMethodOp) (JSObject *obj);
struct JSObjectOps {
JSNewObjectMapOp newObjectMap;
};
struct JSXMLObjectOps {
struct JSObjectOps base;
JSGetMethodOp getMethod;
};
struct JSObjectMap {
struct JSObjectOps *ops;
};
struct JSObject {
struct JSObjectMap *map;
};
struct JSXMLObjectOps js_XMLObjectOps;
/* We need to create SFT's for the entire structure when this address is taken,
not just the part in the component reference itself. */
JSObject *JS_GetMethod(JSObject *obj)
{
if (obj->map->ops == &js_XMLObjectOps.base) {
struct JSXMLObjectOps *ops;
ops = (struct JSXMLObjectOps *) obj->map->ops;
obj = ops->getMethod(obj);
}
return obj;
}

View File

@ -3119,6 +3119,35 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
}
}
break;
/* This is here to make sure we mark the entire base variable as used
when you take its address. Because our used portion analysis is
simple, we aren't looking at casts or pointer arithmetic to see what
happens when you take the address. */
case ADDR_EXPR:
{
tree var = get_base_address (TREE_OPERAND (*tp, 0));
if (var
&& DECL_P (var)
&& DECL_SIZE (var)
&& var_can_have_subvars (var)
&& TREE_CODE (DECL_SIZE (var)) == INTEGER_CST)
{
used_part_t up;
size_t uid = var_ann (var)->uid;
up = get_or_create_used_part_for (uid);
up->minused = 0;
up->maxused = TREE_INT_CST_LOW (DECL_SIZE (var));
up->implicit_uses = true;
used_portions[uid] = up;
*walk_subtrees = 0;
return NULL_TREE;
}
}
break;
case VAR_DECL:
case PARM_DECL:
{

View File

@ -2210,8 +2210,7 @@ do_simple_structure_copy (const struct constraint_expr lhs,
const unsigned HOST_WIDE_INT size)
{
varinfo_t p = get_varinfo (lhs.var);
unsigned HOST_WIDE_INT pstart,last;
unsigned HOST_WIDE_INT pstart, last;
pstart = p->offset;
last = p->offset + size;
for (; p && p->offset < last; p = p->next)
@ -2321,8 +2320,6 @@ do_structure_copy (tree lhsop, tree rhsop)
unsigned HOST_WIDE_INT lhssize;
unsigned HOST_WIDE_INT rhssize;
lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
lhs = get_constraint_for (lhsop);
rhs = get_constraint_for (rhsop);
@ -2334,8 +2331,18 @@ do_structure_copy (tree lhsop, tree rhsop)
rhs = tmp;
}
/* If the RHS is a special var, set all the LHS fields to that
special var. */
/* This is fairly conservative for the RHS == ADDRESSOF case, in that it's
possible it's something we could handle. However, most cases falling
into this are dealing with transparent unions, which are slightly
weird. */
if (rhs.type == ADDRESSOF && rhs.var > integer_id)
{
rhs.type = ADDRESSOF;
rhs.var = anything_id;
}
/* If the RHS is a special var, or an addressof, set all the LHS fields to
that special var. */
if (rhs.var <= integer_id)
{
for (p = get_varinfo (lhs.var); p; p = p->next)
@ -2351,6 +2358,20 @@ do_structure_copy (tree lhsop, tree rhsop)
}
else
{
/* The size only really matters insofar as we don't set more or less of
the variable. If we hit an unknown size var, the size should be the
whole darn thing. */
if (get_varinfo (rhs.var)->is_unknown_size_var)
rhssize = ~0;
else
rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
if (get_varinfo (lhs.var)->is_unknown_size_var)
lhssize = ~0;
else
lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
if (rhs.type == SCALAR && lhs.type == SCALAR)
do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
else if (lhs.type != DEREF && rhs.type == DEREF)
@ -2363,13 +2384,11 @@ do_structure_copy (tree lhsop, tree rhsop)
tree pointertype = TREE_TYPE (rhsdecl);
tree pointedtotype = TREE_TYPE (pointertype);
tree tmpvar;
gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
lhs = get_constraint_for (tmpvar);
do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
rhs = lhs;
lhs = get_constraint_for (lhsop);
do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
do_structure_copy (tmpvar, rhsop);
do_structure_copy (lhsop, tmpvar);
}
}
}
@ -2786,7 +2805,6 @@ create_variable_info_for (tree decl, const char *name)
}
field = fo->field;
gcc_assert (bitpos_of_field (field) == 0);
vi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
{
@ -3049,8 +3067,10 @@ init_base_vars (void)
rhs.var = anything_id;
rhs.offset = 0;
var_anything->address_taken = true;
process_constraint (new_constraint (lhs, rhs));
/* This specifically does not use process_constraint because
process_constraint ignores all anything = anything constraints, since all
but this one are redundant. */
VEC_safe_push (constraint_t, gc, constraints, new_constraint (lhs, rhs));
/* Create the READONLY variable, used to represent that a variable
points to readonly memory. */
@ -3075,7 +3095,6 @@ init_base_vars (void)
rhs.type = ADDRESSOF;
rhs.var = anything_id;
rhs.offset = 0;
var_readonly->address_taken = true;
process_constraint (new_constraint (lhs, rhs));
@ -3091,6 +3110,16 @@ init_base_vars (void)
var_integer->next = NULL;
integer_id = 3;
VEC_safe_push (varinfo_t, gc, varmap, var_integer);
/* *INTEGER = ANYTHING, because we don't know where a dereference of a random
integer will point to. */
lhs.type = SCALAR;
lhs.var = integer_id;
lhs.offset = 0;
rhs.type = ADDRESSOF;
rhs.var = anything_id;
rhs.offset = 0;
process_constraint (new_constraint (lhs, rhs));
}
@ -3102,7 +3131,6 @@ create_alias_vars (void)
{
basic_block bb;
init_alias_vars ();
constraint_pool = create_alloc_pool ("Constraint pool",