When spilling an register, introduce a new temporary for each of its
spills. This allows for more flexibility when allocating registers for
spill code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13907 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 1dda527..e77babb 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -186,19 +186,23 @@
return true;
}
-void LiveIntervals::updateSpilledInterval(Interval& li,
- VirtRegMap& vrm,
- int slot)
+std::vector<LiveIntervals::Interval*>
+LiveIntervals::addIntervalsForSpills(const Interval& li,
+ VirtRegMap& vrm,
+ int slot)
{
+ std::vector<Interval*> added;
+
assert(li.weight != HUGE_VAL &&
"attempt to spill already spilled interval!");
- Interval::Ranges oldRanges;
- swap(oldRanges, li.ranges);
- DEBUG(std::cerr << "\t\t\t\tupdating interval: " << li);
+ DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: "
+ << li << '\n');
- for (Interval::Ranges::iterator i = oldRanges.begin(), e = oldRanges.end();
- i != e; ++i) {
+ const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
+
+ for (Interval::Ranges::const_iterator
+ i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
unsigned index = getBaseIndex(i->first);
unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
for (; index < end; index += InstrSlots::NUM) {
@@ -240,16 +244,31 @@
unsigned end = 1 + (mop.isDef() ?
getUseIndex(index+InstrSlots::NUM) :
getUseIndex(index));
- li.addRange(start, end);
+
+ // create a new register for this spill
+ unsigned nReg =
+ mf_->getSSARegMap()->createVirtualRegister(rc);
+ mi->SetMachineOperandReg(i, nReg);
+ vrm.grow();
+ vrm.assignVirt2StackSlot(nReg, slot);
+ Interval& nI = getOrCreateInterval(nReg);
+ assert(nI.empty());
+ // the spill weight is now infinity as it
+ // cannot be spilled again
+ nI.weight = HUGE_VAL;
+ nI.addRange(start, end);
+ added.push_back(&nI);
+ // update live variables
+ lv_->addVirtualRegisterKilled(nReg, mi->getParent(),mi);
+ DEBUG(std::cerr << "\t\t\t\tadded new interval: "
+ << nI << '\n');
}
}
}
}
}
- // the new spill weight is now infinity as it cannot be spilled again
- li.weight = HUGE_VAL;
- DEBUG(std::cerr << '\n');
- DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n');
+
+ return added;
}
void LiveIntervals::printRegName(unsigned reg) const