On 01/06/2017 03:20 AM, Aurelien Buhrig wrote:

So the insn:
(set (reg:QI 0 r0) (mem:QI (plus:SI (reg:SI 2 r2)(const_int 1))

is transformed into:
(set (reg:SI 8 a0) (reg:SI 2 r2))
(set (reg:SI 8 a0) (const_int 1))
(set (reg:SI 8 a0) (plus:SI (reg:SI 8 a0) (reg:SI 8 a0)))
(set (reg:QI 0 r0) (mem:QI (reg:SI 8 a0))

This "basic" transformation requires two reload regs, but only one is
given/used/possible from the rl structure (in emit_reload_insns).

So where does the issue comes from? The need for 2 reload regs, the
transformation which is too "basic" and could be optimized to use only
one reload reg, or any wrong/missing reload target hook?
Sounds like you need secondary or intermediate reloads.
Thank you Jeff for your help.
Currently, the TARGET_SECONDARY_RELOAD does not check if the address of
a mem rtx is legitimate address and it returns NO_REG with (mem:QI r2).
So first you have to distinguish between an intermediate and scratch register.

Intermediates say that to copy from a particular register class to a particular destination will require the source to first be copied into the intermediate register, then the intermediate to the final destination. So for example if you have a register that you can not directly store to memory, you might use an intermediate. The source register would be copied to the intermediate and the intermediate then stored to memory.

Scratch registers are different -- essentially the backend tells reload that another register from a particular class is needed *and* the pattern to use for generating the reload. So as an example, you might have a two-register indexed address,

For example, loading a constant into an FP register during PIC code generation may require a scratch register to hold intermediate address computations.

You can have cases where you need both a scratch and an intermediate. You can also have cases where you need an intermediate memory location.


Do you suggest the secondary reload must implement a scratch reg & md
pattern to implement this reload?
Perhaps. I don't know enough about your architecture to be 100% sure about how all the pieces interact with each other -- reload, and secondary reloads in particular are a complex area. I'm largely going on your comment that you need 2 reload registers.

Presumably you don't have an instruction for
(set (reg) (plus (reg) (const_int)))

Thus you need two scratch reload regs IIUC. One to hold r2 another to hold (const_int 1). So you'd want to generate

(set (areg1) (reg r2))
(set (areg2) (const_int 1))
(set (areg1) (plus (areg1) (areg2)
(set (r0) (mem (areg1))

Or something along those lines. If you're going to stick with reload, you'll likely want to dig into find_reloads_address and its children to see what reloads it generates and why (debug_reload can be helpful here).

jeff


Reply via email to