+2013-09-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58459
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr): Remove
+ restriction not propagating into loops.
+
2013-09-26 Florian Weimer <fw@deneb.enyo.de>
* tree-ssa.h (walk_use_def_chains_fn, walk_use_def_chains): Delete.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre" } */
+
+typedef struct {
+ unsigned int key;
+} S;
+typedef struct s1 {
+ unsigned int key;
+ unsigned int bits;
+ struct s1 *left, *right;
+}S1;
+extern S a[1024];
+static inline int bar( S* p, S1* n )
+{
+ S1 *curr;
+ S1 *next;
+
+ if ( n->left == n )
+ return (int)(p->key == n->key);
+
+ curr = n;
+ next = n->left;
+
+ while (curr->bits > next->bits ) {
+ curr = next;
+ if (p->key & (1 << curr->bits))
+ next = curr->right;
+ else
+ next = curr->left;
+ }
+
+ return (int)(p->key == next->key);
+
+}
+
+int foo (S1 *root, int N)
+{
+ volatile int r;
+ int i,j;
+ for (i=0; i<N; i++)
+ for (j=0;j<1024; j++)
+ r = bar(&a[j], root);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "key" 4 "pre" } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
static bool
forward_propagate_addr_expr (tree name, tree rhs)
{
- int stmt_loop_depth = bb_loop_depth (gimple_bb (SSA_NAME_DEF_STMT (name)));
imm_use_iterator iter;
gimple use_stmt;
bool all = true;
/* If the use is not in a simple assignment statement, then
there is nothing we can do. */
- if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
+ if (!is_gimple_assign (use_stmt))
{
if (!is_gimple_debug (use_stmt))
all = false;
continue;
}
- /* If the use is in a deeper loop nest, then we do not want
- to propagate non-invariant ADDR_EXPRs into the loop as that
- is likely adding expression evaluations into the loop. */
- if (bb_loop_depth (gimple_bb (use_stmt)) > stmt_loop_depth
- && !is_gimple_min_invariant (rhs))
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+ result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
+ single_use_p);
+ /* If the use has moved to a different statement adjust
+ the update machinery for the old statement too. */
+ if (use_stmt != gsi_stmt (gsi))
{
- all = false;
- continue;
+ update_stmt (use_stmt);
+ use_stmt = gsi_stmt (gsi);
}
-
- {
- gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
- result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
- single_use_p);
- /* If the use has moved to a different statement adjust
- the update machinery for the old statement too. */
- if (use_stmt != gsi_stmt (gsi))
- {
- update_stmt (use_stmt);
- use_stmt = gsi_stmt (gsi);
- }
-
- update_stmt (use_stmt);
- }
+ update_stmt (use_stmt);
all &= result;
/* Remove intermediate now unused copy and conversion chains. */