One issue with default implementation of zero_call_used_regs

Qing Zhao QING.ZHAO@ORACLE.COM
Fri Sep 25 15:59:19 GMT 2020



> On Sep 25, 2020, at 10:28 AM, Richard Sandiford <richard.sandiford@arm.com> wrote:
> 
> Qing Zhao <QING.ZHAO@ORACLE.COM <mailto:QING.ZHAO@ORACLE.COM>> writes:
>>> On Sep 25, 2020, at 7:53 AM, Richard Sandiford <richard.sandiford@arm.com> wrote:
>>> 
>>> Qing Zhao <QING.ZHAO@ORACLE.COM> writes:
>>>> Hi, Richard,
>>>> 
>>>> As you suggested, I added a default implementation of the target hook “zero_cal_used_regs (HARD_REG_SET)” as following in my latest patch
>>>> 
>>>> 
>>>> /* The default hook for TARGET_ZERO_CALL_USED_REGS.  */
>>>> 
>>>> void
>>>> default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
>>> 
>>> FWIW, I was suggesting to return the set of registers that are actually
>>> cleared too.  Here you have the hook emit the asm statement, but IMO the
>>> way we generate the asm for a given set of registers should be entirely
>>> target-independent, and happen outside the hook.
>>> 
>>> So the hook returning the set of cleared registers does two things:
>>> 
>>> (1) It indicates which registers should be clobbered by the asm
>>>   (which would be generated after calling the hook, but emitted
>>>   before the sequence of instructions generated by the hook).
>> 
>> For this purpose, this hook should return a Set of RTX that hold the cleared registers, a HARD_REG_SET is not enough.
>> 
>> Since in the ASM_OPERANDS, we will need the RTX for the register (not the REGNO).
>> 
>> Which data structure in GCC should be used here to hold this returned value as Set of RTX ?
> 
> A HARD_REG_SET is enough.  All the caller needs to know is: which registers
> were clobbered?  It can then represent a clobber of R with a clobber of
> reg_regno_rtx[R].

I did not find reg_regno_rtx in the current gcc source, not sure how to use it?
> 
> The mode isn't important for single-register clobbers: clobbering a single
> register in one mode is equivalent to clobbering it in another mode.
> None of the register contents survive the clobber.

Okay, I see.

Then is the following good enough:

/* Generate asm volatile("" : : : "memory") as a memory blockage, at the 
   same time clobbering the register set  specified by ZEROED_REGS.  */

void
expand_asm_memory_blockage_clobber_regs (HARD_REG_SET zeroed_regs)
{
  rtx asm_op, clob_mem, clob_reg;

  /* first get the number of registers that have been zeroed from ZEROED_REGS set.  */
  unsigned int  num_of_regs = ….;

  asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
                                 rtvec_alloc (0), rtvec_alloc (0),
                                 rtvec_alloc (0), UNKNOWN_LOCATION);
  MEM_VOLATILE_P (asm_op) = 1;

  rtvec v = rtvec_alloc (num_of_regs + 2);

  clob_mem = gen_rtx_SCRATCH (VOIDmode);
  clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
  clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);

  RTVEC_ELT (v,0) = asm_op;
  RTVEC_ELT (v,1) = clob_mem;

  for (unsigned int I = 0; i < FIRST_PSEUDO_REGISTER; i++)
    If (TEST_HARD_REG_BIT (zeroed_regs, i))
      {
        clob_reg  = gen_rtx_CLOBBER (VOIDmode, reg_regno_rtx[i]);
        RTVEC_ELT (v,i+2) = clob_reg;
      }
  
  emit_insn (gen_rtx_PARALLEL (VOIDmode, v));                              
}

How to come up with the above:’

   clob_reg  = gen_rtx_CLOBBER (VOIDmode, reg_regno_rtx[i]);?

> 
>>> (2) It indicates which registers should be treated as live on return.
>>> 
>>> FWIW, for (2), I'd recommend storing the returned HARD_REG_SET in crtl.
>> 
>> Instead of storing this info in crtl, in my current patch, I added the following in “df-scan.c":
>> +static HARD_REG_SET zeroed_reg_set;
>> 
>> And routines that manipulate this HARD_REG_SET. 
>> I think that this should serve the same purpose as storing it to crtl? 
> 
> Storing it in crtl is better for two reasons:
> 
> - Using global statics for this kind of thing makes it harder to
>  compile functions in parallel.  (Work is underway to allow that.)
> 
> - Having the information in crtl reduces the risk that information
>  from one function will get reused for another function, without the
>  variable being reinitialised inbetween.

Okay, will add a new field zeroed_reg_set into crtl.

Thanks.

Qing
> 
> Thanks,
> Richard



More information about the Gcc-patches mailing list