diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17f9b2b8217..65b1fb359cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-01-26 Richard Biener + + PR tree-optimization/69452 + * tree-ssa-loop-im.c (move_computations_dom_walker): Remove. + (move_computations_dom_walker::before_dom_children): Rename + to ... + (move_computations_worker): This. + (move_computations): Perform an RPO rather than a DOM walk. + 2016-01-26 Jakub Jelinek PR target/69442 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67bc4e4cf57..ec6456afc32 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-26 Richard Biener + + PR tree-optimization/69452 + * gcc.dg/torture/pr69452.c: New testcase. + 2016-01-26 Jakub Jelinek PR target/69442 diff --git a/gcc/testsuite/gcc.dg/torture/pr69452.c b/gcc/testsuite/gcc.dg/torture/pr69452.c new file mode 100644 index 00000000000..8bd931dd457 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr69452.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ + +short a, f, h; +struct S0 { + int f0; +} b; +char c, d, e, j, k; +int g; +char fn1(char p1, int p2) { return 7 >> p2 ? p1 : p2; } +void fn2() { + int l, m, n; + struct S0 o = {0}; + for (;;) { + int p = 1, r = e; + unsigned q = 6; + l = r == 0 ? q : q % r; + n = l; + c = f; + k = fn1(p, n ^ e); + char s = k; + j = s / 6; + if (j) { + int t = d, u = m = d ? t : t / d; + h = a || u; + b.f0 = h; + for (; d;) + ; + } else { + b = o; + if (d != g) + for (;;) + ; + } + } +} diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index e1b22de74bc..ec0fb7fcb46 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1112,15 +1112,16 @@ public: data stored in LIM_DATA structures associated with each statement. Callback for walk_dominator_tree. */ -edge -move_computations_dom_walker::before_dom_children (basic_block bb) +unsigned int +move_computations_worker (basic_block bb) { struct loop *level; unsigned cost = 0; struct lim_aux_data *lim_data; + unsigned int todo = 0; if (!loop_outer (bb->loop_father)) - return NULL; + return todo; for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi); ) { @@ -1171,7 +1172,7 @@ move_computations_dom_walker::before_dom_children (basic_block bb) gimple_cond_lhs (cond), gimple_cond_rhs (cond)); new_stmt = gimple_build_assign (gimple_phi_result (stmt), COND_EXPR, t, arg0, arg1); - todo_ |= TODO_cleanup_cfg; + todo |= TODO_cleanup_cfg; } if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (new_stmt))) && (!ALWAYS_EXECUTED_IN (bb) @@ -1266,7 +1267,8 @@ move_computations_dom_walker::before_dom_children (basic_block bb) else gsi_insert_on_edge (e, stmt); } - return NULL; + + return todo; } /* Hoist the statements out of the loops prescribed by data stored in @@ -1275,14 +1277,20 @@ move_computations_dom_walker::before_dom_children (basic_block bb) static unsigned int move_computations (void) { - move_computations_dom_walker walker (CDI_DOMINATORS); - walker.walk (cfun->cfg->x_entry_block_ptr); + int *rpo = XNEWVEC (int, last_basic_block_for_fn (cfun)); + int n = pre_and_rev_post_order_compute_fn (cfun, NULL, rpo, false); + unsigned todo = 0; + + for (int i = 0; i < n; ++i) + todo |= move_computations_worker (BASIC_BLOCK_FOR_FN (cfun, rpo[i])); + + free (rpo); gsi_commit_edge_inserts (); if (need_ssa_update_p (cfun)) rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); - return walker.todo_; + return todo; } /* Checks whether the statement defining variable *INDEX can be hoisted