Hi All, I finally had a chance to get back to my pbqp trials, now using the 3.0 release. I still hit the same assert : "Attempting to spill already spilled value." This is triggered because in RegAllocPBQP::mapPBQPToRegAlloc, a vreg node is either : - a physical register (problem.isPRegOption(vreg, alloc)), - or a spill (problem.isSpillOption(vreg, alloc)) The problem is that pass CalcSpillWeights can 'hint' that it is a poor idea to spill this specific register with : CalcSpillWeights.cpp / VirtRegAuxInfo::CalculateWeightAndHint : // Mark li as unspillable if all live ranges are tiny. if (li.isZeroLength(LIS.getSlotIndexes())) { li.markNotSpillable(); ... This hint makes the register non spillable at all for the spiller (that's the assert above), not just a bad-idea-to-spill-but-feasible. The pbqp allocator does not cope with this distinction and allways attempts to spill it. I would need some guidance on how to modify the pbqp to handle this case properly. Best regards, -- Arnaud de Grandmaison
Hi Arnaud, LiveInterval::markNotSpillable() sets the live interval's spill weight to infinity. For well-formed PBQP graphs (i.e. ones that have some finite-cost solution), PBQP should never chose to spill such an interval. The two possibilities for this crash are that the input graph has no finite-cost solution, or that you've exposed a bug in the PBQP solver.>From memory your target is not public, so I won't be able to reproducethe crash myself. Is that correct? If that's the case, I could add functionality to dump the PBQP graphs during allocation. I think they should give me enough information to debug the issue. Would you be able to share the PBQP graphs? Cheers, Lang. On Wed, Mar 21, 2012 at 8:40 AM, Arnaud de Grandmaison <arnaud.allarddegrandmaison at parrot.com> wrote:> > Hi All, > > I finally had a chance to get back to my pbqp trials, now using the 3.0 > release. I still hit the same assert : "Attempting to spill already spilled > value." > > This is triggered because in RegAllocPBQP::mapPBQPToRegAlloc, a vreg node is > either : > - a physical register (problem.isPRegOption(vreg, alloc)), > - or a spill (problem.isSpillOption(vreg, alloc)) > > The problem is that pass CalcSpillWeights can 'hint' that it is a poor > idea to spill this specific register with : > > CalcSpillWeights.cpp / VirtRegAuxInfo::CalculateWeightAndHint : > // Mark li as unspillable if all live ranges are tiny. > if (li.isZeroLength(LIS.getSlotIndexes())) { > li.markNotSpillable(); > ... > > This hint makes the register non spillable at all for the spiller (that's the > assert above), not just a bad-idea-to-spill-but-feasible. The pbqp allocator > does not cope with this distinction and allways attempts to spill it. > > I would need some guidance on how to modify the pbqp to handle this case > properly. > > Best regards, > -- > Arnaud de Grandmaison > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Hi Lang,> From memory your target is not public, so I won't be able to reproduce > the crash myself. Is that correct?Correct.> If that's the case, I could add functionality to dump the PBQP graphs > during allocation. I think they should give me enough information to > debug the issue. Would you be able to share the PBQP graphs?I can share the pbqp graph if you send me a patch with the added functionality you want. On my side, I already checked the node cost for this register, which is correctly set to inf for spill, as well as the edge costs, and they look ok. I also attached my target's pbqp related file in case you want to double check what I did. This is llvm-3.0 based. It comprises 2 passes : the FemtoPBQPBuilder, plus a FemtoPairablepass, which undo some of the coalescer's work. The insertRegCopy may specifically need a double check, as I am not 100% sure to have updated correctly the LiveInterval information. In terms of registers, the Femto target is simplistic : a single register class GR16, for data and pointers, all i16. It has 16 registers, R0 to R15; R15 is used as stack pointer, and R14 potentialy as framepointer. A pair is constituted from a register + its successor, i.e. (R0, R1), (R1,R2), (R2, R3), ... are valid pairs. This is an instruction encoding constraint, as we only have 16bits wide instructions. Pairs involving R15 are never allowed, those with R14 may be allowed, depending on each function. Most instructions have no pairing constraints, and do not appear here, being handled by the PBQPBuilder default base class. A few instructions have 1 or 2 pairs of registers, and are all handled by the 2 passes above. Thanks for your help, -- Arnaud de Grandmaison Senior CPU engineer Business Unit Digital Tuner Parrot S.A. 174, quai de Jemmapes 75010 Paris - France Phone: +33 1 48 03 84 59 -------------- next part -------------- A non-text attachment was scrubbed... Name: FemtoRegisterAllocator.cpp Type: text/x-c++src Size: 17631 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120326/07c07e0e/attachment.cpp>