diff options
Diffstat (limited to 'llvm/lib/CodeGen/PrologEpilogInserter.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/PrologEpilogInserter.cpp | 31 | 
1 files changed, 24 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 3106455..d14d710 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/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?");    }  }  | 
