aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenth@gcc.gnu.org>2017-12-05 08:06:08 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2017-12-05 08:06:08 +0000
commit4c83982f27efb6a764a3193c04a2cb649fe8902f (patch)
treed159d0405e0f06f07749493445452d013826152b /gcc
parentbe6a1ba2815b5273decfe850c1a95382737b5b00 (diff)
downloadgcc-4c83982f27efb6a764a3193c04a2cb649fe8902f.zip
gcc-4c83982f27efb6a764a3193c04a2cb649fe8902f.tar.gz
gcc-4c83982f27efb6a764a3193c04a2cb649fe8902f.tar.bz2
gimple-loop-interchange.cc (loop_cand::classify_simple_reduction): Simplify.
2017-12-05 Richard Biener <rguenther@suse.de> * gimple-loop-interchange.cc (loop_cand::classify_simple_reduction): Simplify. (loop_cand::analyze_iloop_reduction_var): Reject dead reductions. (loop_cand::analyze_oloop_reduction_var): Likewise. Simplify. (tree_loop_interchange::interchange_loops): Properly analyze scalar evolution before instantiating a SCEV. From-SVN: r255402
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-loop-interchange.cc72
1 files changed, 23 insertions, 49 deletions
diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index 1f46509..f834138 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -432,8 +432,6 @@ void
loop_cand::classify_simple_reduction (reduction_p re)
{
gimple *producer, *consumer;
- enum tree_code code;
- tree lhs, rhs;
/* Check init variable of reduction and how it is initialized. */
if (TREE_CODE (re->init) == SSA_NAME)
@@ -444,50 +442,21 @@ loop_cand::classify_simple_reduction (reduction_p re)
if (!bb || bb->loop_father != m_outer)
return;
- if (!is_gimple_assign (producer))
+ if (!gimple_assign_load_p (producer))
return;
- code = gimple_assign_rhs_code (producer);
- if (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS)
- return;
-
- lhs = gimple_assign_lhs (producer);
- if (lhs != re->init)
- return;
-
- rhs = gimple_assign_rhs1 (producer);
- if (!REFERENCE_CLASS_P (rhs))
- return;
-
- re->init_ref = rhs;
+ re->init_ref = gimple_assign_rhs1 (producer);
}
else if (!CONSTANT_CLASS_P (re->init))
return;
- /* Check how reduction variable is used. Note usually reduction variable
- is used outside of its defining loop, we don't require that in terms of
- loop interchange. */
- if (!re->lcssa_phi)
- consumer = single_use_in_loop (re->next, m_loop);
- else
- consumer = single_use_in_loop (PHI_RESULT (re->lcssa_phi), m_outer);
-
- if (!consumer || !is_gimple_assign (consumer))
- return;
-
- code = gimple_assign_rhs_code (consumer);
- if (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS)
- return;
-
- lhs = gimple_assign_lhs (consumer);
- if (!REFERENCE_CLASS_P (lhs))
- return;
-
- rhs = gimple_assign_rhs1 (consumer);
- if (rhs != PHI_RESULT (re->lcssa_phi))
+ /* Check how reduction variable is used. */
+ consumer = single_use_in_loop (PHI_RESULT (re->lcssa_phi), m_outer);
+ if (!consumer
+ || !gimple_store_p (consumer))
return;
- re->fini_ref = lhs;
+ re->fini_ref = gimple_get_lhs (consumer);
re->consumer = consumer;
/* Simple reduction with constant initializer. */
@@ -608,6 +577,9 @@ loop_cand::analyze_iloop_reduction_var (tree var)
else
return false;
}
+ if (!lcssa_phi)
+ return false;
+
re = XCNEW (struct reduction);
re->var = var;
re->init = init;
@@ -681,15 +653,9 @@ loop_cand::analyze_oloop_reduction_var (loop_cand *iloop, tree var)
/* Outer loop's reduction should only be used to initialize inner loop's
simple reduction. */
- FOR_EACH_IMM_USE_FAST (use_p, iterator, var)
- {
- stmt = USE_STMT (use_p);
- if (is_gimple_debug (stmt))
- continue;
-
- if (stmt != inner_re->phi)
- return false;
- }
+ if (! single_imm_use (var, &use_p, &stmt)
+ || stmt != inner_re->phi)
+ return false;
/* Check this reduction is correctly used outside of loop via lcssa phi. */
FOR_EACH_IMM_USE_FAST (use_p, iterator, next)
@@ -711,6 +677,8 @@ loop_cand::analyze_oloop_reduction_var (loop_cand *iloop, tree var)
else
return false;
}
+ if (!lcssa_phi)
+ return false;
re = XCNEW (struct reduction);
re->var = var;
@@ -1146,12 +1114,18 @@ tree_loop_interchange::interchange_loops (loop_cand &iloop, loop_cand &oloop)
edge instantiate_below = loop_preheader_edge (loop_nest);
gsi = gsi_last_bb (loop_preheader_edge (loop_nest)->src);
i_niters = number_of_latch_executions (iloop.m_loop);
- i_niters = instantiate_scev (instantiate_below, loop_nest, i_niters);
+ i_niters = analyze_scalar_evolution (loop_outer (iloop.m_loop), i_niters);
+ i_niters = instantiate_scev (instantiate_below, loop_outer (iloop.m_loop),
+ i_niters);
i_niters = force_gimple_operand_gsi (&gsi, unshare_expr (i_niters), true,
NULL_TREE, false, GSI_CONTINUE_LINKING);
o_niters = number_of_latch_executions (oloop.m_loop);
if (oloop.m_loop != loop_nest)
- o_niters = instantiate_scev (instantiate_below, loop_nest, o_niters);
+ {
+ o_niters = analyze_scalar_evolution (loop_outer (oloop.m_loop), o_niters);
+ o_niters = instantiate_scev (instantiate_below, loop_outer (oloop.m_loop),
+ o_niters);
+ }
o_niters = force_gimple_operand_gsi (&gsi, unshare_expr (o_niters), true,
NULL_TREE, false, GSI_CONTINUE_LINKING);