Commit 6569d386 by Eric Botcazou Committed by Eric Botcazou

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
parent ce41c38b
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> 2009-06-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
PR target/40482 PR target/40482
......
...@@ -2473,6 +2473,36 @@ tree_node_structure (const_tree t) ...@@ -2473,6 +2473,36 @@ tree_node_structure (const_tree t)
gcc_unreachable (); 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 /* 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. */ or offset that depends on a field within a record. */
...@@ -2660,7 +2690,7 @@ substitute_in_expr (tree exp, tree f, tree r) ...@@ -2660,7 +2690,7 @@ substitute_in_expr (tree exp, tree f, tree r)
{ {
enum tree_code code = TREE_CODE (exp); enum tree_code code = TREE_CODE (exp);
tree op0, op1, op2, op3; tree op0, op1, op2, op3;
tree new_tree, inner; tree new_tree;
/* We handle TREE_LIST and COMPONENT_REF separately. */ /* We handle TREE_LIST and COMPONENT_REF separately. */
if (code == TREE_LIST) if (code == TREE_LIST)
...@@ -2673,27 +2703,32 @@ substitute_in_expr (tree exp, tree f, tree r) ...@@ -2673,27 +2703,32 @@ substitute_in_expr (tree exp, tree f, tree r)
return tree_cons (TREE_PURPOSE (exp), op1, op0); return tree_cons (TREE_PURPOSE (exp), op1, op0);
} }
else if (code == COMPONENT_REF) else if (code == COMPONENT_REF)
{ {
/* If this expression is getting a value from a PLACEHOLDER_EXPR tree inner;
and it is the right field, replace it with R. */
for (inner = TREE_OPERAND (exp, 0); /* If this expression is getting a value from a PLACEHOLDER_EXPR
REFERENCE_CLASS_P (inner); and it is the right field, replace it with R. */
inner = TREE_OPERAND (inner, 0)) for (inner = TREE_OPERAND (exp, 0);
; REFERENCE_CLASS_P (inner);
if (TREE_CODE (inner) == PLACEHOLDER_EXPR inner = TREE_OPERAND (inner, 0))
&& TREE_OPERAND (exp, 1) == f) ;
return r;
/* The field. */
/* If this expression hasn't been completed let, leave it alone. */ op1 = TREE_OPERAND (exp, 1);
if (TREE_CODE (inner) == PLACEHOLDER_EXPR && TREE_TYPE (inner) == 0)
return exp; if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
return r;
op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
if (op0 == TREE_OPERAND (exp, 0)) /* If this expression hasn't been completed let, leave it alone. */
return exp; if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
return exp;
new_tree = fold_build3 (COMPONENT_REF, TREE_TYPE (exp),
op0, TREE_OPERAND (exp, 1), NULL_TREE); 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 else
switch (TREE_CODE_CLASS (code)) switch (TREE_CODE_CLASS (code))
...@@ -2754,7 +2789,8 @@ substitute_in_expr (tree exp, tree f, tree r) ...@@ -2754,7 +2789,8 @@ substitute_in_expr (tree exp, tree f, tree r)
&& op3 == TREE_OPERAND (exp, 3)) && op3 == TREE_OPERAND (exp, 3))
return exp; 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; break;
default: default:
...@@ -2764,23 +2800,28 @@ substitute_in_expr (tree exp, tree f, tree r) ...@@ -2764,23 +2800,28 @@ substitute_in_expr (tree exp, tree f, tree r)
case tcc_vl_exp: case tcc_vl_exp:
{ {
tree copy = NULL_TREE;
int i; int i;
new_tree = NULL_TREE;
for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++) for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
{ {
tree op = TREE_OPERAND (exp, i); tree op = TREE_OPERAND (exp, i);
tree new_op = SUBSTITUTE_IN_EXPR (op, f, r); tree new_op = SUBSTITUTE_IN_EXPR (op, f, r);
if (new_op != op) if (new_op != op)
{ {
if (!copy) if (!new_tree)
copy = copy_node (exp); new_tree = copy_node (exp);
TREE_OPERAND (copy, i) = new_op; TREE_OPERAND (new_tree, i) = new_op;
} }
} }
if (copy) if (new_tree)
new_tree = fold (copy); {
new_tree = fold (new_tree);
if (TREE_CODE (new_tree) == CALL_EXPR)
process_call_operands (new_tree);
}
else else
return exp; return exp;
} }
...@@ -2790,7 +2831,7 @@ substitute_in_expr (tree exp, tree f, tree r) ...@@ -2790,7 +2831,7 @@ substitute_in_expr (tree exp, tree f, tree r)
gcc_unreachable (); gcc_unreachable ();
} }
TREE_READONLY (new_tree) = TREE_READONLY (exp); TREE_READONLY (new_tree) |= TREE_READONLY (exp);
return new_tree; return new_tree;
} }
...@@ -2802,6 +2843,7 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2802,6 +2843,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
{ {
enum tree_code code = TREE_CODE (exp); enum tree_code code = TREE_CODE (exp);
tree op0, op1, op2, op3; tree op0, op1, op2, op3;
tree new_tree;
/* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type /* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
in the chain of OBJ. */ in the chain of OBJ. */
...@@ -2877,8 +2919,9 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2877,8 +2919,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj); op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
if (op0 == TREE_OPERAND (exp, 0)) if (op0 == TREE_OPERAND (exp, 0))
return exp; return exp;
else
return fold_build1 (code, TREE_TYPE (exp), op0); new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
break;
case 2: case 2:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj); op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
...@@ -2886,8 +2929,9 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2886,8 +2929,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)) if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
return exp; 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: case 3:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj); op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
...@@ -2897,8 +2941,9 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2897,8 +2941,9 @@ substitute_placeholder_in_expr (tree exp, tree obj)
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1) if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
&& op2 == TREE_OPERAND (exp, 2)) && op2 == TREE_OPERAND (exp, 2))
return exp; 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: case 4:
op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj); op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
...@@ -2910,8 +2955,10 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2910,8 +2955,10 @@ substitute_placeholder_in_expr (tree exp, tree obj)
&& op2 == TREE_OPERAND (exp, 2) && op2 == TREE_OPERAND (exp, 2)
&& op3 == TREE_OPERAND (exp, 3)) && op3 == TREE_OPERAND (exp, 3))
return exp; 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: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -2920,30 +2967,39 @@ substitute_placeholder_in_expr (tree exp, tree obj) ...@@ -2920,30 +2967,39 @@ substitute_placeholder_in_expr (tree exp, tree obj)
case tcc_vl_exp: case tcc_vl_exp:
{ {
tree copy = NULL_TREE;
int i; int i;
new_tree = NULL_TREE;
for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++) for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
{ {
tree op = TREE_OPERAND (exp, i); tree op = TREE_OPERAND (exp, i);
tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj); tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
if (new_op != op) if (new_op != op)
{ {
if (!copy) if (!new_tree)
copy = copy_node (exp); new_tree = copy_node (exp);
TREE_OPERAND (copy, i) = new_op; TREE_OPERAND (new_tree, i) = new_op;
} }
} }
if (copy) if (new_tree)
return fold (copy); {
new_tree = fold (new_tree);
if (TREE_CODE (new_tree) == CALL_EXPR)
process_call_operands (new_tree);
}
else else
return exp; return exp;
} }
break;
default: default:
gcc_unreachable (); 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 /* 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) ...@@ -8183,41 +8239,6 @@ build_omp_clause (location_t loc, enum omp_clause_code code)
return t; 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 /* 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. 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 Except for the CODE and operand count field, other storage for the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment