Yes, I want the register to be allocatable when there are no stack frames used in the function so it can be used for other purposes. In fact, I looked at how other backends solve this problem, but they are all too conservative by always reserving the register which in my case it is not a good solution because of the performance impact of not having this register available. I find very interesting what you mentioned of tying the physical reg to spill code. I've created a pseudo instruction for spill code and i've tied this physical reg as one of its operands (this register is sort of a shadow reg of the stack pointer where it can be used as a normal reg when there's no stack manipulation in the function or as the SP when regs are spilled). Then if I understood correctly the second part is making the regalloc aware of this so it can evict other live ranges using this register to avoid the conflict of both using this register freely and in the spill code which is what is happening to me, however I'm not very confident with myself on touching the regalloc. I've also added Jakob (i hope he doesn't mind :) ) to this thread so he can give his point of view. Thanks for the reply Andy. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20111129/a605c286/attachment.html>
On Nov 29, 2011, at 10:24 AM, Borja Ferrer wrote:> Yes, I want the register to be allocatable when there are no stack frames used in the function so it can be used for other purposes. In fact, I looked at how other backends solve this problem, but they are all too conservative by always reserving the register which in my case it is not a good solution because of the performance impact of not having this register available. > > I find very interesting what you mentioned of tying the physical reg to spill code. I've created a pseudo instruction for spill code and i've tied this physical reg as one of its operands (this register is sort of a shadow reg of the stack pointer where it can be used as a normal reg when there's no stack manipulation in the function or as the SP when regs are spilled). > Then if I understood correctly the second part is making the regalloc aware of this so it can evict other live ranges using this register to avoid the conflict of both using this register freely and in the spill code which is what is happening to me, however I'm not very confident with myself on touching the regalloc.It's not really clear if you actually need that register to be reserved throughout the function, or if you just need it to be available around spill code. Both are possible, though. Note that this is a bit of a hack, since it won't work with the fast register allocator. You will need some custom code in RAGreedy since the current target APIs don't support this. When you spill, you can evict live ranges assigned to your 'reserved' register and put them back on the work queue. See for example the RAGreedy::LRE_WillShrinkVirtReg() callback. You can choose to evict all live ranges assigned to that register and reserve it, or you can just evict the single live range crossing your spill code if you just need the register to be available for spilling. You can also use the PBQP register allocator which already supports multi-pass allocation. It's probably quite simple to reserve a register after pass 1 spills. /jakob
Thanks for all the hints Jakob, I've added the following piece of code after the spill code handling inside selectOrSplit() (ignoring some control logic): for (LiveIntervals::const_iterator I = LIS->begin(), E = LIS->end(); I !E; ++I) { unsigned VirtReg = I->first; if ((TargetRegisterInfo::isVirtualRegister(VirtReg)) && (VRM->getPhys(VirtReg) == REG_Y)) { LiveInterval &LI = LIS->getInterval(VirtReg); unassign(LI, REG_Y); enqueue(&LI); } } RegClassInfo.runOnMachineFunction(VRM->getMachineFunction()); // update reserve reglist So similar to what's done in LRE_WillShrinkVirtReg(), it searches for live intervals where REG_Y is allocated and evicts them for reallocation. I don't know if there's a faster way of doing this but it's working :) About your first question: the register has to be reserved throughout the whole function. Thanks for the help -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20111130/e510ab4e/attachment.html>