From 5a3c6a87b0173b9d367f7b55e7c99e5110ede057 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 29 Jan 2009 02:20:59 +0000 Subject: Exit with nice warnings when register allocator run out of registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63267 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveInterval.cpp | 10 ++++ lib/CodeGen/LiveIntervalAnalysis.cpp | 14 ++++- lib/CodeGen/RegAllocLocal.cpp | 105 ++++++++++++++++++++++------------- 3 files changed, 88 insertions(+), 41 deletions(-) (limited to 'lib/CodeGen') diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 4392652..6341b9c 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -244,6 +244,16 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { return ranges.insert(it, LR); } +/// isInOneLiveRange - Return true if the range specified is entirely in the +/// a single LiveRange of the live interval. +bool LiveInterval::isInOneLiveRange(unsigned Start, unsigned End) { + Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start); + if (I == ranges.begin()) + return false; + --I; + return I->contains(Start) && I->contains(End-1); +} + /// removeRange - Remove the specified range from this interval. Note that /// the range must be in a single LiveRange in its entirety. diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 8cd82a6..8e8e8ff 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -2228,7 +2228,19 @@ void LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, unsigned Index = getInstructionIndex(MI); if (pli.liveAt(Index)) { vrm.addEmergencySpill(SpillReg, MI); - pli.removeRange(getLoadIndex(Index), getStoreIndex(Index)+1); + unsigned StartIdx = getLoadIndex(Index); + unsigned EndIdx = getStoreIndex(Index)+1; + if (pli.isInOneLiveRange(StartIdx, EndIdx)) + pli.removeRange(StartIdx, EndIdx); + else { + cerr << "Ran out of registers during register allocation!\n"; + if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { + cerr << "Please check your inline asm statement for invalid " + << "constraints:\n"; + MI->print(cerr.stream(), tm_); + } + exit(1); + } for (const unsigned* AS = tri_->getSubRegisters(SpillReg); *AS; ++AS) { if (!hasInterval(*AS)) continue; diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index 174e394..9fc5f73 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -27,6 +27,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -237,7 +238,7 @@ namespace { /// value. This method returns the modified instruction. /// MachineInstr *reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, - unsigned OpNum); + unsigned OpNum, SmallSet &RRegs); /// ComputeLocalLiveness - Computes liveness of registers within a basic /// block, setting the killed/dead flags as appropriate. @@ -475,7 +476,8 @@ unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I, /// modified instruction. /// MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, - unsigned OpNum) { + unsigned OpNum, + SmallSet &ReloadedRegs) { unsigned VirtReg = MI->getOperand(OpNum).getReg(); // If the virtual register is already available, just update the instruction @@ -513,6 +515,29 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, MF->getRegInfo().setPhysRegUsed(PhysReg); MI->getOperand(OpNum).setReg(PhysReg); // Assign the input register getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum); + + if (!ReloadedRegs.insert(PhysReg)) { + cerr << "Ran out of registers during register allocation!\n"; + if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { + cerr << "Please check your inline asm statement for invalid " + << "constraints:\n"; + MI->print(cerr.stream(), TM); + } + exit(1); + } + for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg); + *SubRegs; ++SubRegs) { + if (!ReloadedRegs.insert(*SubRegs)) { + cerr << "Ran out of registers during register allocation!\n"; + if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { + cerr << "Please check your inline asm statement for invalid " + << "constraints:\n"; + MI->print(cerr.stream(), TM); + } + exit(1); + } + } + return MI; } @@ -581,17 +606,16 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) { if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue; - const unsigned* subregs = TRI->getAliasSet(MO.getReg()); - if (subregs) { - while (*subregs) { + const unsigned* Aliases = TRI->getAliasSet(MO.getReg()); + if (Aliases) { + while (*Aliases) { DenseMap >::iterator - alias = LastUseDef.find(*subregs); + alias = LastUseDef.find(*Aliases); - if (alias != LastUseDef.end() && - alias->second.first != I) - LastUseDef[*subregs] = std::make_pair(I, i); + if (alias != LastUseDef.end() && alias->second.first != I) + LastUseDef[*Aliases] = std::make_pair(I, i); - ++subregs; + ++Aliases; } } } @@ -695,12 +719,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { MF->getRegInfo().setPhysRegUsed(Reg); PhysRegsUsed[Reg] = 0; // It is free and reserved now AddToPhysRegsUseOrder(Reg); - for (const unsigned *AliasSet = TRI->getSubRegisters(Reg); - *AliasSet; ++AliasSet) { - if (PhysRegsUsed[*AliasSet] != -2) { - AddToPhysRegsUseOrder(*AliasSet); - PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now - MF->getRegInfo().setPhysRegUsed(*AliasSet); + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + *SubRegs; ++SubRegs) { + if (PhysRegsUsed[*SubRegs] != -2) { + AddToPhysRegsUseOrder(*SubRegs); + PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now + MF->getRegInfo().setPhysRegUsed(*SubRegs); } } } @@ -778,12 +802,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { PhysRegsUsed[Reg] = 0; // It is free and reserved now AddToPhysRegsUseOrder(Reg); - for (const unsigned *AliasSet = TRI->getSubRegisters(Reg); - *AliasSet; ++AliasSet) { - if (PhysRegsUsed[*AliasSet] != -2) { - MF->getRegInfo().setPhysRegUsed(*AliasSet); - PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now - AddToPhysRegsUseOrder(*AliasSet); + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + *SubRegs; ++SubRegs) { + if (PhysRegsUsed[*SubRegs] != -2) { + MF->getRegInfo().setPhysRegUsed(*SubRegs); + PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now + AddToPhysRegsUseOrder(*SubRegs); } } } @@ -797,12 +821,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { // physical register is referenced by the instruction, that it is guaranteed // to be live-in, or the input is badly hosed. // + SmallSet ReloadedRegs; for (unsigned i = 0; i != MI->getNumOperands(); ++i) { MachineOperand& MO = MI->getOperand(i); // here we are looking for only used operands (never def&use) if (MO.isReg() && !MO.isDef() && MO.getReg() && !MO.isImplicit() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) - MI = reloadVirtReg(MBB, MI, i); + MI = reloadVirtReg(MBB, MI, i, ReloadedRegs); } // If this instruction is the last user of this register, kill the @@ -830,13 +855,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { DOUT << " Last use of " << TRI->getName(PhysReg) << "[%reg" << VirtReg <<"], removing it from live set\n"; removePhysReg(PhysReg); - for (const unsigned *AliasSet = TRI->getSubRegisters(PhysReg); - *AliasSet; ++AliasSet) { - if (PhysRegsUsed[*AliasSet] != -2) { + for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg); + *SubRegs; ++SubRegs) { + if (PhysRegsUsed[*SubRegs] != -2) { DOUT << " Last use of " - << TRI->getName(*AliasSet) + << TRI->getName(*SubRegs) << "[%reg" << VirtReg <<"], removing it from live set\n"; - removePhysReg(*AliasSet); + removePhysReg(*SubRegs); } } } @@ -861,12 +886,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { PhysRegsUsed[Reg] = 0; // It is free and reserved now AddToPhysRegsUseOrder(Reg); - for (const unsigned *AliasSet = TRI->getSubRegisters(Reg); - *AliasSet; ++AliasSet) { - if (PhysRegsUsed[*AliasSet] != -2) { - MF->getRegInfo().setPhysRegUsed(*AliasSet); - PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now - AddToPhysRegsUseOrder(*AliasSet); + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + *SubRegs; ++SubRegs) { + if (PhysRegsUsed[*SubRegs] != -2) { + MF->getRegInfo().setPhysRegUsed(*SubRegs); + PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now + AddToPhysRegsUseOrder(*SubRegs); } } } @@ -883,12 +908,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) { PhysRegsUsed[Reg] = 0; // It is free and reserved now } MF->getRegInfo().setPhysRegUsed(Reg); - for (const unsigned *AliasSet = TRI->getSubRegisters(Reg); - *AliasSet; ++AliasSet) { - if (PhysRegsUsed[*AliasSet] != -2) { - AddToPhysRegsUseOrder(*AliasSet); - PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now - MF->getRegInfo().setPhysRegUsed(*AliasSet); + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + *SubRegs; ++SubRegs) { + if (PhysRegsUsed[*SubRegs] != -2) { + AddToPhysRegsUseOrder(*SubRegs); + PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now + MF->getRegInfo().setPhysRegUsed(*SubRegs); } } } -- cgit v1.1