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?


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.

Johann


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