From f4840c07f84d018c4de5dbdad4166b9e162f8f89 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 16 Nov 2010 19:55:14 +0000 Subject: Fix emergency spilling in LiveIntervals::spillPhysRegAroundRegDefsUses. Always spill the full representative register at any point where any subregister is live. This fixes PR8620 which caused the old logic to get confused and not spill anything at all. The fundamental problem here is that the coalescer is too aggressive about physical register coalescing. It sometimes makes it impossible to allocate registers without these emergency spills. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119375 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 45 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 9b42012..c61b790 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1928,6 +1928,9 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, unsigned PhysReg, VirtRegMap &vrm) { unsigned SpillReg = getRepresentativeReg(PhysReg); + DEBUG(dbgs() << "spillPhysRegAroundRegDefsUses " << tri_->getName(PhysReg) + << " represented by " << tri_->getName(SpillReg) << '\n'); + for (const unsigned *AS = tri_->getAliasSet(PhysReg); *AS; ++AS) // If there are registers which alias PhysReg, but which are not a // sub-register of the chosen representative super register. Assert @@ -1939,15 +1942,16 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, SmallVector PRegs; if (hasInterval(SpillReg)) PRegs.push_back(SpillReg); - else { - SmallSet Added; - for (const unsigned* AS = tri_->getSubRegisters(SpillReg); *AS; ++AS) - if (Added.insert(*AS) && hasInterval(*AS)) { - PRegs.push_back(*AS); - for (const unsigned* ASS = tri_->getSubRegisters(*AS); *ASS; ++ASS) - Added.insert(*ASS); - } - } + for (const unsigned *SR = tri_->getSubRegisters(SpillReg); *SR; ++SR) + if (hasInterval(*SR)) + PRegs.push_back(*SR); + + DEBUG({ + dbgs() << "Trying to spill:"; + for (unsigned i = 0, e = PRegs.size(); i != e; ++i) + dbgs() << ' ' << tri_->getName(PRegs[i]); + dbgs() << '\n'; + }); SmallPtrSet SeenMIs; for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(li.reg), @@ -1958,18 +1962,16 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, continue; SeenMIs.insert(MI); SlotIndex Index = getInstructionIndex(MI); + bool LiveReg = false; for (unsigned i = 0, e = PRegs.size(); i != e; ++i) { unsigned PReg = PRegs[i]; LiveInterval &pli = getInterval(PReg); if (!pli.liveAt(Index)) continue; - vrm.addEmergencySpill(PReg, MI); + LiveReg = true; SlotIndex StartIdx = Index.getLoadIndex(); SlotIndex EndIdx = Index.getNextIndex().getBaseIndex(); - if (pli.isInOneLiveRange(StartIdx, EndIdx)) { - pli.removeRange(StartIdx, EndIdx); - Cut = true; - } else { + if (!pli.isInOneLiveRange(StartIdx, EndIdx)) { std::string msg; raw_string_ostream Msg(msg); Msg << "Ran out of registers during register allocation!"; @@ -1980,15 +1982,14 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li, } report_fatal_error(Msg.str()); } - for (const unsigned* AS = tri_->getSubRegisters(PReg); *AS; ++AS) { - if (!hasInterval(*AS)) - continue; - LiveInterval &spli = getInterval(*AS); - if (spli.liveAt(Index)) - spli.removeRange(Index.getLoadIndex(), - Index.getNextIndex().getBaseIndex()); - } + pli.removeRange(StartIdx, EndIdx); + LiveReg = true; } + if (!LiveReg) + continue; + DEBUG(dbgs() << "Emergency spill around " << Index << '\t' << *MI); + vrm.addEmergencySpill(SpillReg, MI); + Cut = true; } return Cut; } -- cgit v1.1