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

Chris Lattner lattner at cs.uiuc.edu
Thu May 4 18:05:02 PDT 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAGISel.cpp updated: 1.233 -> 1.234
---
Log message:

Sink noop copies into the basic block that uses them.  This reduces the number
of cross-block live ranges, and allows the bb-at-a-time selector to always
coallesce these away, at isel time.

This reduces the load on the coallescer and register allocator.  For example
on a codec on X86, we went from:

   1643 asm-printer           - Number of machine instrs printed
    419 liveintervals         - Number of loads/stores folded into instructions
   1144 liveintervals         - Number of identity moves eliminated after coalescing
   1022 liveintervals         - Number of interval joins performed
    282 liveintervals         - Number of intervals after coalescing
   1304 liveintervals         - Number of original intervals
     86 regalloc              - Number of times we had to backtrack
1.90232 regalloc              - Ratio of intervals processed over total intervals
     40 spiller               - Number of values reused
    182 spiller               - Number of loads added
    121 spiller               - Number of stores added
    132 spiller               - Number of register spills
      6 twoaddressinstruction - Number of instructions commuted to coalesce
    360 twoaddressinstruction - Number of two-address instructions

to:

   1636 asm-printer           - Number of machine instrs printed
    403 liveintervals         - Number of loads/stores folded into instructions
   1155 liveintervals         - Number of identity moves eliminated after coalescing
   1033 liveintervals         - Number of interval joins performed
    279 liveintervals         - Number of intervals after coalescing
   1312 liveintervals         - Number of original intervals
     76 regalloc              - Number of times we had to backtrack
1.88998 regalloc              - Ratio of intervals processed over total intervals
      1 spiller               - Number of copies elided
     41 spiller               - Number of values reused
    191 spiller               - Number of loads added
    114 spiller               - Number of stores added
    128 spiller               - Number of register spills
      4 twoaddressinstruction - Number of instructions commuted to coalesce
    356 twoaddressinstruction - Number of two-address instructions

On this testcase, this change provides a modest reduction in spill code,
regalloc iterations, and total instructions emitted.  It increases the number
of register coallesces.



---
Diffs of the changes:  (+77 -4)

 SelectionDAGISel.cpp |   81 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 77 insertions(+), 4 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.233 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.234
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.233	Tue May  2 22:48:02 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Thu May  4 20:04:50 2006
@@ -2763,6 +2763,49 @@
   return V = Ptr;
 }
 
+/// OptimizeNoopCopyExpression - We have determined that the specified cast
+/// instruction is a noop copy (e.g. it's casting from one pointer type to
+/// another, int->uint, or int->sbyte on PPC.
+static void OptimizeNoopCopyExpression(CastInst *CI) {
+  BasicBlock *DefBB = CI->getParent();
+  
+  /// InsertedCasts - Only insert a cast in each block once.
+  std::map<BasicBlock*, CastInst*> InsertedCasts;
+  
+  for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); 
+       UI != E; ) {
+    Use &TheUse = UI.getUse();
+    Instruction *User = cast<Instruction>(*UI);
+    
+    // Figure out which BB this cast is used in.  For PHI's this is the
+    // appropriate predecessor block.
+    BasicBlock *UserBB = User->getParent();
+    if (PHINode *PN = dyn_cast<PHINode>(User)) {
+      unsigned OpVal = UI.getOperandNo()/2;
+      UserBB = PN->getIncomingBlock(OpVal);
+    }
+    
+    // Preincrement use iterator so we don't invalidate it.
+    ++UI;
+    
+    // If this user is in the same block as the cast, don't change the cast.
+    if (UserBB == DefBB) continue;
+    
+    // If we have already inserted a cast into this block, use it.
+    CastInst *&InsertedCast = InsertedCasts[UserBB];
+
+    if (!InsertedCast) {
+      BasicBlock::iterator InsertPt = UserBB->begin();
+      while (isa<PHINode>(InsertPt)) ++InsertPt;
+      
+      InsertedCast = 
+        new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt);
+    }
+    
+    // Replace a use of the cast with a use of the new casat.
+    TheUse = InsertedCast;
+  }
+}
 
 /// OptimizeGEPExpression - Since we are doing basic-block-at-a-time instruction
 /// selection, we want to be a bit careful about some things.  In particular, if
@@ -2890,8 +2933,10 @@
   // constants, this way the load of the constant into a vreg will not be placed
   // into MBBs that are used some other way.
   //
-  // In this pass we also look for GEP instructions that are used across basic
-  // blocks and rewrites them to improve basic-block-at-a-time selection.
+  // In this pass we also look for GEP and cast instructions that are used
+  // across basic blocks and rewrite them to improve basic-block-at-a-time
+  // selection.
+  //
   // 
   for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
     PHINode *PN;
@@ -2901,9 +2946,37 @@
         if (isa<Constant>(PN->getIncomingValue(i)))
           SplitCriticalEdge(PN->getIncomingBlock(i), BB);
     
-    for (BasicBlock::iterator E = BB->end(); BBI != E; )
-      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(BBI++))
+    for (BasicBlock::iterator E = BB->end(); BBI != E; ) {
+      Instruction *I = BBI++;
+      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
         OptimizeGEPExpression(GEPI, TLI.getTargetData());
+      } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
+        // If this is a noop copy, sink it into user blocks to reduce the number
+        // of virtual registers that must be created and coallesced.
+        MVT::ValueType SrcVT = TLI.getValueType(CI->getOperand(0)->getType());
+        MVT::ValueType DstVT = TLI.getValueType(CI->getType());
+        
+        // This is an fp<->int conversion?
+        if (MVT::isInteger(SrcVT) != MVT::isInteger(DstVT))
+          continue;
+        
+        // If this is an extension, it will be a zero or sign extension, which
+        // isn't a noop.
+        if (SrcVT < DstVT) continue;
+        
+        // If these values will be promoted, find out what they will be promoted
+        // to.  This helps us consider truncates on PPC as noop copies when they
+        // are.
+        if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote)
+          SrcVT = TLI.getTypeToTransformTo(SrcVT);
+        if (TLI.getTypeAction(DstVT) == TargetLowering::Promote)
+          DstVT = TLI.getTypeToTransformTo(DstVT);
+
+        // If, after promotion, these are the same types, this is a noop copy.
+        if (SrcVT == DstVT)
+          OptimizeNoopCopyExpression(CI);
+      }
+    }
   }
   
   FunctionLoweringInfo FuncInfo(TLI, Fn, MF);






More information about the llvm-commits mailing list