On 12/19/14 03:20, Zamyatin, Igor wrote:
Hi!
This is an attempt to extend RTL unroller to allow cases like mentioned in the
PR -
namely when loop has duplicated exit blocks and back edges.
Bootstrapped and regtested on x86_64, also checking wide range of benchmarks -
spec2K, spec2006, EEMBC
Is it ok for trunk in case if no testing issues?
Thanks,
Igor
Changelog:
Gcc:
2014-12-19 Igor Zamyatin <igor.zamya...@intel.com>
PR rtl-optimization/64081
* loop-iv.c (def_pred_latch_p): New function.
(latch_dominating_def): Allow specific cases with non-single
definitions.
(iv_get_reaching_def): Likewise.
(check_complex_exit_p): New function.
(check_simple_exit): Use check_complex_exit_p to allow certain cases
with exits not executing on any iteration.
Testsuite:
2014-12-19 Igor Zamyatin <igor.zamya...@intel.com>
PR rtl-optimization/64081
* gcc.dg/pr64081.c: New test.
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index f55cea2..d5d48f1 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
/* Finds the definition of REG that dominates loop latch and stores
it to DEF. Returns false if there is not a single definition
- dominating the latch. If REG has no definition in loop, DEF
+ dominating the latch or all defs are same and they are on different
+ predecessors of loop latch. If REG has no definition in loop, DEF
is set to NULL and true is returned. */
Is it really sufficient here to verify that all the defs are on latch
predecessors, what about the case where there is a predecessor without a
def. How do you guarantee domination in that case?
ISTM that given the structure for the code you're writing that you'd
want to verify that in the event of multiple definitions that all of
them appear on immediate predecessors of the latch *and* that each
immediate predecessor has a definition.
static bool
latch_dominating_def (rtx reg, df_ref *def)
{
df_ref single_rd = NULL, adef;
- unsigned regno = REGNO (reg);
+ unsigned regno = REGNO (reg), def_num = 0;
struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch);
for (adef = DF_REG_DEF_CHAIN (regno); adef; adef = DF_REF_NEXT_REG (adef))
{
+ /* Initialize this to true for the very first iteration when
+ SINGLE_RD is NULL. */
+ bool def_pred_latch = true;
+
if (!bitmap_bit_p (df->blocks_to_analyze, DF_REF_BBNO (adef))
|| !bitmap_bit_p (&bb_info->out, DF_REF_ID (adef)))
continue;
- /* More than one reaching definition. */
+ /* More than one reaching definition is ok in case definitions are
+ in predecessors of latch block and those definitions are the same.
+ Probably this could be relaxed and check for sub-dominance instead
+ predecessor. */
if (single_rd)
- return false;
-
- if (!just_once_each_iteration_p (current_loop, DF_REF_BB (adef)))
- return false;
+ {
+ def_num++;
+ if (!(def_pred_latch = def_pred_latch_p (adef))
+ || !rtx_equal_p( PATTERN (DF_REF_INSN (single_rd)),
Whitespace nit here. Whitespace goes before the open paren for the
function call, not after.
@@ -351,10 +384,10 @@ latch_dominating_def (rtx reg, df_ref *def)
static enum iv_grd_result
iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def)
And in this routine, you appear to do both checks. ie, each def is on
an immediate predecessor and each immediate predecessor has a def. Is
there some reason why iv_get_reaching_def has the stronger check while
latch_dominating_def does not?
jeff