On December 4, 2017 5:01:45 PM GMT+01:00, "Bin.Cheng" <amker.ch...@gmail.com> 
wrote:
>On Mon, Dec 4, 2017 at 3:43 PM, Richard Biener <rguent...@suse.de>
>wrote:
>>
>> When skimming through the code I noticed the following (chatted on
>IRC
>> about parts of the changes).
>>
>> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>>
>> Will commit tomorrow unless you beat me to that.
>>
>> Richard.
>>
>> 2017-12-04  Richard Biener  <rguent...@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.
>>
>> Index: gcc/gimple-loop-interchange.cc
>> ===================================================================
>> --- gcc/gimple-loop-interchange.cc      (revision 255383)
>> +++ gcc/gimple-loop-interchange.cc      (working copy)
>> @@ -444,50 +444,21 @@ loop_cand::classify_simple_reduction (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 +579,9 @@ loop_cand::analyze_iloop_reduction_var (
>>        else
>>         return false;
>>      }
>> +  if (!lcssa_phi)
>> +    return false;
>> +
>>    re = XCNEW (struct reduction);
>>    re->var = var;
>>    re->init = init;
>> @@ -681,15 +655,9 @@ loop_cand::analyze_oloop_reduction_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 +679,8 @@ loop_cand::analyze_oloop_reduction_var (
>>        else
>>         return false;
>>      }
>> +  if (!lcssa_phi)
>> +    return false;
>>
>>    re = XCNEW (struct reduction);
>>    re->var = var;
>> @@ -1146,12 +1116,18 @@ tree_loop_interchange::interchange_loops
>>    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);
>> +    }
>Hmm, sorry to disturb.  IIRC, it's important to instantiate niters
>against the outermost loop in nest.  Otherwise niters could refer to
>intermediate variables defined by loop in nest, which may lead to
>undefined ssa use issue in the chain of interchange.


That's a common misconception of the instantiate_scev interface. We instantiate 
against below, the loop argument is to interpret the chrec and absolutely has 
to match what loop you called analyze_evolution on. Otherwise there's a chance 
you get garbage out (from garbage in). 

Richard. 
>Thanks,
>bin
>>    o_niters = force_gimple_operand_gsi (&gsi, unshare_expr
>(o_niters), true,
>>                                        NULL_TREE, false,
>GSI_CONTINUE_LINKING);
>>

Reply via email to