aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2009-06-19 21:33:21 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2009-06-19 21:33:21 +0000
commit6569d386e28bb84135413af40c470d238a7fea54 (patch)
treedfb7b06c5ec8138aeeeb8d117e191a4058bd79e9
parentce41c38bfcb5f4f45791fd13b52dcd687834c818 (diff)
downloadgcc-6569d386e28bb84135413af40c470d238a7fea54.zip
gcc-6569d386e28bb84135413af40c470d238a7fea54.tar.gz
gcc-6569d386e28bb84135413af40c470d238a7fea54.tar.bz2
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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/tree.c179
2 files changed, 109 insertions, 79 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8de4e56..c946499 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/tree.c b/gcc/tree.c
index f48512f..139c1e5 100644
--- a/gcc/tree.c
+++ b/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;
-
- /* If this expression hasn't been completed let, leave it alone. */
- if (TREE_CODE (inner) == PLACEHOLDER_EXPR && TREE_TYPE (inner) == 0)
- 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, TREE_OPERAND (exp, 1), NULL_TREE);
+ {
+ tree inner;
+
+ /* 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))
+ ;
+
+ /* The field. */
+ op1 = TREE_OPERAND (exp, 1);
+
+ 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