Hi Jakob, Jonas et al, Jakob wrote: [...]> Jonas wrote: > [...] > > What's more, setting the GPR_CR class to 'not-spillable' would probably do the trick here as we > > basically do not want to do this, and I would not have to pre-allocate. But there is probably a > > better way, or? > > I am sorry, I simply don't understand what you are asking for. You might as well suggest that we all > don't pay taxes. It sounds tempting, but the plan needs some details. > > If the fast register allocator is not working for you, you can use the greedy register allocator in > -O0 builds by passing -regalloc=greedy. It's not that much slower.[...] I believe that Jonas wants to have the following: - A register class specification such that you get the same effect as 'glue code', but without having to introducing custom nodes and lowering to represent this glue. I think that 'glue' is today the only solution if you do not want to produce spill code. In a backend on which I have been working, we have a compare instruction that sets a flag (true or false), and a conditional branch instruction, that jumps if the flag is true. Initially, I tried to specify this by providing a lowering of the compare instruction : (CCReg only contains one register) def CMPEQ : Instr< (outs CCReg:$dst), (ins IntRegs:$lhs, IntRegs:$rhs), "cmpeq $lhs, $src", [(cmpeq IntRegs:$dst, IntRegs:$src)>; def BCC : Instr< (outs), (ins CCReg:$cc, brtarget:$addr), "bcc $addr", [(brcond CCReg:$cc, bb:$addr)]>;This worked, but for more complex programs, llvm tries to generate code to move CC and to spill CC. I was able to get rid of the 'moves' by setting the copycost to -1. For getting rid of the spills, I was forced to introduce custom nodes, that pass the CC register through 'glue'. Having a property to register classes that identifies a 'glue-like' behavior would make sense to me. Greetings, Jeroen Dobbelaere
On 2012 2 2, at 08:40, Jeroen Dobbelaere <Jeroen.Dobbelaere at synopsys.com> wrote:> I was able to get rid of the 'moves' by setting the copycost to -1. > For getting rid of the spills, I was forced to introduce custom nodes, that pass the CC register > through 'glue'. > > Having a property to register classes that identifies a 'glue-like' behavior would make sense to me.I think setting CopyCost = -1 more or less does what you want, but I don't really understand what that field is for. It is only ever used by the scheduler. Register allocation completely ignores it. Judging by how it is used, it should probably be a property of registers, not register classes. /jakob
Well, I actually glue my condition-registers already, but as far as I know this only affects the scheduling from the DAG to the MachineFunction. It still happened that a register allocator at -O0 would spill this register for no reason at all in between these instructions. The CopyCost attribute would help me, if the register allocators would factor it in with the spillWeight calculation. I suppose this would be fairly simple to implement, given that all the register allocators except -fast use the CalcSpillWeights class, where it could be included. Would this make sense to you as a patch? Maybe CopyCost and SpillCost should be held separate, I don't know, but in this case a new attribute could be introduced. Jonas -----Original Message----- From: Jakob Stoklund Olesen [mailto:stoklund at 2pi.dk] Sent: Friday, February 03, 2012 2:02 AM To: Jeroen Dobbelaere Cc: Jonas Paulsson; Jonas Paulsson; LLVMDEV Subject: Re: [LLVMdev] register allocation On 2012 2 2, at 08:40, Jeroen Dobbelaere <Jeroen.Dobbelaere at synopsys.com> wrote:> I was able to get rid of the 'moves' by setting the copycost to -1. > For getting rid of the spills, I was forced to introduce custom nodes, > that pass the CC register through 'glue'. > > Having a property to register classes that identifies a 'glue-like' behavior would make sense to me.I think setting CopyCost = -1 more or less does what you want, but I don't really understand what that field is for. It is only ever used by the scheduler. Register allocation completely ignores it. Judging by how it is used, it should probably be a property of registers, not register classes. /jakob