Multiple instructions can be inserted when eliminating frame indexes. We need
authorBill Wendling <isanbard@gmail.com>
Mon, 3 Mar 2008 22:11:16 +0000 (22:11 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 3 Mar 2008 22:11:16 +0000 (22:11 +0000)
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

lib/CodeGen/PrologEpilogInserter.cpp

index 3106455850931defc66aa541e9a1c24491b15ff4..d14d71026ef476c361aeeffa3e29f0c5da72348e 100644 (file)
@@ -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?");
   }
 }