summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h17
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp18
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp73
3 files changed, 84 insertions, 24 deletions
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 49d16892f8..95bf29167c 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -93,6 +93,15 @@ public:
while (MBBI != I) forward();
}
+ /// Invert the behavior of forward() on the current instruction (undo the
+ /// changes to the available registers made by forward()).
+ void unprocess();
+
+ /// Unprocess instructions until you reach the provided iterator.
+ void unprocess(MachineBasicBlock::iterator I) {
+ while (MBBI != I) unprocess();
+ }
+
/// skipTo - Move the internal MBB iterator but do not update register states.
void skipTo(MachineBasicBlock::iterator I) {
if (I == MachineBasicBlock::iterator(NULL))
@@ -100,6 +109,10 @@ public:
MBBI = I;
}
+ MachineBasicBlock::iterator getCurrentPosition() const {
+ return MBBI;
+ }
+
/// getRegsUsed - return all registers currently in use in used.
void getRegsUsed(BitVector &used, bool includeReserved);
@@ -171,6 +184,10 @@ private:
RegsAvailable |= Regs;
}
+ /// Processes the current instruction and fill the KillRegs and DefRegs bit
+ /// vectors.
+ void determineKillsAndDefs();
+
/// Add Reg and all its sub-registers to BV.
void addRegWithSubRegs(BitVector &BV, unsigned Reg);
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 5a168dd244..e5872df731 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -826,6 +826,8 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
MachineInstr *MI = I;
MachineBasicBlock::iterator J = llvm::next(I);
+ MachineBasicBlock::iterator P = I == BB->begin() ?
+ MachineBasicBlock::iterator(NULL) : llvm::prior(I);
// RS should process this instruction before we might scavenge at this
// location. This is because we might be replacing a virtual register
@@ -869,8 +871,20 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
// problem because we need the spill code before I: Move I to just
// prior to J.
if (I != llvm::prior(J)) {
- BB->splice(J, BB, I++);
- RS->skipTo(I == BB->begin() ? NULL : llvm::prior(I));
+ BB->splice(J, BB, I);
+
+ // Before we move I, we need to prepare the RS to visit I again.
+ // Specifically, RS will assert if it sees uses of registers that
+ // it believes are undefined. Because we have already processed
+ // register kills in I, when it visits I again, it will believe that
+ // those registers are undefined. To avoid this situation, unprocess
+ // the instruction I.
+ assert(RS->getCurrentPosition() == I &&
+ "The register scavenger has an unexpected position");
+ I = P;
+ RS->unprocess(P);
+
+ // RS->skipTo(I == BB->begin() ? NULL : llvm::prior(I));
} else
++I;
}
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 55a66ba548..07ace7a436 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -110,30 +110,11 @@ void RegScavenger::addRegWithSubRegs(BitVector &BV, unsigned Reg) {
BV.set(*SubRegs);
}
-void RegScavenger::forward() {
- // Move ptr forward.
- if (!Tracking) {
- MBBI = MBB->begin();
- Tracking = true;
- } else {
- assert(MBBI != MBB->end() && "Already past the end of the basic block!");
- MBBI = llvm::next(MBBI);
- }
- assert(MBBI != MBB->end() && "Already at the end of the basic block!");
+void RegScavenger::determineKillsAndDefs() {
+ assert(Tracking && "Must be tracking to determine kills and defs");
MachineInstr *MI = MBBI;
-
- 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())
- return;
+ assert(!MI->isDebugValue() && "Debug values have no kills or defs");
// Find out which registers are early clobbered, killed, defined, and marked
// def-dead in this instruction.
@@ -167,6 +148,54 @@ void RegScavenger::forward() {
addRegWithSubRegs(DefRegs, Reg);
}
}
+}
+
+void RegScavenger::unprocess() {
+ assert(Tracking && "Cannot unprocess because we're not tracking");
+
+ MachineInstr *MI = MBBI;
+ if (MI->isDebugValue())
+ return;
+
+ determineKillsAndDefs();
+
+ // Commit the changes.
+ setUsed(KillRegs);
+ setUnused(DefRegs);
+
+ if (MBBI == MBB->begin()) {
+ MBBI = MachineBasicBlock::iterator(NULL);
+ Tracking = false;
+ } else
+ --MBBI;
+}
+
+void RegScavenger::forward() {
+ // Move ptr forward.
+ if (!Tracking) {
+ MBBI = MBB->begin();
+ Tracking = true;
+ } else {
+ assert(MBBI != MBB->end() && "Already past the end of the basic block!");
+ MBBI = llvm::next(MBBI);
+ }
+ assert(MBBI != MBB->end() && "Already at the end of the basic block!");
+
+ MachineInstr *MI = MBBI;
+
+ 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())
+ return;
+
+ determineKillsAndDefs();
// Verify uses and defs.
#ifndef NDEBUG