diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2008-03-11 07:19:34 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2008-03-11 07:19:34 +0000 |
| commit | 676dd7c80b6f91178452535ac45ca58feb23cc42 (patch) | |
| tree | 33282790f7a542b3ef2f3af7a23646d8f8514a1c /lib/CodeGen/VirtRegMap.cpp | |
| parent | 204496d58e7e740f0da6d41c6214a91d67950d26 (diff) | |
When the register allocator runs out of registers, spill a physical register around the def's and use's of the interval being allocated to make it possible for the interval to target a register and spill it right away and restore a register for uses. This likely generates terrible code but is before than aborting.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48218 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
| -rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index c39ac610e9..cce36e5162 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -125,6 +125,21 @@ void VirtRegMap::assignVirtReMatId(unsigned virtReg, int id) { Virt2ReMatIdMap[virtReg] = id; } +int VirtRegMap::getEmergencySpillSlot(const TargetRegisterClass *RC) { + std::map<const TargetRegisterClass*, int>::iterator I = + EmergencySpillSlots.find(RC); + if (I != EmergencySpillSlots.end()) + return I->second; + int SS = MF.getFrameInfo()->CreateStackObject(RC->getSize(), + RC->getAlignment()); + if (LowSpillSlot == NO_STACK_SLOT) + LowSpillSlot = SS; + if (HighSpillSlot == NO_STACK_SLOT || SS > HighSpillSlot) + HighSpillSlot = SS; + I->second = SS; + return SS; +} + void VirtRegMap::addSpillSlotUse(int FI, MachineInstr *MI) { if (!MF.getFrameInfo()->isFixedObjectIndex(FI)) { assert(FI >= 0 && "Spill slot index should not be negative!"); @@ -164,6 +179,7 @@ void VirtRegMap::RemoveMachineInstrFromMaps(MachineInstr *MI) { MI2VirtMap.erase(MI); SpillPt2VirtMap.erase(MI); RestorePt2VirtMap.erase(MI); + EmergencySpillMap.erase(MI); } void VirtRegMap::print(std::ostream &OS) const { @@ -1043,6 +1059,30 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { MachineInstr &MI = *MII; const TargetInstrDesc &TID = MI.getDesc(); + if (VRM.hasEmergencySpills(&MI)) { + // Spill physical register(s) in the rare case the allocator has run out + // of registers to allocate. + SmallSet<int, 4> UsedSS; + std::vector<unsigned> &EmSpills = VRM.getEmergencySpills(&MI); + for (unsigned i = 0, e = EmSpills.size(); i != e; ++i) { + unsigned PhysReg = EmSpills[i]; + const TargetRegisterClass *RC = + TRI->getPhysicalRegisterRegClass(PhysReg); + assert(RC && "Unable to determine register class!"); + int SS = VRM.getEmergencySpillSlot(RC); + if (UsedSS.count(SS)) + assert(0 && "Need to spill more than one physical registers!"); + UsedSS.insert(SS); + TII->storeRegToStackSlot(MBB, MII, PhysReg, true, SS, RC); + MachineInstr *StoreMI = prior(MII); + VRM.addSpillSlotUse(SS, StoreMI); + TII->loadRegFromStackSlot(MBB, next(MII), PhysReg, SS, RC); + MachineInstr *LoadMI = next(MII); + VRM.addSpillSlotUse(SS, LoadMI); + ++NumSpills; + } + } + // Insert restores here if asked to. if (VRM.isRestorePt(&MI)) { std::vector<unsigned> &RestoreRegs = VRM.getRestorePtRestores(&MI); |
