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