[PATCH v2] combine: Tweak the condition of last_set invalidation

Kewen.Lin linkw@linux.ibm.com
Tue Nov 30 08:47:28 GMT 2021


Hi Segher,

Thanks for the review!

on 2021/11/30 上午6:28, Segher Boessenkool wrote:
> Hi!
> 
> On Fri, Jun 11, 2021 at 09:16:21PM +0800, Kewen.Lin wrote:
>>>> +	      /* Should pick up the lowest luid if the references
>>>> +		 are in the same block.  */
>>>> +	      if (label_tick == rsp->last_set_table_tick
>>>> +		  && rsp->last_set_table_luid > insn_luid)
>>>> +		rsp->last_set_table_luid = insn_luid;
>>>
>>> Why?  Is it conservative for the check you will do later?  Please spell
>>> this out, it is crucial!
>>
>> Since later the combinations involving this insn probably make the
>> register be used in one insn sitting ahead (which has smaller luid than
>> the one which was recorded before).  Yes, it's very conservative, this
>> ensure that we always use the luid of the insn which is the first insn
>> using this register in the block.
> 
> Why would that be correct?!
> 

The later check has:

       if (!insn
-          || (value && rsp->last_set_table_tick >= label_tick_ebb_start))
+          || (value && rsp->last_set_table_tick >= label_tick_ebb_start
+              && !(label_tick == rsp->last_set_table_tick
+                   && DF_INSN_LUID (insn) < rsp->last_set_table_luid)))
         rsp->last_set_invalid = 1;

For "label_tick != rsp->last_set_table_tick", it's the same as before.

For "label_tick == rsp->last_set_table_tick", we have the below:

+              if (label_tick == rsp->last_set_table_tick
+                  && rsp->last_set_table_luid > insn_luid)
+                rsp->last_set_table_luid = insn_luid;

It keeps checking and updating with the smallest LUID of the insns which
have the expression involving register n are placed in last_set_value.

The updating here aims to ensure we always the LUID of first INSN which
uses register n (or saying that having one expression involving register n
is placed in last_set_value).

For the first time we set last_set_table_tick for register n, we will also
set last_set_table_luid.  For below case, we record x for LUID.  Assuming
we combining 1,2,x to 2,x and regX is updated to be used in insn2.  Then
the first INSN using regX has become to insn 2.

  ... reg1 // insn 1
  ...
  ... reg2 // insn 2
  ...
  ... regX // insn x
  ...
  regX     // insn y
  ...

Later whether combining moves regX setting upward or not, the LUID which it
compares with is always the updated smallest one (insn 2 here), not the one
which is set at the beginning.  So I think it's conservative.

>> The last_set invalidation is going
>> to catch the case like:
>>
>>    ... regX  // avoid the set used here ...
>>    regX = ...
>>    ...
>>
>> Once we have the smallest luid one of all insns which use register X,
>> any unsafe regX sets should be caught.
> 
> Yes, you invalidate more, but because you put lies in the table :-(
> 

This patch tries to relax some restrictions, it seems there are no lies.  :)
Could you help to explain this comment more?

>> 	* combine.c (struct reg_stat_type): New member
>> 	last_set_table_luid.
> 
> This fits on one line.
> 
>> 	(update_table_tick): Add one argument for insn luid and
>> 	set last_set_table_luid with it, remove its declaration.
>> 	(record_value_for_reg): Adjust the condition to set
>> 	last_set_invalid nonzero.
> 
> These lines break earlier than they should as well.
> 
>> +  /* Record the luid of the insn which uses register n, the insn should
>> +     be the first one using register n in that block of the insn which
>> +     last_set_table_tick was set for.  */
>> +
>> +  int				last_set_table_luid;
> 
> I'm not sure what this variable is for.  The comment says something
> else than the variable name does, and now I don't know what to
> believe :-)
> 
> The name says it is for a SET, the explanation says it is for a USE.
> 

Good point.  :)  For the existing last_set_table_tick,
  /* Record the value of label_tick when an expression involving register n
     is placed in last_set_value.  */

  int				last_set_table_tick;

it seems it has the set in the name too, but "an expression involving
register n " is actually a reference (use) to register n?

How about the below one referring to "last_set_table_tick"?

/* Record the smallest luid of the insns whose expressions involving
   register n are placed in last_set_value, meanwhile the insns locate
   in the same block of the insn which last_set_table_tick was set for.  */


BR,
Kewen


More information about the Gcc-patches mailing list