tree.c (substitute_in_expr): Tweak and reformat.
* tree.c (substitute_in_expr) <COMPONENT_REF>: Tweak and reformat. <tcc_vl_exp>: Call process_call_operands on the new CALL_EXPR. Propagate the TREE_READONLY flag without overwriting it. (substitute_placeholder_in_expr) <tcc_vl_exp>: Likewise. Propagate the TREE_READONLY flag onto the result. (process_call_operands): Move around. Use correct constant value. From-SVN: r148729
This commit is contained in:
parent
ce41c38bfc
commit
6569d386e2
@ -1,3 +1,12 @@
|
||||
2009-06-19 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* tree.c (substitute_in_expr) <COMPONENT_REF>: Tweak and reformat.
|
||||
<tcc_vl_exp>: Call process_call_operands on the new CALL_EXPR.
|
||||
Propagate the TREE_READONLY flag without overwriting it.
|
||||
(substitute_placeholder_in_expr) <tcc_vl_exp>: Likewise.
|
||||
Propagate the TREE_READONLY flag onto the result.
|
||||
(process_call_operands): Move around. Use correct constant value.
|
||||
|
||||
2009-06-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||
|
||||
PR target/40482
|
||||
|
173
gcc/tree.c
173
gcc/tree.c
@ -2473,6 +2473,36 @@ tree_node_structure (const_tree t)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Set various status flags when building a CALL_EXPR object T. */
|
||||
|
||||
static void
|
||||
process_call_operands (tree t)
|
||||
{
|
||||
bool side_effects = TREE_SIDE_EFFECTS (t);
|
||||
int i;
|
||||
|
||||
if (!side_effects)
|
||||
for (i = 1; i < TREE_OPERAND_LENGTH (t); i++)
|
||||
{
|
||||
tree op = TREE_OPERAND (t, i);
|
||||
if (op && TREE_SIDE_EFFECTS (op))
|
||||
{
|
||||
side_effects = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!side_effects)
|
||||
{
|
||||
/* Calls have side-effects, except those to const or pure functions. */
|
||||
i = call_expr_flags (t);
|
||||
if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
|
||||
side_effects = true;
|
||||
}
|
||||
|
||||
TREE_SIDE_EFFECTS (t) = side_effects;
|
||||
}
|
||||
|
||||
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
|
||||
or offset that depends on a field within a record. */
|
||||
@ -2660,7 +2690,7 @@ substitute_in_expr (tree exp, tree f, tree r)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (exp);
|
||||
tree op0, op1, op2, op3;
|
||||
tree new_tree, inner;
|
||||
tree new_tree;
|
||||
|
||||
/* We handle TREE_LIST and COMPONENT_REF separately. */
|
||||
if (code == TREE_LIST)
|
||||
@ -2673,27 +2703,32 @@ substitute_in_expr (tree exp, tree f, tree r)
|
||||
return tree_cons (TREE_PURPOSE (exp), op1, op0);
|
||||
}
|
||||
else if (code == COMPONENT_REF)
|
||||
{
|
||||
/* If this expression is getting a value from a PLACEHOLDER_EXPR
|
||||
and it is the right field, replace it with R. */
|
||||
for (inner = TREE_OPERAND (exp, 0);
|
||||
REFERENCE_CLASS_P (inner);
|
||||
inner = TREE_OPERAND (inner, 0))
|
||||
;
|
||||
if (TREE_CODE (inner) == PLACEHOLDER_EXPR
|
||||
&& TREE_OPERAND (exp, 1) == f)
|
||||
return r;
|
||||
{
|
||||
tree inner;
|
||||
|
||||
/* If this expression hasn't been completed let, leave it alone. */
|
||||
if (TREE_CODE (inner) == PLACEHOLDER_EXPR && TREE_TYPE (inner) == 0)
|
||||
return exp;
|
||||
/* If this expression is getting a value from a PLACEHOLDER_EXPR
|
||||
and it is the right field, replace it with R. */
|
||||
for (inner = TREE_OPERAND (exp, 0);
|
||||
REFERENCE_CLASS_P (inner);
|
||||
inner = TREE_OPERAND (inner, 0))
|
||||
;
|
||||
|
||||
op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
|
||||
if (op0 == TREE_OPERAND (exp, 0))
|
||||
return exp;
|
||||
/* The field. */
|
||||
op1 = TREE_OPERAND (exp, 1);
|
||||
|
||||
new_tree = fold_build3 (COMPONENT_REF, TREE_TYPE (exp),
|
||||
op0, TREE_OPERAND (exp, 1), NULL_TREE);
|
||||
if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
|
||||
return r;
|
||||
|
||||
/* If this expression hasn't been completed let, leave it alone. */
|
||||
if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
|
||||
return exp;
|
||||
|
||||
op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
|
||||
if (op0 == TREE_OPERAND (exp, 0))
|
||||
return exp;
|
||||
|
||||
new_tree
|
||||
= fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
|
||||
}
|
||||
else
|
||||
switch (TREE_CODE_CLASS (code))
|
||||
@ -2754,7 +2789,8 @@ substitute_in_expr (tree exp, tree f, tree r)
|
||||
&& op3 == TREE_OPERAND (exp, 3))
|
||||
return exp;
|
||||
|
||||
new_tree = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
|
||||
new_tree
|
||||
= fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2764,23 +2800,28 @@ substitute_in_expr (tree exp, tree f, tree r)
|
||||
|
||||
case tcc_vl_exp:
|
||||
{
|
||||
tree copy = NULL_TREE;
|
||||
int i;
|
||||
|
||||
new_tree = NULL_TREE;
|
||||
|
||||
for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
|
||||
{
|
||||
tree op = TREE_OPERAND (exp, i);
|
||||
tree new_op = SUBSTITUTE_IN_EXPR (op, f, r);
|
||||
if (new_op != op)
|
||||
{
|
||||
if (!copy)
|
||||
copy = copy_node (exp);
|
||||
TREE_OPERAND (copy, i) = new_op;
|
||||
if (!new_tree)
|
||||
new_tree = copy_node (exp);
|
||||
TREE_OPERAND (new_tree, i) = new_op;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
new_tree = fold (copy);
|
||||
if (new_tree)
|
||||
{
|
||||
new_tree = fold (new_tree);
|
||||
if (TREE_CODE (new_tree) == CALL_EXPR)
|
||||
process_call_operands (new_tree);
|
||||
}
|
||||
else
|
||||
return exp;
|
||||
}
|
||||
@ -2790,7 +2831,7 @@ substitute_in_expr (tree exp, tree f, tree r)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
TREE_READONLY (new_tree) = TREE_READONLY (exp);
|
||||
TREE_READONLY (new_tree) |= TREE_READONLY (exp);
|
||||
return new_tree;
|
||||
}
|
||||
|
||||
@ -2802,6 +2843,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (exp);
|
||||
tree op0, op1, op2, op3;
|
||||
tree new_tree;
|
||||
|
||||
/* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
|
||||
in the chain of OBJ. */
|
||||
@ -2877,8 +2919,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
|
||||
if (op0 == TREE_OPERAND (exp, 0))
|
||||
return exp;
|
||||
else
|
||||
return fold_build1 (code, TREE_TYPE (exp), op0);
|
||||
|
||||
new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
|
||||
@ -2886,8 +2929,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
|
||||
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
|
||||
return exp;
|
||||
else
|
||||
return fold_build2 (code, TREE_TYPE (exp), op0, op1);
|
||||
|
||||
new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
|
||||
@ -2897,8 +2941,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
|
||||
&& op2 == TREE_OPERAND (exp, 2))
|
||||
return exp;
|
||||
else
|
||||
return fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
|
||||
|
||||
new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
|
||||
@ -2910,8 +2955,10 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
&& op2 == TREE_OPERAND (exp, 2)
|
||||
&& op3 == TREE_OPERAND (exp, 3))
|
||||
return exp;
|
||||
else
|
||||
return fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
|
||||
|
||||
new_tree
|
||||
= fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
@ -2920,30 +2967,39 @@ substitute_placeholder_in_expr (tree exp, tree obj)
|
||||
|
||||
case tcc_vl_exp:
|
||||
{
|
||||
tree copy = NULL_TREE;
|
||||
int i;
|
||||
|
||||
new_tree = NULL_TREE;
|
||||
|
||||
for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
|
||||
{
|
||||
tree op = TREE_OPERAND (exp, i);
|
||||
tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
|
||||
if (new_op != op)
|
||||
{
|
||||
if (!copy)
|
||||
copy = copy_node (exp);
|
||||
TREE_OPERAND (copy, i) = new_op;
|
||||
if (!new_tree)
|
||||
new_tree = copy_node (exp);
|
||||
TREE_OPERAND (new_tree, i) = new_op;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
return fold (copy);
|
||||
if (new_tree)
|
||||
{
|
||||
new_tree = fold (new_tree);
|
||||
if (TREE_CODE (new_tree) == CALL_EXPR)
|
||||
process_call_operands (new_tree);
|
||||
}
|
||||
else
|
||||
return exp;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
TREE_READONLY (new_tree) |= TREE_READONLY (exp);
|
||||
return new_tree;
|
||||
}
|
||||
|
||||
/* Stabilize a reference so that we can use it any number of times
|
||||
@ -8183,41 +8239,6 @@ build_omp_clause (location_t loc, enum omp_clause_code code)
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Set various status flags when building a CALL_EXPR object T. */
|
||||
|
||||
static void
|
||||
process_call_operands (tree t)
|
||||
{
|
||||
bool side_effects;
|
||||
|
||||
side_effects = TREE_SIDE_EFFECTS (t);
|
||||
if (!side_effects)
|
||||
{
|
||||
int i, n;
|
||||
n = TREE_OPERAND_LENGTH (t);
|
||||
for (i = 1; i < n; i++)
|
||||
{
|
||||
tree op = TREE_OPERAND (t, i);
|
||||
if (op && TREE_SIDE_EFFECTS (op))
|
||||
{
|
||||
side_effects = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!side_effects)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Calls have side-effects, except those to const or
|
||||
pure functions. */
|
||||
i = call_expr_flags (t);
|
||||
if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
|
||||
side_effects = 1;
|
||||
}
|
||||
TREE_SIDE_EFFECTS (t) = side_effects;
|
||||
}
|
||||
|
||||
/* Build a tcc_vl_exp object with code CODE and room for LEN operands. LEN
|
||||
includes the implicit operand count in TREE_OPERAND 0, and so must be >= 1.
|
||||
Except for the CODE and operand count field, other storage for the
|
||||
|
Loading…
Reference in New Issue
Block a user