diff options
author | Steven Bosscher <stevenb@suse.de> | 2005-05-12 22:13:00 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2005-05-12 22:13:00 +0000 |
commit | 0995a441f572b99071e2ab2b256c027e4a19e217 (patch) | |
tree | 354efb3b7fe79e6c570a46275544956edce4638f | |
parent | 02f20dc3fdfe1031a02b856ce6a7cc283ea49cf1 (diff) | |
download | gcc-0995a441f572b99071e2ab2b256c027e4a19e217.zip gcc-0995a441f572b99071e2ab2b256c027e4a19e217.tar.gz gcc-0995a441f572b99071e2ab2b256c027e4a19e217.tar.bz2 |
re PR tree-optimization/21520 (missing PRE opportunity with operand after operand)
Fix PR tree-optimization/21520
* tree-ssa-pre.c (phi_translate): Use fully_constant_expression
to attempt to fold constants.
From-SVN: r99632
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr21532.c | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 54 |
3 files changed, 57 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5e5e6f..fb42b57 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-05-12 Steven Bosscher <stevenb@suse.de> + + Fix PR tree-optimization/21520 + * tree-ssa-pre.c (phi_translate): Use fully_constant_expression + to attempt to fold constants. + 2005-05-12 Kaz Kojima <kkojima@gcc.gnu.org> * config/sh/sh.c: Declare the prototype of sh_adjust_unroll_max diff --git a/gcc/testsuite/gcc.c-torture/compile/pr21532.c b/gcc/testsuite/gcc.c-torture/compile/pr21532.c new file mode 100644 index 0000000..1b8bc22 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr21532.c @@ -0,0 +1,14 @@ + + +int +bar (unsigned char key) +{ + unsigned char buf[sizeof (unsigned long)+2]; + unsigned char b; + unsigned char *buf_ = buf + 1; + + for (b = 8; b != 0; b--) + buf_[b] = key >> b; + + return foo (b); +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index f2e14a7..0494774 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -842,6 +842,19 @@ debug_value_set (value_set_t set, const char *setname, int blockindex) print_value_set (stderr, set, setname, blockindex); } +/* Return the folded version of T if T, when folded, is a gimple + min_invariant. Otherwise, return T. */ + +static tree +fully_constant_expression (tree t) +{ + tree folded; + folded = fold (t); + if (folded && is_gimple_min_invariant (folded)) + return folded; + return t; +} + /* Translate EXPR using phis in PHIBLOCK, so that it has the values of the phis in PRED. Return NULL if we can't find a leader for each part of the translated expression. */ @@ -889,12 +902,22 @@ phi_translate (tree expr, value_set_t set, basic_block pred, return NULL; if (newop1 != oldop1 || newop2 != oldop2) { + tree t; newexpr = pool_alloc (binary_node_pool); memcpy (newexpr, expr, tree_size (expr)); - create_tree_ann (newexpr); TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1); TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2); - vn_lookup_or_add (newexpr, NULL); + t = fully_constant_expression (newexpr); + if (t != newexpr) + { + pool_free (binary_node_pool, newexpr); + newexpr = t; + } + else + { + create_tree_ann (newexpr); + vn_lookup_or_add (newexpr, NULL); + } expr = newexpr; phi_trans_add (oldexpr, newexpr, pred); } @@ -913,11 +936,21 @@ phi_translate (tree expr, value_set_t set, basic_block pred, return NULL; if (newop1 != oldop1) { + tree t; newexpr = pool_alloc (unary_node_pool); memcpy (newexpr, expr, tree_size (expr)); - create_tree_ann (newexpr); TREE_OPERAND (newexpr, 0) = get_value_handle (newop1); - vn_lookup_or_add (newexpr, NULL); + t = fully_constant_expression (newexpr); + if (t != newexpr) + { + pool_free (unary_node_pool, newexpr); + newexpr = t; + } + else + { + create_tree_ann (newexpr); + vn_lookup_or_add (newexpr, NULL); + } expr = newexpr; phi_trans_add (oldexpr, newexpr, pred); } @@ -1412,19 +1445,6 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) return name; } -/* Return the folded version of T if T, when folded, is a gimple - min_invariant. Otherwise, return T. */ - -static tree -fully_constant_expression (tree t) -{ - tree folded; - folded = fold (t); - if (folded && is_gimple_min_invariant (folded)) - return folded; - return t; -} - /* Insert the to-be-made-available values of NODE for each predecessor, stored in AVAIL, into the predecessors of BLOCK, and merge the result with a phi node, given the same value handle as NODE. The prefix of the phi node is |