[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Mar 16 10:25:35 PST 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.167 -> 1.168
---
Log message:

Save/restore VRSAVE once per function, not once per block.


---
Diffs of the changes:  (+52 -39)

 PPCISelDAGToDAG.cpp |   91 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 52 insertions(+), 39 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.167 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.168
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.167	Tue Mar 14 11:56:49 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Thu Mar 16 12:25:23 2006
@@ -39,17 +39,21 @@
   /// instructions for SelectionDAG operations.
   ///
   class PPCDAGToDAGISel : public SelectionDAGISel {
+    PPCTargetMachine &TM;
     PPCTargetLowering PPCLowering;
     unsigned GlobalBaseReg;
   public:
-    PPCDAGToDAGISel(PPCTargetMachine &TM)
-      : SelectionDAGISel(PPCLowering),
-        PPCLowering(*TM.getTargetLowering()){}
+    PPCDAGToDAGISel(PPCTargetMachine &tm)
+      : SelectionDAGISel(PPCLowering), TM(tm),
+        PPCLowering(*TM.getTargetLowering()) {}
     
     virtual bool runOnFunction(Function &Fn) {
       // Make sure we re-emit a set of the global base reg if necessary
       GlobalBaseReg = 0;
-      return SelectionDAGISel::runOnFunction(Fn);
+      SelectionDAGISel::runOnFunction(Fn);
+      
+      InsertVRSaveCode(Fn);
+      return true;
     }
    
     /// getI32Imm - Return a target constant with the specified value, of type
@@ -121,6 +125,8 @@
     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
     
+    void InsertVRSaveCode(Function &Fn);
+
     virtual const char *getPassName() const {
       return "PowerPC DAG->DAG Pattern Instruction Selection";
     } 
@@ -199,13 +205,19 @@
   
   // Emit machine code to BB.
   ScheduleAndEmitDAG(DAG);
-  
+}
+
+/// InsertVRSaveCode - Once the entire function has been instruction selected,
+/// all virtual registers are created and all machine instructions are built,
+/// check to see if we need to save/restore VRSAVE.  If so, do it.
+void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) {
   // Check to see if this function uses vector registers, which means we have to
   // save and restore the VRSAVE register and update it with the regs we use.  
   //
   // In this case, there will be virtual registers of vector type type created
   // by the scheduler.  Detect them now.
-  SSARegMap *RegMap = DAG.getMachineFunction().getSSARegMap();
+  MachineFunction &Fn = MachineFunction::get(&F);
+  SSARegMap *RegMap = Fn.getSSARegMap();
   bool HasVectorVReg = false;
   for (unsigned i = MRegisterInfo::FirstVirtualRegister, 
        e = RegMap->getLastVirtReg()+1; i != e; ++i)
@@ -213,7 +225,8 @@
       HasVectorVReg = true;
       break;
     }
-  
+  if (!HasVectorVReg) return;  // nothing to do.
+      
   // If we have a vector register, we want to emit code into the entry and exit
   // blocks to save and restore the VRSAVE register.  We do this here (instead
   // of marking all vector instructions as clobbering VRSAVE) for two reasons:
@@ -223,41 +236,41 @@
   // 2. This (more significantly) allows us to create a temporary virtual
   //    register to hold the saved VRSAVE value, allowing this temporary to be
   //    register allocated, instead of forcing it to be spilled to the stack.
-  if (HasVectorVReg) {
-    // Create two vregs - one to hold the VRSAVE register that is live-in to the
-    // function and one for the value after having bits or'd into it.
-    unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-    unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-    
-    MachineFunction &MF = DAG.getMachineFunction();
-    MachineBasicBlock &EntryBB = *MF.begin();
-    // Emit the following code into the entry block:
-    // InVRSAVE = MFVRSAVE
-    // UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
-    // MTVRSAVE UpdatedVRSAVE
-    MachineBasicBlock::iterator IP = EntryBB.begin();  // Insert Point
-    BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
-    BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
-    BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
-    
-    // Find all return blocks, outputting a restore in each epilog.
-    const TargetInstrInfo &TII = *DAG.getTarget().getInstrInfo();
-    for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
-      if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
-        IP = BB->end(); --IP;
-        
-        // Skip over all terminator instructions, which are part of the return
-        // sequence.
-        MachineBasicBlock::iterator I2 = IP;
-        while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
-          IP = I2;
-        
-        // Emit: MTVRSAVE InVRSave
-        BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
-      }        
+
+  // Create two vregs - one to hold the VRSAVE register that is live-in to the
+  // function and one for the value after having bits or'd into it.
+  unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+  unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+  
+  MachineBasicBlock &EntryBB = *Fn.begin();
+  // Emit the following code into the entry block:
+  // InVRSAVE = MFVRSAVE
+  // UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE
+  // MTVRSAVE UpdatedVRSAVE
+  MachineBasicBlock::iterator IP = EntryBB.begin();  // Insert Point
+  BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE);
+  BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE);
+  BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE);
+  
+  // Find all return blocks, outputting a restore in each epilog.
+  const TargetInstrInfo &TII = *TM.getInstrInfo();
+  for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+    if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) {
+      IP = BB->end(); --IP;
+      
+      // Skip over all terminator instructions, which are part of the return
+      // sequence.
+      MachineBasicBlock::iterator I2 = IP;
+      while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode()))
+        IP = I2;
+      
+      // Emit: MTVRSAVE InVRSave
+      BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE);
+    }        
   }
 }
 
+
 /// getGlobalBaseReg - Output the instructions required to put the
 /// base address to use for accessing globals into a register.
 ///






More information about the llvm-commits mailing list