This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Using secondary reload to reload CONST_INT?


2011/3/21 Georg-Johann Lay <avr@gjlay.de>:
> Denis Chertykov schrieb:
>> 2011/3/20 Georg-Johann Lay <avr@gjlay.de>:
>>> The AVR controller basically has two kinds of hard registers:
>>>
>>> * LD_REGS (constraint "d") that can move immediates
>>> * NO_LD_REGS (constraint "l") that cannot move immediates
>>>
>>> movsi insn of avr backend does not supply an "l,i" constraint alternative,
>>> so that reload takes care of that and allocates an intermediate SImode
>>> d-reg.
>>
>> The *movsi pattern:
>> (define_insn "*movsi"
>> Â [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
>> Â Â Â Â (match_operand:SI 1 "general_operand" Â Â Â "r,L,Qm,rL,i,i"))]
>>
>> Last constraints pair `r' and `i' supply an `l' and `i' because `r' = `dl'.
>>
>> Also, to optimize movsi exists the following peephole2:
>> (define_peephole2 ; movsi_lreg_const
>> Â [(match_scratch:QI 2 "d")
>> Â Â(set (match_operand:SI 0 "l_register_operand" "")
>> Â Â Â Â (match_operand:SI 1 "immediate_operand" ""))
>> Â Â(match_dup 2)]
>> Â "(operands[1] != const0_rtx
>> Â Â && operands[1] != constm1_rtx)"
>> Â [(parallel [(set (match_dup 0) (match_dup 1))
>> Â Â Â Â Â Â (clobber (match_dup 2))])]
>> Â "")
>>
>>
>>> The drawback is that this allocates 4 GPRs (AVR is 8-bit machine).
>>
>> Please, provide an example.
>
> Yes, you're right. There is this alternative "r,i" which use
> __tmp_reg__ to temporarily backup a d-reg.
>
> So my intention was actually to remove the "r,i" alternative and have
> it handled by secondary reload; the original question is if secondary
> reload is designed to handle the reg-const combination that will occur
> in that case.
>
> The default to load a const needs 10 instructions.
>
> Â/* Last resort, better than loading from memory. Â*/
> Â*l = 10;
> Âreturn (AS2 (mov,__tmp_reg__,r31) CR_TAB
> Â Â Â Â ÂAS2 (ldi,r31,lo8(%1)) Â Â CR_TAB
> Â Â Â Â ÂAS2 (mov,%A0,r31) Â Â Â Â CR_TAB
> Â Â Â Â ÂAS2 (ldi,r31,hi8(%1)) Â Â CR_TAB
> Â Â Â Â ÂAS2 (mov,%B0,r31) Â Â Â Â CR_TAB
> Â Â Â Â ÂAS2 (ldi,r31,hlo8(%1)) Â ÂCR_TAB
> Â Â Â Â ÂAS2 (mov,%C0,r31) Â Â Â Â CR_TAB
> Â Â Â Â ÂAS2 (ldi,r31,hhi8(%1)) Â ÂCR_TAB
> Â Â Â Â ÂAS2 (mov,%D0,r31) Â Â Â Â CR_TAB
> Â Â Â Â ÂAS2 (mov,r31,__tmp_reg__));
>
> With a d-reg from secondary reload it's at most 8 instructions.
>
> The current code relies on a d-reg being available in peep2, and the
> overhead for HI resp. QI is even higher.
>
> Thus, if no d-reg is at hand in peep2, we get the big code.
>
> A secondary reload would always supply a d-reg because register
> allocator would arrange for that and we would not have to rely on peep2.
>
> Moreover, the extra_cost of secondary reload might allow to give more
> accurate costs.

I'm not sure that you right because reloading is a complicated
process, and real
cost of one `d' register may be bigger then save/restore to tmp_reg.
Please, provide test results.

Denis.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]