> On Sep 25, 2020, at 11:58 AM, Richard Sandiford <richard.sandif...@arm.com>
> wrote:
>
> Qing Zhao <qing.z...@oracle.com> writes:
>>>>
>>>>
>>>> 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?
>
> Sorry, I misremembered the name, it's regno_reg_rtx (which makes
> more sense than what I wrote).
Found 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));
>> }
>
> Yeah, looks like it should work.
thanks.
Last question, in the following code portion:
/* Now we get a hard register set that need to be zeroed, pass it to
target to generate zeroing sequence. */
HARD_REG_SET zeroed_hardregs;
start_sequence ();
zeroed_hardregs = targetm.calls.zero_call_used_regs (need_zeroed_hardregs);
rtx_insn *seq = get_insns ();
end_sequence ();
if (seq)
{
/* emit the memory blockage and register clobber asm volatile. */
rtx barrier_rtx = expand_asm_reg_clobber_blockage (zeroed_hardregs);
/* How to insert the barrier_rtx before "seq"???. */
??????
emit_insn_before (barrier_rtx, seq); ??????
emit_insn_before (seq, ret);
/* update the data flow information. */
df_set_bb_dirty (BLOCK_FOR_INSN (ret));
}
In the above, how should I insert the barrier_rtx in the beginning of “seq” ?
And then insert the seq before ret?
Is there special thing I need to take care?
Qing
>
> Thanks,
> Richard