2016-04-26 18:39 GMT+03:00 H.J. Lu <hjl.to...@gmail.com>:
> On Tue, Apr 26, 2016 at 8:21 AM, Ilya Enkovich <enkovich....@gmail.com> wrote:
>> 2016-04-26 18:12 GMT+03:00 H.J. Lu <hjl.to...@gmail.com>:
>>> On Tue, Apr 26, 2016 at 8:05 AM, Ilya Enkovich <enkovich....@gmail.com> 
>>> wrote:
>>>> 2016-04-26 17:55 GMT+03:00 H.J. Lu <hjl.to...@gmail.com>:
>>>>> On Tue, Apr 26, 2016 at 7:15 AM, Ilya Enkovich <enkovich....@gmail.com> 
>>>>> wrote:
>>>>>> 2016-04-26 17:07 GMT+03:00 H.J. Lu <hjl.to...@gmail.com>:
>>>>>>> On Mon, Apr 25, 2016 at 9:13 AM, Ilya Enkovich <enkovich....@gmail.com> 
>>>>>>> wrote:
>>>>>>>> 2016-04-25 18:27 GMT+03:00 H.J. Lu <hjl.to...@gmail.com>:
>>>>>>>>>
>>>>>>>>> Ilya, can you take a look?
>>>>>>>>>
>>>>>>>>> Thanks.
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> H.J.
>>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> Algorithmic part of the patch looks OK to me except the following 
>>>>>>>> piece of code.
>>>>>>>>
>>>>>>>> +/* Check REF's chain to add new insns into a queue
>>>>>>>> +   and find registers requiring conversion.  */
>>>>>>>>
>>>>>>>> Comment is wrong because you don't have any conversions required for
>>>>>>>> your candidates.
>>>>>>>
>>>>>>> I will fix it.
>>>>>>>
>>>>>>>> +
>>>>>>>> +void
>>>>>>>> +scalar_chain_64::analyze_register_chain (bitmap candidates, df_ref 
>>>>>>>> ref)
>>>>>>>> +{
>>>>>>>> +  df_link *chain;
>>>>>>>> +
>>>>>>>> +  gcc_assert (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))
>>>>>>>> +             || bitmap_bit_p (candidates, DF_REF_INSN_UID (ref)));
>>>>>>>> +  add_to_queue (DF_REF_INSN_UID (ref));
>>>>>>>> +
>>>>>>>> +  for (chain = DF_REF_CHAIN (ref); chain; chain = chain->next)
>>>>>>>> +    {
>>>>>>>> +      unsigned uid = DF_REF_INSN_UID (chain->ref);
>>>>>>>> +
>>>>>>>> +      if (!NONDEBUG_INSN_P (DF_REF_INSN (chain->ref)))
>>>>>>>> +       continue;
>>>>>>>> +
>>>>>>>> +      if (!DF_REF_REG_MEM_P (chain->ref))
>>>>>>>> +       continue;
>>>>>>>>
>>>>>>>> I believe here you wrongly jump to the next ref intead of actually 
>>>>>>>> adding it
>>>>>>>> to a queue.  You may just use
>>>>>>>>
>>>>>>>> gcc_assert (!DF_REF_REG_MEM_P (chain->ref));
>>>>>>>>
>>>>>>>> because you should'n have a candidate used in address operand.
>>>>>>>
>>>>>>> I will update.
>>>>>>>
>>>>>>>> +
>>>>>>>> +      if (bitmap_bit_p (insns, uid))
>>>>>>>> +       continue;
>>>>>>>> +
>>>>>>>> +      if (bitmap_bit_p (candidates, uid))
>>>>>>>> +       add_to_queue (uid);
>>>>>>>>
>>>>>>>> Probably gcc_assert (bitmap_bit_p (candidates, uid)) since no uses and 
>>>>>>>> defs
>>>>>>>> out of candidates list are allowed?
>>>>>>>
>>>>>>> That would be wrong since there are
>>>>>>>
>>>>>>>  while (!bitmap_empty_p (queue))
>>>>>>>     {
>>>>>>>       insn_uid = bitmap_first_set_bit (queue);
>>>>>>>       bitmap_clear_bit (queue, insn_uid);
>>>>>>>       bitmap_clear_bit (candidates, insn_uid);
>>>>>>>       add_insn (candidates, insn_uid);
>>>>>>>     }
>>>>>>>
>>>>>>> An instruction is a candidate and the bit is cleared when
>>>>>>> analyze_register_chain is called.
>>>>>>
>>>>>> You clear candidates bit but the first thing you do in add_insn is set
>>>>>> insns bit.
>>>>>> Thus you should hit:
>>>>>>
>>>>>>       if (bitmap_bit_p (insns, uid))
>>>>>>         continue;
>>>>>>
>>>>>> For handled candidates.
>>>>>>
>>>>>> Probably it would be more clear if we keep this clear/set pair
>>>>>> together?  E.g. move
>>>>>> bitmap_clear_bit (candidates, insn_uid) to scalar_chain::add_insn.
>>>>>>
>>>>>
>>>>> After we started processing candidates, we only use candidates
>>>>> to check if an instruction is a candidate, not to check if an
>>>>> instruction is NOT a candidate.
>>>>
>>>> I don't see how it's related to what I said.  My point is that
>>>> when you analyze added insn you shouldn't reach insns which are both
>>>> not in candidates and not in current scalar_chain_64.  That's why I
>>>> think you miss an assert in scalar_chain_64::analyze_register_chain.
>>>
>>> Since all candidates will be processed by
>>>
>>>  while (!bitmap_empty_p (queue))
>>>     {
>>>       insn_uid = bitmap_first_set_bit (queue);
>>>       bitmap_clear_bit (queue, insn_uid);
>>>       bitmap_clear_bit (candidates, insn_uid);
>>>       add_insn (candidates, insn_uid);
>>>     }
>>
>> This process only queue, not all candidates.  analyze_register_chain
>> fills queue bitmap to build a chain.
>>
>>>
>>> I will change to
>>>
>>> /* Check REF's chain to add new insns into a queue.  */
>>>
>>> void
>>> timode_scalar_chain::analyze_register_chain (bitmap candidates,
>>>                                              df_ref ref)
>>> {
>>>     gcc_assert (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))
>>>               || bitmap_bit_p (candidates, DF_REF_INSN_UID (ref)));
>>>   add_to_queue (DF_REF_INSN_UID (ref));
>>> }
>>>
>>
>> The purpose of analyze_register_chain is to collect all register defs
>> or uses into chain's queue.  You can't just remove a loop over ref's
>> chain then.
>
> That is true for DImode conversion.  For TImode conversion,
> there are no register conversions required:
>
> https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01394.html
>
> All it does it to call add_to_queue.

No conversion means no mark_dual_mode_def calls in analyze_register_chain
but it still may call add_to_queue multiple times in its loop. E.g.

1: r1 = 1
...
5: r1 = 2
..
10: r2 = r1

When you add #10 into a chain you should add both #1 and #5 into a queue.
That's what analyze_register_chain is supposed to do.

Thanks,
Ilya

>
> Here is the updated patch.  OK for trunk if there is no regression
> on x86-64?
>
> --
> H.J.

Reply via email to