[llvm-commits] CVS: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp

Vikram Adve vadve at cs.uiuc.edu
Fri Oct 11 11:13:01 PDT 2002


Changes in directory llvm/lib/CodeGen/RegAlloc:

PhyRegAlloc.cpp updated: 1.77 -> 1.78

---
Log message:

Major bug fix: spill code for an instruction in a delay slot was
merrily being inserted before/after the instruction!


---
Diffs of the changes:

Index: llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp
diff -u llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.77 llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.78
--- llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp:1.77	Sat Sep 28 12:02:40 2002
+++ llvm/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp	Fri Oct 11 11:12:40 2002
@@ -419,6 +419,32 @@
 // Utility functions used below
 //-----------------------------
 inline void
+InsertBefore(MachineInstr* newMI,
+             MachineCodeForBasicBlock& MIVec,
+             MachineCodeForBasicBlock::iterator& MII)
+{
+  MII = MIVec.insert(MII, newMI);
+  ++MII;
+}
+
+inline void
+InsertAfter(MachineInstr* newMI,
+            MachineCodeForBasicBlock& MIVec,
+            MachineCodeForBasicBlock::iterator& MII)
+{
+  ++MII;    // insert before the next instruction
+  MII = MIVec.insert(MII, newMI);
+}
+
+inline void
+SubstituteInPlace(MachineInstr* newMI,
+                  MachineCodeForBasicBlock& MIVec,
+                  MachineCodeForBasicBlock::iterator MII)
+{
+  *MII = newMI;
+}
+
+inline void
 PrependInstructions(vector<MachineInstr *> &IBef,
                     MachineCodeForBasicBlock& MIVec,
                     MachineCodeForBasicBlock::iterator& MII,
@@ -434,8 +460,7 @@
             if (OrigMI) cerr << "For MInst:\n  " << *OrigMI;
             cerr << msg << "PREPENDed instr:\n  " << **AdIt << "\n";
           }
-          MII = MIVec.insert(MII, *AdIt);
-          ++MII;
+          InsertBefore(*AdIt, MIVec, MII);
         }
     }
 }
@@ -456,8 +481,7 @@
             if (OrigMI) cerr << "For MInst:\n  " << *OrigMI;
             cerr << msg << "APPENDed instr:\n  "  << **AdIt << "\n";
           }
-          ++MII;    // insert before the next instruction
-          MII = MIVec.insert(MII, *AdIt);
+          InsertAfter(*AdIt, MIVec, MII);
         }
     }
 }
@@ -477,7 +501,7 @@
   
   for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
        BBI != BBE; ++BBI) {
-    
+
     // iterate over all the machine instructions in BB
     MachineCodeForBasicBlock &MIVec = MachineCodeForBasicBlock::get(BBI);
     for (MachineCodeForBasicBlock::iterator MII = MIVec.begin();
@@ -538,13 +562,38 @@
                 insertCode4SpilledLR(LR, MInst, BBI, OpNum );
             }
         } // for each operand
-      
-      
+
       // Now add instructions that the register allocator inserts before/after 
       // this machine instructions (done only for calls/rets/incoming args)
       // We do this here, to ensure that spill for an instruction is inserted
       // closest as possible to an instruction (see above insertCode4Spill...)
       // 
+      // First, if the instruction in the delay slot of a branch needs
+      // instructions inserted, move it out of the delay slot and before the
+      // branch because putting code before or after it would be VERY BAD!
+      // 
+      unsigned bumpIteratorBy = 0;
+      if (MII != MIVec.begin())
+        if (unsigned predDelaySlots =
+            TM.getInstrInfo().getNumDelaySlots((*(MII-1))->getOpCode()))
+          {
+            assert(predDelaySlots==1 && "Not handling multiple delay slots!");
+            if (TM.getInstrInfo().isBranch((*(MII-1))->getOpCode())
+                && (AddedInstrMap.count(MInst) ||
+                    AddedInstrMap[MInst].InstrnsAfter.size() > 0))
+            {
+              // Current instruction is in the delay slot of a branch and it
+              // needs spill code inserted before or after it.
+              // Move it before the preceding branch.
+              InsertBefore(MInst, MIVec, --MII);
+              MachineInstr* nopI =
+                new MachineInstr(TM.getInstrInfo().getNOPOpCode());
+              SubstituteInPlace(nopI, MIVec, MII+1); // replace orig with NOP
+              --MII;                  // point to MInst in new location
+              bumpIteratorBy = 2;     // later skip the branch and the NOP!
+            }
+          }
+
       // If there are instructions to be added, *before* this machine
       // instruction, add them now.
       //      
@@ -561,9 +610,18 @@
 	// added after it must really go after the delayed instruction(s)
 	// So, we move the InstrAfter of the current instruction to the 
 	// corresponding delayed instruction
-	
-	unsigned delay;
-	if ((delay=TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) >0){ 
+	if (unsigned delay =
+            TM.getInstrInfo().getNumDelaySlots(MInst->getOpCode())) { 
+          
+          // Delayed instructions are typically branches or calls.  Let's make
+          // sure this is not a branch, otherwise "insert-after" is meaningless,
+          // and should never happen for any reason (spill code, register
+          // restores, etc.).
+          assert(! TM.getInstrInfo().isBranch(MInst->getOpCode()) &&
+                 ! TM.getInstrInfo().isReturn(MInst->getOpCode()) &&
+                 "INTERNAL ERROR: Register allocator should not be inserting "
+                 "any code after a branch or return!");
+
 	  move2DelayedInstr(MInst,  *(MII+delay) );
 	}
 	else {
@@ -572,7 +630,11 @@
 	  AppendInstructions(AddedInstrMap[MInst].InstrnsAfter, MIVec, MII,"");
 	}  // if not delay
       }
-      
+
+      // If we mucked with the instruction order above, adjust the loop iterator
+      if (bumpIteratorBy)
+        MII = MII + bumpIteratorBy;
+
     } // for each machine instruction
   }
 }





More information about the llvm-commits mailing list