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

Chris Lattner lattner at cs.uiuc.edu
Sun Dec 15 13:52:01 PST 2002


Changes in directory llvm/lib/CodeGen:

RegAllocSimple.cpp updated: 1.17 -> 1.18

---
Log message:

* Simplify code a bit by breaking the PHI node handling stuff out into a seperate
  function from normal regalloc code
* Make the regalloc for a block a function instead of part of runOnMachineBB, which
  makes it easier to see what's going on in runOnMBB.


---
Diffs of the changes:

Index: llvm/lib/CodeGen/RegAllocSimple.cpp
diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.17 llvm/lib/CodeGen/RegAllocSimple.cpp:1.18
--- llvm/lib/CodeGen/RegAllocSimple.cpp:1.17	Sun Dec 15 13:07:34 2002
+++ llvm/lib/CodeGen/RegAllocSimple.cpp	Sun Dec 15 13:51:14 2002
@@ -60,10 +60,8 @@
     std::map<unsigned, unsigned> RegsUsed;
     std::map<const TargetRegisterClass*, unsigned> RegClassIdx;
 
-    RegAllocSimple(TargetMachine &tm) : TM(tm),
-                                        RegInfo(tm.getRegisterInfo()),
-                                        PhysRegClasses(RegInfo)
-    {
+    RegAllocSimple(TargetMachine &tm)
+      : TM(tm), RegInfo(tm.getRegisterInfo()), PhysRegClasses(RegInfo) {
       RegsUsed[RegInfo->getFramePointer()] = 1;
       RegsUsed[RegInfo->getStackPointer()] = 1;
 
@@ -75,7 +73,8 @@
       return RegsUsed.find(Reg) == RegsUsed.end();
     }
 
-    ///
+    /// allocateStackSpaceFor - This allocates space for the specified virtual
+    /// register to be held on the stack.
     unsigned allocateStackSpaceFor(unsigned VirtReg, 
                                    const TargetRegisterClass *regClass);
 
@@ -85,7 +84,7 @@
 
     /// Returns all `borrowed' registers back to the free pool
     void clearAllRegs() {
-        RegClassIdx.clear();
+      RegClassIdx.clear();
     }
 
     /// Invalidates any references, real or implicit, to physical registers
@@ -106,23 +105,23 @@
     void cleanupAfterFunction() {
       VirtReg2OffsetMap.clear();
       SSA2PhysRegMap.clear();
-      NumBytesAllocated = 4;   /* FIXME: This is X86 specific */
+      NumBytesAllocated = 4;   // FIXME: This is X86 specific
     }
 
     /// Moves value from memory into that register
     MachineBasicBlock::iterator
-    moveUseToReg (MachineBasicBlock *MBB,
+    moveUseToReg (MachineBasicBlock &MBB,
                   MachineBasicBlock::iterator I, unsigned VirtReg,
                   unsigned &PhysReg);
 
     /// Saves reg value on the stack (maps virtual register to stack value)
     MachineBasicBlock::iterator
-    saveVirtRegToStack (MachineBasicBlock *MBB,
+    saveVirtRegToStack (MachineBasicBlock &MBB,
                         MachineBasicBlock::iterator I, unsigned VirtReg,
                         unsigned PhysReg);
 
     MachineBasicBlock::iterator
-    savePhysRegToStack (MachineBasicBlock *MBB,
+    savePhysRegToStack (MachineBasicBlock &MBB,
                         MachineBasicBlock::iterator I, unsigned PhysReg);
 
     /// runOnFunction - Top level implementation of instruction selection for
@@ -130,6 +129,13 @@
     ///
     bool runOnMachineFunction(MachineFunction &Fn);
 
+    /// AllocateBasicBlock - Register allocate the specified basic block.
+    void AllocateBasicBlock(MachineBasicBlock &MBB);
+
+    /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions
+    /// in predecessor basic blocks.
+    void EliminatePHINodes(MachineBasicBlock &MBB);
+
     bool runOnFunction(Function &Fn) {
       return runOnMachineFunction(MachineFunction::get(&Fn));
     }
@@ -137,6 +143,8 @@
 
 }
 
+/// allocateStackSpaceFor - This allocates space for the specified virtual
+/// register to be held on the stack.
 unsigned RegAllocSimple::allocateStackSpaceFor(unsigned VirtReg,
                                             const TargetRegisterClass *regClass)
 {
@@ -180,7 +188,7 @@
 }
 
 MachineBasicBlock::iterator
-RegAllocSimple::moveUseToReg (MachineBasicBlock *MBB,
+RegAllocSimple::moveUseToReg (MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator I,
                               unsigned VirtReg, unsigned &PhysReg)
 {
@@ -191,13 +199,13 @@
   PhysReg = getFreeReg(VirtReg);
 
   // Add move instruction(s)
-  return RegInfo->loadRegOffset2Reg(MBB, I, PhysReg,
+  return RegInfo->loadRegOffset2Reg(&MBB, I, PhysReg,
                                     RegInfo->getFramePointer(),
                                     -stackOffset, regClass->getDataSize());
 }
 
 MachineBasicBlock::iterator
-RegAllocSimple::saveVirtRegToStack (MachineBasicBlock *MBB,
+RegAllocSimple::saveVirtRegToStack (MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator I,
                                     unsigned VirtReg, unsigned PhysReg)
 {
@@ -207,13 +215,13 @@
   unsigned stackOffset = allocateStackSpaceFor(VirtReg, regClass);
 
   // Add move instruction(s)
-  return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
+  return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg,
                                      RegInfo->getFramePointer(),
                                      -stackOffset, regClass->getDataSize());
 }
 
 MachineBasicBlock::iterator
-RegAllocSimple::savePhysRegToStack (MachineBasicBlock *MBB,
+RegAllocSimple::savePhysRegToStack (MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator I,
                                     unsigned PhysReg)
 {
@@ -223,157 +231,157 @@
   unsigned offset = allocateStackSpaceFor(PhysReg, regClass);
 
   // Add move instruction(s)
-  return RegInfo->storeReg2RegOffset(MBB, I, PhysReg,
+  return RegInfo->storeReg2RegOffset(&MBB, I, PhysReg,
                                      RegInfo->getFramePointer(),
                                      offset, regClass->getDataSize());
 }
 
-bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
-  cleanupAfterFunction();
-
-  unsigned virtualReg, physReg;
-  DEBUG(std::cerr << "Machine Function " << "\n");
-  MF = &Fn;
-
-  for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
-       MBB != MBBe; ++MBB)
-  {
-    MachineBasicBlock *CurrMBB = &(*MBB);
-
-    // Handle PHI instructions specially: add moves to each pred block
-    while (MBB->front()->getOpcode() == 0) {
-      MachineInstr *MI = MBB->front();
-      // get rid of the phi
-      MBB->erase(MBB->begin());
+/// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
+/// predecessor basic blocks.
+void RegAllocSimple::EliminatePHINodes(MachineBasicBlock &MBB) {
+  while (MBB.front()->getOpcode() == 0) {
+    MachineInstr *MI = MBB.front();
+    // get rid of the phi
+    MBB.erase(MBB.begin());
     
-      // a preliminary pass that will invalidate any registers that
-      // are used by the instruction (including implicit uses)
-      invalidatePhysRegs(MI);
-
-      DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n");
-
-      DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
-      MachineOperand &targetReg = MI->getOperand(0);
-
-      // If it's a virtual register, allocate a physical one
-      // otherwise, just use whatever register is there now
-      // note: it MUST be a register -- we're assigning to it
-      virtualReg = (unsigned) targetReg.getAllocatedRegNum();
-      if (targetReg.isVirtualRegister()) {
-        physReg = getFreeReg(virtualReg);
-      } else {
-        physReg = virtualReg;
-      }
-
-      // Find the register class of the target register: should be the
-      // same as the values we're trying to store there
-      const TargetRegisterClass* regClass = PhysRegClasses[physReg];
-      assert(regClass && "Target register class not found!");
-      unsigned dataSize = regClass->getDataSize();
-
-      for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
-        MachineOperand &opVal = MI->getOperand(i-1);
-
-        // Get the MachineBasicBlock equivalent of the BasicBlock that is the
-        // source path the phi
-        MachineBasicBlock *opBlock = MI->getOperand(i).getMachineBasicBlock();
-        MachineBasicBlock::iterator opI = opBlock->end();
-        MachineInstr *opMI = *(--opI);
-        const MachineInstrInfo &MII = TM.getInstrInfo();
-        // must backtrack over ALL the branches in the previous block, until no more
-        while ((MII.isBranch(opMI->getOpcode()) || MII.isReturn(opMI->getOpcode()))
-               && opI != opBlock->begin())
-        {
-          opMI = *(--opI);
-        }
-        // move back to the first branch instruction so new instructions
-        // are inserted right in front of it and not in front of a non-branch
-        ++opI; 
-
-
-        // Retrieve the constant value from this op, move it to target
-        // register of the phi
-        if (opVal.getType() == MachineOperand::MO_SignExtendedImmed ||
-            opVal.getType() == MachineOperand::MO_UnextendedImmed)
-        {
-          opI = RegInfo->moveImm2Reg(opBlock, opI, physReg,
-                                     (unsigned) opVal.getImmedValue(),
-                                     dataSize);
-          saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
-        } else {
-          // Allocate a physical register and add a move in the BB
-          unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum();
-          unsigned opPhysReg; // = getFreeReg(opVirtualReg);
-          opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg);
-          //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg,
-          //                           dataSize);
-          // Save that register value to the stack of the TARGET REG
-          saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
-        }
+    // a preliminary pass that will invalidate any registers that
+    // are used by the instruction (including implicit uses)
+    invalidatePhysRegs(MI);
+    
+    DEBUG(std::cerr << "num invalid regs: " << RegsUsed.size() << "\n");
+    
+    DEBUG(std::cerr << "num ops: " << MI->getNumOperands() << "\n");
+    MachineOperand &targetReg = MI->getOperand(0);
+    
+    // If it's a virtual register, allocate a physical one
+    // otherwise, just use whatever register is there now
+    // note: it MUST be a register -- we're assigning to it
+    unsigned virtualReg = (unsigned) targetReg.getAllocatedRegNum();
+    unsigned physReg;
+    if (targetReg.isVirtualRegister()) {
+      physReg = getFreeReg(virtualReg);
+    } else {
+      physReg = virtualReg;
+    }
+    
+    // Find the register class of the target register: should be the
+    // same as the values we're trying to store there
+    const TargetRegisterClass* regClass = PhysRegClasses[physReg];
+    assert(regClass && "Target register class not found!");
+    unsigned dataSize = regClass->getDataSize();
+    
+    for (int i = MI->getNumOperands() - 1; i >= 2; i-=2) {
+      MachineOperand &opVal = MI->getOperand(i-1);
+      
+      // Get the MachineBasicBlock equivalent of the BasicBlock that is the
+      // source path the phi
+      MachineBasicBlock &opBlock = *MI->getOperand(i).getMachineBasicBlock();
+      MachineBasicBlock::iterator opI = opBlock.end();
+      MachineInstr *opMI = *--opI;
+      const MachineInstrInfo &MII = TM.getInstrInfo();
 
-        // make regs available to other instructions
-        clearAllRegs();
+      // must backtrack over ALL the branches in the previous block, until no
+      // more
+      while (MII.isBranch(opMI->getOpcode()) && opI != opBlock.begin())
+        opMI = *--opI;
+
+      // move back to the first branch instruction so new instructions
+      // are inserted right in front of it and not in front of a non-branch
+      if (!MII.isBranch(opMI->getOpcode()))
+        ++opI;
+      
+      // Retrieve the constant value from this op, move it to target
+      // register of the phi
+      if (opVal.isImmediate()) {
+        opI = RegInfo->moveImm2Reg(&opBlock, opI, physReg,
+                                   (unsigned) opVal.getImmedValue(),
+                                   dataSize);
+        saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
+      } else {
+        // Allocate a physical register and add a move in the BB
+        unsigned opVirtualReg = (unsigned) opVal.getAllocatedRegNum();
+        unsigned opPhysReg; // = getFreeReg(opVirtualReg);
+        opI = moveUseToReg(opBlock, opI, opVirtualReg, physReg);
+        //opI = RegInfo->moveReg2Reg(opBlock, opI, physReg, opPhysReg,
+        //                           dataSize);
+        // Save that register value to the stack of the TARGET REG
+        saveVirtRegToStack(opBlock, opI, virtualReg, physReg);
       }
       
-      // really delete the instruction
-      delete MI;
+      // make regs available to other instructions
+      clearAllRegs();
     }
+    
+    // really delete the instruction
+    delete MI;
+  }
+}
 
-    //loop over each basic block
-    for (MachineBasicBlock::iterator I = MBB->begin(); I != MBB->end(); ++I)
-    {
-      MachineInstr *MI = *I;
-
-      // a preliminary pass that will invalidate any registers that
-      // are used by the instruction (including implicit uses)
-      invalidatePhysRegs(MI);
-
-      // Loop over uses, move from memory into registers
-      for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
-        MachineOperand &op = MI->getOperand(i);
-
-        if (op.getType() == MachineOperand::MO_SignExtendedImmed ||
-            op.getType() == MachineOperand::MO_UnextendedImmed)
-        {
-          DEBUG(std::cerr << "const\n");
-        } else if (op.isVirtualRegister()) {
-          virtualReg = (unsigned) op.getAllocatedRegNum();
-          DEBUG(std::cerr << "op: " << op << "\n");
-          DEBUG(std::cerr << "\t inst[" << i << "]: ";
-                MI->print(std::cerr, TM));
-
-          // make sure the same virtual register maps to the same physical
-          // register in any given instruction
-          if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) {
-            physReg = VirtReg2PhysRegMap[virtualReg];
-          } else {
-            if (op.opIsDef()) {
-              if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
-                // must be same register number as the first operand
-                // This maps a = b + c into b += c, and saves b into a's spot
-                physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum();
-              } else {
-                physReg = getFreeReg(virtualReg);
-              }
-              MachineBasicBlock::iterator J = I;
-              J = saveVirtRegToStack(CurrMBB, ++J, virtualReg, physReg);
-              I = --J;
+
+void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) {
+  // Handle PHI instructions specially: add moves to each pred block
+  EliminatePHINodes(MBB);
+  
+  //loop over each basic block
+  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
+    MachineInstr *MI = *I;
+    
+    // a preliminary pass that will invalidate any registers that
+    // are used by the instruction (including implicit uses)
+    invalidatePhysRegs(MI);
+    
+    // Loop over uses, move from memory into registers
+    for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
+      MachineOperand &op = MI->getOperand(i);
+      
+      if (op.isImmediate()) {
+        DEBUG(std::cerr << "const\n");
+      } else if (op.isVirtualRegister()) {
+        unsigned virtualReg = (unsigned) op.getAllocatedRegNum();
+        DEBUG(std::cerr << "op: " << op << "\n");
+        DEBUG(std::cerr << "\t inst[" << i << "]: ";
+              MI->print(std::cerr, TM));
+        
+        // make sure the same virtual register maps to the same physical
+        // register in any given instruction
+        unsigned physReg;
+        if (VirtReg2PhysRegMap.find(virtualReg) != VirtReg2PhysRegMap.end()) {
+          physReg = VirtReg2PhysRegMap[virtualReg];
+        } else {
+          if (op.opIsDef()) {
+            if (TM.getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
+              // must be same register number as the first operand
+              // This maps a = b + c into b += c, and saves b into a's spot
+              physReg = (unsigned) MI->getOperand(1).getAllocatedRegNum();
             } else {
-              I = moveUseToReg(CurrMBB, I, virtualReg, physReg);
+              physReg = getFreeReg(virtualReg);
             }
-            VirtReg2PhysRegMap[virtualReg] = physReg;
+            MachineBasicBlock::iterator J = I;
+            J = saveVirtRegToStack(MBB, ++J, virtualReg, physReg);
+            I = --J;
+          } else {
+            I = moveUseToReg(MBB, I, virtualReg, physReg);
           }
-          MI->SetMachineOperandReg(i, physReg);
-          DEBUG(std::cerr << "virt: " << virtualReg << 
-                ", phys: " << op.getAllocatedRegNum() << "\n");
+          VirtReg2PhysRegMap[virtualReg] = physReg;
         }
+        MI->SetMachineOperandReg(i, physReg);
+        DEBUG(std::cerr << "virt: " << virtualReg << 
+              ", phys: " << op.getAllocatedRegNum() << "\n");
       }
-
-      clearAllRegs();
-      VirtReg2PhysRegMap.clear();
     }
-
+    
+    clearAllRegs();
+    VirtReg2PhysRegMap.clear();
   }
+}
+
+bool RegAllocSimple::runOnMachineFunction(MachineFunction &Fn) {
+  DEBUG(std::cerr << "Machine Function " << "\n");
+  MF = &Fn;
+
+  for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
+       MBB != MBBe; ++MBB)
+    AllocateBasicBlock(*MBB);
 
   // add prologue we should preserve callee-save registers...
   MachineFunction::iterator Fi = Fn.begin();
@@ -381,21 +389,22 @@
   MachineBasicBlock::iterator MBBi = MBB->begin();
   RegInfo->emitPrologue(MBB, MBBi, NumBytesAllocated);
 
+  const MachineInstrInfo &MII = TM.getInstrInfo();
+
   // add epilogue to restore the callee-save registers
   // loop over the basic block
   for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
-       MBB != MBBe; ++MBB)
-  {
+       MBB != MBBe; ++MBB) {
     // check if last instruction is a RET
-    MachineBasicBlock::iterator I = (*MBB).end();
-    MachineInstr *MI = *(--I);
-    const MachineInstrInfo &MII = TM.getInstrInfo();
+    MachineBasicBlock::iterator I = MBB->end();
+    MachineInstr *MI = *--I;
     if (MII.isReturn(MI->getOpcode())) {
       // this block has a return instruction, add epilogue
       RegInfo->emitEpilogue(MBB, I, NumBytesAllocated);
     }
   }
 
+  cleanupAfterFunction();
   return false;  // We never modify the LLVM itself.
 }
 





More information about the llvm-commits mailing list