aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@act-europe.fr>2003-04-16 23:33:19 +0200
committerRichard Kenner <kenner@gcc.gnu.org>2003-04-16 17:33:19 -0400
commita9ecacf6c44316e20d54c36f84ae80dedfff09e6 (patch)
treed54db0fbb9e85319256be0471da62b0bf8117eb6 /gcc/tree.c
parent15b19a7dbf433b1936eecd042ce7dedbb23220f9 (diff)
downloadgcc-a9ecacf6c44316e20d54c36f84ae80dedfff09e6.zip
gcc-a9ecacf6c44316e20d54c36f84ae80dedfff09e6.tar.gz
gcc-a9ecacf6c44316e20d54c36f84ae80dedfff09e6.tar.bz2
tree.c (skip_simple_arithmetics_at, [...]): New functions.
* tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions. (save_expr): Replace loop by call to skip_simple_arithmetics_at. * tree.h: Add prototypes for the two new functions. * fold-const.c (fold_binary_op_with_conditional_arg): Replace test updates introduced in the previous revision by call to saved_expr_p. * stor-layout.c (put_pending_size): Use skip_simple_arithmetics_at. From-SVN: r65702
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 09c239e..ce5e219 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1379,34 +1379,7 @@ save_expr (expr)
tree expr;
{
tree t = fold (expr);
- tree inner;
-
- /* We don't care about whether this can be used as an lvalue in this
- context. */
- while (TREE_CODE (t) == NON_LVALUE_EXPR)
- t = TREE_OPERAND (t, 0);
-
- /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
- a constant, it will be more efficient to not make another SAVE_EXPR since
- it will allow better simplification and GCSE will be able to merge the
- computations if they actually occur. */
- inner = t;
- while (1)
- {
- if (TREE_CODE_CLASS (TREE_CODE (inner)) == '1')
- inner = TREE_OPERAND (inner, 0);
- else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
- {
- if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
- inner = TREE_OPERAND (inner, 0);
- else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
- inner = TREE_OPERAND (inner, 1);
- else
- break;
- }
- else
- break;
- }
+ tree inner = skip_simple_arithmetic (t);
/* If the tree evaluates to a constant, then we don't want to hide that
fact (i.e. this allows further folding, and direct checks for constants).
@@ -1419,7 +1392,7 @@ save_expr (expr)
|| TREE_CODE (inner) == ERROR_MARK)
return t;
- /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
+ /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
it means that the size or offset of some field of an object depends on
the value within another field.
@@ -1428,7 +1401,7 @@ save_expr (expr)
evaluated more than once. Front-ends must assure this case cannot
happen by surrounding any such subexpressions in their own SAVE_EXPR
and forcing evaluation at the proper time. */
- if (contains_placeholder_p (t))
+ if (contains_placeholder_p (inner))
return t;
t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);
@@ -1441,6 +1414,55 @@ save_expr (expr)
return t;
}
+/* Look inside EXPR and into any simple arithmetic operations. Return
+ the innermost non-arithmetic node. */
+
+tree
+skip_simple_arithmetic (expr)
+ tree expr;
+{
+ tree inner;
+
+ /* We don't care about whether this can be used as an lvalue in this
+ context. */
+ while (TREE_CODE (expr) == NON_LVALUE_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
+ a constant, it will be more efficient to not make another SAVE_EXPR since
+ it will allow better simplification and GCSE will be able to merge the
+ computations if they actually occur. */
+ inner = expr;
+ while (1)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (inner)) == '1')
+ inner = TREE_OPERAND (inner, 0);
+ else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
+ {
+ if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
+ inner = TREE_OPERAND (inner, 0);
+ else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
+ inner = TREE_OPERAND (inner, 1);
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ return inner;
+}
+
+/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a
+ SAVE_EXPR. Return FALSE otherwise. */
+
+bool
+saved_expr_p (expr)
+ tree expr;
+{
+ return TREE_CODE (skip_simple_arithmetic (expr)) == SAVE_EXPR;
+}
+
/* Arrange for an expression to be expanded multiple independent
times. This is useful for cleanup actions, as the backend can
expand them multiple times in different places. */