summaryrefslogtreecommitdiff
path: root/lib/CodeGen/PrologEpilogInserter.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-10-20 19:52:35 +0000
committerJim Grosbach <grosbach@apple.com>2009-10-20 19:52:35 +0000
commit03d02d4faa6cf8ae1337f64bc83dcbd9de570372 (patch)
tree0c6287774fac9e83aef7a8c8f410a5a5ef9c1ba8 /lib/CodeGen/PrologEpilogInserter.cpp
parentbab42bdd876f7233075075628c56987ce46bfe75 (diff)
downloadllvm-03d02d4faa6cf8ae1337f64bc83dcbd9de570372.tar.gz
llvm-03d02d4faa6cf8ae1337f64bc83dcbd9de570372.tar.bz2
llvm-03d02d4faa6cf8ae1337f64bc83dcbd9de570372.tar.xz
Better handle instructions that re-def a scratch register
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/PrologEpilogInserter.cpp')
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp27
1 files changed, 18 insertions, 9 deletions
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 873d2372c5..8388fdbd7c 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -778,6 +778,8 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
// directly.
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
MachineInstr *MI = I;
+ bool isDefInsn = false;
+ bool isKillInsn = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
if (MI->getOperand(i).isReg()) {
MachineOperand &MO = MI->getOperand(i);
@@ -802,6 +804,12 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
}
continue;
}
+ // If this is a def, remember that this insn defines the value.
+ // This lets us properly consider insns which re-use the scratch
+ // register, such as r2 = sub r2, #imm, in the middle of the
+ // scratch range.
+ if (MO.isDef())
+ isDefInsn = true;
// Have we already allocated a scratch register for this virtual?
if (Reg != CurrentVirtReg) {
@@ -866,19 +874,20 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
assert (CurrentScratchReg && "Missing scratch register!");
MI->getOperand(i).setReg(CurrentScratchReg);
- // If this is the last use of the register, stop tracking it.
if (MI->getOperand(i).isKill()) {
- PrevScratchReg = CurrentScratchReg;
- PrevLastUseMI = MI;
+ isKillInsn = true;
PrevLastUseOp = i;
- CurrentScratchReg = CurrentVirtReg = 0;
- havePrevValue = trackingCurrentValue;
- // Re-scan the operands of this instruction to catch definitions
- // of the scratch register we're using. This is to handle things
- // like ldr "r2, [scratch]" where scratch is r2.
- i = 0;
+ PrevLastUseMI = MI;
}
}
+ // If this is the last use of the scratch, stop tracking it. The
+ // last use will be a kill operand in an instruction that does
+ // not also define the scratch register.
+ if (isKillInsn && !isDefInsn) {
+ PrevScratchReg = CurrentScratchReg;
+ CurrentScratchReg = CurrentVirtReg = 0;
+ havePrevValue = trackingCurrentValue;
+ }
RS->forward(MI);
}
}