This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix PR tree-optimization/21520, testcase for 21532
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 12 May 2005 18:12:24 -0400
- Subject: [PATCH]: Fix PR tree-optimization/21520, testcase for 21532
This is Steven Bosscher's patch to fix PR 21520, and other missed PRE
optimizations that are due to folding (though probably not all of them).
Folding during phi translation allows us to eliminate a lot more
redundant expressions.
I've also added the testcase for 21532 that would happen with this
patch, but without the last one.
Bootstrapped and regtested on i686-pc-linux-gnu, applied to mainline.
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.
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-pre.c,v
retrieving revision 2.85
diff -u -p -r2.85 tree-ssa-pre.c
--- tree-ssa-pre.c 12 May 2005 17:11:16 -0000 2.85
+++ tree-ssa-pre.c 12 May 2005 22:09:32 -0000
@@ -842,6 +842,19 @@ debug_value_set (value_set_t set, const
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 se
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 se
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
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
Index: testsuite/gcc.c-torture/compile/pr21532.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr21532.c
diff -N testsuite/gcc.c-torture/compile/pr21532.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/compile/pr21532.c 12 May 2005 22:09:39 -0000
@@ -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);
+}