summaryrefslogtreecommitdiff
path: root/lib/CodeGen/PrologEpilogInserter.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2008-03-03 22:11:16 +0000
committerBill Wendling <isanbard@gmail.com>2008-03-03 22:11:16 +0000
commit988a5782d3ce3cddc65d57d6aac7312d33ed59ab (patch)
tree16b1f90503e71204372fd74c859e80c908b657ea /lib/CodeGen/PrologEpilogInserter.cpp
parentc2a324fa364601c863416eb558f399200a7e0978 (diff)
downloadllvm-988a5782d3ce3cddc65d57d6aac7312d33ed59ab.tar.gz
llvm-988a5782d3ce3cddc65d57d6aac7312d33ed59ab.tar.bz2
llvm-988a5782d3ce3cddc65d57d6aac7312d33ed59ab.tar.xz
Multiple instructions can be inserted when eliminating frame indexes. We need
the register scavenger to process all of those new instructions instead of just the last one inserted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47860 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/PrologEpilogInserter.cpp')
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp31
1 files changed, 24 insertions, 7 deletions
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 3106455850..d14d71026e 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -530,27 +530,44 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
// Visit the instructions created by eliminateCallFramePseudoInstr().
I = next(PrevI);
MI = NULL;
- } else if (I->getOpcode() == TargetInstrInfo::DECLARE)
+ } else if (I->getOpcode() == TargetInstrInfo::DECLARE) {
// Ignore it.
- I++;
- else {
- I++;
+ ++I;
+ } else {
+ bool DoIncr = true;
+
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
if (MI->getOperand(i).isFrameIndex()) {
+ // Some instructions (e.g. inline asm instructions) can have
+ // multiple frame indices and/or cause eliminateFrameIndex to insert
+ // more than one instruction. We need the register scavenger to go
+ // through all of these instructions so that it can update its
+ // register information. We keep the iterator at the point before
+ // insertion so that we can revisit them in full.
+ bool AtBeginning = (I == BB->begin());
+ if (!AtBeginning) --I;
+
// If this instruction has a FrameIndex operand, we need to use that
// target machine register info object to eliminate it.
TRI.eliminateFrameIndex(MI, SPAdj, RS);
- // Revisit the instruction in full. Some instructions (e.g. inline
- // asm instructions) can have multiple frame indices.
- --I;
+ // Reset the iterator if we were at the beginning of the BB.
+ if (AtBeginning) {
+ I = BB->begin();
+ DoIncr = false;
+ }
+
MI = 0;
break;
}
+
+ if (DoIncr) ++I;
}
+
// Update register states.
if (RS && MI) RS->forward(MI);
}
+
assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?");
}
}