aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2013-03-22 23:32:27 +0000
committerHal Finkel <hfinkel@anl.gov>2013-03-22 23:32:27 +0000
commitdc3beb90178fc316f63790812b22201884eaa017 (patch)
treed3574ac59a9d120549452dd0f94db575bb04096e /lib/CodeGen/RegisterScavenging.cpp
parenta2e3834d1644889484ef3a8a94189b7369e3eaf9 (diff)
Allow the register scavenger to spill multiple registers
This patch lets the register scavenger make use of multiple spill slots in order to guarantee that it will be able to provide multiple registers simultaneously. To support this, the RS's API has changed slightly: setScavengingFrameIndex / getScavengingFrameIndex have been replaced by addScavengingFrameIndex / isScavengingFrameIndex / getScavengingFrameIndices. In forthcoming commits, the PowerPC backend will use this capability in order to implement the spilling of condition registers, and some special-purpose registers, without relying on r0 being reserved. In some cases, spilling these registers requires two GPRs: one for addressing and one to hold the value being transferred. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177774 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index d0d30e8f94..be33854060 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -45,8 +45,11 @@ bool RegScavenger::isAliasUsed(unsigned Reg) const {
}
void RegScavenger::initRegState() {
- ScavengedReg = 0;
- ScavengeRestore = NULL;
+ for (SmallVector<ScavengedInfo, 2>::iterator I = Scavenged.begin(),
+ IE = Scavenged.end(); I != IE; ++I) {
+ I->Reg = 0;
+ I->Restore = NULL;
+ }
// All registers started out unused.
RegsAvailable.set();
@@ -120,9 +123,13 @@ void RegScavenger::forward() {
MachineInstr *MI = MBBI;
- if (MI == ScavengeRestore) {
- ScavengedReg = 0;
- ScavengeRestore = NULL;
+ for (SmallVector<ScavengedInfo, 2>::iterator I = Scavenged.begin(),
+ IE = Scavenged.end(); I != IE; ++I) {
+ if (I->Restore != MI)
+ continue;
+
+ I->Reg = 0;
+ I->Restore = NULL;
}
if (MI->isDebugValue())
@@ -358,36 +365,44 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
return SReg;
}
- assert(ScavengedReg == 0 &&
- "Scavenger slot is live, unable to scavenge another register!");
+ // Find an available scavenging slot.
+ int SI;
+ for (SI = 0; SI < Scavenged.size(); ++SI)
+ if (Scavenged[SI].Reg == 0)
+ break;
+
+ assert(SI < Scavenged.size() &&
+ "Scavenger slots are live, unable to scavenge another register!");
// Avoid infinite regress
- ScavengedReg = SReg;
+ Scavenged[SI].Reg = SReg;
// If the target knows how to save/restore the register, let it do so;
// otherwise, use the emergency stack spill slot.
if (!TRI->saveScavengerRegister(*MBB, I, UseMI, RC, SReg)) {
// Spill the scavenged register before I.
- assert(ScavengingFrameIndex >= 0 &&
+ assert(Scavenged[SI].FrameIndex >= 0 &&
"Cannot scavenge register without an emergency spill slot!");
- TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC,TRI);
+ TII->storeRegToStackSlot(*MBB, I, SReg, true, Scavenged[SI].FrameIndex,
+ RC, TRI);
MachineBasicBlock::iterator II = prior(I);
unsigned FIOperandNum = getFrameIndexOperandNum(II);
TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
// Restore the scavenged register before its use (or first terminator).
- TII->loadRegFromStackSlot(*MBB, UseMI, SReg, ScavengingFrameIndex, RC, TRI);
+ TII->loadRegFromStackSlot(*MBB, UseMI, SReg, Scavenged[SI].FrameIndex,
+ RC, TRI);
II = prior(UseMI);
FIOperandNum = getFrameIndexOperandNum(II);
TRI->eliminateFrameIndex(II, SPAdj, FIOperandNum, this);
}
- ScavengeRestore = prior(UseMI);
+ Scavenged[SI].Restore = prior(UseMI);
// Doing this here leads to infinite regress.
- // ScavengedReg = SReg;
+ // Scavenged[SI].Reg = SReg;
DEBUG(dbgs() << "Scavenged register (with spill): " << TRI->getName(SReg) <<
"\n");