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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 28 | ||||
-rw-r--r-- | gcc/stor-layout.c | 5 | ||||
-rw-r--r-- | gcc/tree.c | 82 | ||||
-rw-r--r-- | gcc/tree.h | 10 |
5 files changed, 83 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb692cf..19fdf5a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2003-04-16 Olivier Hainque <hainque@act-europe.fr> + * 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. + * expr.c (store_field): Force usage of bitfield instructions when the field position requires it, whatever SLOW_UNALIGNED_ACCESS. (expand_expr, case BIT_FIELD_REF): likewise. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 065a4fc..fa64fd2 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4568,21 +4568,19 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p) false_value = convert (testtype, integer_zero_node); } - /* If ARG is complex we want to make sure we only evaluate - it once. Though this is only required if it is volatile, it - might be more efficient even if it is not. However, if we - succeed in folding one part to a constant, we do not need - to make this SAVE_EXPR. Since we do this optimization - primarily to see if we do end up with constant and this - SAVE_EXPR interferes with later optimizations, suppressing - it when we can is important. - - If we are not in a function, we can't make a SAVE_EXPR, so don't - try to do so. Don't try to see if the result is a constant - if an arm is a COND_EXPR since we get exponential behavior - in that case. */ - - if (TREE_CODE (arg) == SAVE_EXPR) + /* If ARG is complex we want to make sure we only evaluate it once. Though + this is only required if it is volatile, it might be more efficient even + if it is not. However, if we succeed in folding one part to a constant, + we do not need to make this SAVE_EXPR. Since we do this optimization + primarily to see if we do end up with constant and this SAVE_EXPR + interferes with later optimizations, suppressing it when we can is + important. + + If we are not in a function, we can't make a SAVE_EXPR, so don't try to + do so. Don't try to see if the result is a constant if an arm is a + COND_EXPR since we get exponential behavior in that case. */ + + if (saved_expr_p (arg)) save = 1; else if (lhs == 0 && rhs == 0 && !TREE_CONSTANT (arg) diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 7ebdda8..66067d6 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -128,10 +128,7 @@ put_pending_size (expr) { /* Strip any simple arithmetic from EXPR to see if it has an underlying SAVE_EXPR. */ - while (TREE_CODE_CLASS (TREE_CODE (expr)) == '1' - || (TREE_CODE_CLASS (TREE_CODE (expr)) == '2' - && TREE_CONSTANT (TREE_OPERAND (expr, 1)))) - expr = TREE_OPERAND (expr, 0); + expr = skip_simple_arithmetic (expr); if (TREE_CODE (expr) == SAVE_EXPR) pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes); @@ -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. */ @@ -2681,6 +2681,16 @@ extern int lvalue_or_else PARAMS ((tree, const char *)); extern tree save_expr PARAMS ((tree)); +/* Look inside EXPR and into any simple arithmetic operations. Return + the innermost non-arithmetic node. */ + +extern tree skip_simple_arithmetic PARAMS ((tree)); + +/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a + SAVE_EXPR. Return FALSE otherwise. */ + +extern bool saved_expr_p PARAMS ((tree)); + /* Returns the index of the first non-tree operand for CODE, or the number of operands if all are trees. */ |