diff options
author | Olivier Hainque <hainque@act-europe.fr> | 2003-04-16 23:33:19 +0200 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2003-04-16 17:33:19 -0400 |
commit | a9ecacf6c44316e20d54c36f84ae80dedfff09e6 (patch) | |
tree | d54db0fbb9e85319256be0471da62b0bf8117eb6 /gcc/tree.c | |
parent | 15b19a7dbf433b1936eecd042ce7dedbb23220f9 (diff) | |
download | gcc-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.c | 82 |
1 files changed, 52 insertions, 30 deletions
@@ -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. */ |