On 06/01/2017 17:06, Jeff Law wrote: > 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. >> 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).
Thank you very much Jeff for your help. The best mapping for my target would be: (set areg1 r2) (set r0 (mem:QI (areg1 + 1)), and only 1 scratch would be needed. In secondary_reload, I can see the pattern (mem:QI (reg+1)) during IRA pass with reg being a pseudo (ira_cost), but I cannot tranform it since I do not know in which class the address reg would be reloaded into (or maybe I can, but I don't know how since reg_renumber is -1 for this pseudo). And the reload pass does not call my secondary reload with this pattern mapped onto hw regs, so I cannot transform it. So I try to add LEGITIMIZE_RELOAD_ADDRESS. I can see the (mem:QI (r2+1)) with hwreg, and so try to push_reload r2 with the "BASE_REG_CLASS". But it has no effect. Indeed, in push_secondary_reload, the secondary_reload is called and if NO_REG and CODE_FOR_nothing is returned, "no reload reg is needed" ... But r2 is a hwreg which does not belong to BASE_REG_CLASS, can be directly copied to BASE_REG_CLASS and it does need a reload reg. So should not push_secondary_reload check for class intersection ? Or how to perform a reload from a hwreg to a class it does not belong to? Thanks, Aurélien