[llvm-commits] [llvm] r52383 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAG.h include/llvm/CodeGen/SelectionDAGISel.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Chris Lattner sabre at nondot.org
Mon Jun 16 23:09:18 PDT 2008


Author: lattner
Date: Tue Jun 17 01:09:18 2008
New Revision: 52383

URL: http://llvm.org/viewvc/llvm-project?rev=52383&view=rev
Log:
add a new -enable-value-prop flag for llcbeta, that enables propagation
of value info (sign/zero ext info) from one MBB to another.  This doesn't
handle much right now because of two limitations:

1) only handles zext/sext, not random bit propagation (no assert exists 
   for this)
2) doesn't handle phis.



Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=52383&r1=52382&r2=52383&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Jun 17 01:09:18 2008
@@ -31,6 +31,7 @@
   class MachineModuleInfo;
   class MachineFunction;
   class MachineConstantPoolValue;
+  class FunctionLoweringInfo;
 
 /// SelectionDAG class - This is used to represent a portion of an LLVM function
 /// in a low-level Data Dependence DAG representation suitable for instruction
@@ -46,6 +47,7 @@
 class SelectionDAG {
   TargetLowering &TLI;
   MachineFunction &MF;
+  FunctionLoweringInfo &FLI;
   MachineModuleInfo *MMI;
 
   /// Root - The root of the entire DAG.  EntryNode - The starting token.
@@ -59,8 +61,9 @@
   FoldingSet<SDNode> CSEMap;
 
 public:
-  SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineModuleInfo *mmi)
-  : TLI(tli), MF(mf), MMI(mmi) {
+  SelectionDAG(TargetLowering &tli, MachineFunction &mf, 
+               FunctionLoweringInfo &fli, MachineModuleInfo *mmi)
+  : TLI(tli), MF(mf), FLI(fli), MMI(mmi) {
     EntryNode = Root = getNode(ISD::EntryToken, MVT::Other);
   }
   ~SelectionDAG();
@@ -68,6 +71,7 @@
   MachineFunction &getMachineFunction() const { return MF; }
   const TargetMachine &getTarget() const;
   TargetLowering &getTargetLoweringInfo() const { return TLI; }
+  FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
   MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
 
   /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=52383&r1=52382&r2=52383&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Tue Jun 17 01:09:18 2008
@@ -158,6 +158,7 @@
     MachineBasicBlock *Default;
     BitTestInfo Cases;
   };
+  
 protected:
   /// Pick a safe ordering and emit instructions for each target node in the
   /// graph.
@@ -183,6 +184,8 @@
                          FunctionLoweringInfo &FuncInfo);
   void CodeGenAndEmitDAG(SelectionDAG &DAG);
   void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL);
+  
+  void ComputeLiveOutVRegInfo(SelectionDAG &DAG);
 
   /// SwitchCases - Vector of CaseBlock structures used to communicate
   /// SwitchInst code generation information.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=52383&r1=52382&r2=52383&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jun 17 01:09:18 2008
@@ -48,6 +48,10 @@
 #include <algorithm>
 using namespace llvm;
 
+static cl::opt<bool>
+EnableValueProp("enable-value-prop", cl::Hidden, cl::init(false));
+
+
 #ifndef NDEBUG
 static cl::opt<bool>
 ViewISelDAGs("view-isel-dags", cl::Hidden,
@@ -326,6 +330,16 @@
       assert(R == 0 && "Already initialized this value register!");
       return R = CreateRegForValue(V);
     }
+    
+    struct LiveOutInfo {
+      unsigned NumSignBits;
+      APInt KnownOne, KnownZero;
+      LiveOutInfo() : NumSignBits(0) {}
+    };
+    
+    /// LiveOutRegInfo - Information about live out vregs, indexed by their
+    /// register number offset by 'FirstVirtualRegister'.
+    std::vector<LiveOutInfo> LiveOutRegInfo;
   };
 }
 
@@ -1748,12 +1762,11 @@
                                             unsigned Reg,
                                             SelectionDAGISel::BitTestCase &B) {
   // Emit bit tests and jumps
-  SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getPointerTy());
+  SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, 
+                                           TLI.getPointerTy());
   
-  SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(),
-                                SwitchVal,
-                                DAG.getConstant(B.Mask,
-                                                TLI.getPointerTy()));
+  SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
+                                DAG.getConstant(B.Mask, TLI.getPointerTy()));
   SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
                                   DAG.getConstant(0, TLI.getPointerTy()),
                                   ISD::SETNE);
@@ -3706,7 +3719,7 @@
 /// this value and returns the result as a ValueVT value.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.
 /// If the Flag pointer is NULL, no flag is used.
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG, 
                                         SDOperand &Chain,
                                         SDOperand *Flag) const {
   // Assemble the legal parts into the final values.
@@ -3728,6 +3741,49 @@
         *Flag = P.getValue(2);
       }
       Chain = P.getValue(1);
+      
+      // If the source register was virtual and if we know something about it,
+      // add an assert node.
+      if (TargetRegisterInfo::isVirtualRegister(Regs[Part+i]) &&
+          RegisterVT.isInteger() && !RegisterVT.isVector()) {
+        unsigned SlotNo = Regs[Part+i]-TargetRegisterInfo::FirstVirtualRegister;
+        FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+        if (FLI.LiveOutRegInfo.size() > SlotNo) {
+          FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[SlotNo];
+          
+          unsigned RegSize = RegisterVT.getSizeInBits();
+          unsigned NumSignBits = LOI.NumSignBits;
+          unsigned NumZeroBits = LOI.KnownZero.countLeadingOnes();
+          
+          // FIXME: We capture more information than the dag can represent.  For
+          // now, just use the tightest assertzext/assertsext possible.
+          bool isSExt = true;
+          MVT FromVT(MVT::Other);
+          if (NumSignBits == RegSize)
+            isSExt = true, FromVT = MVT::i1;   // ASSERT SEXT 1
+          else if (NumZeroBits >= RegSize-1)
+            isSExt = false, FromVT = MVT::i1;  // ASSERT ZEXT 1
+          else if (NumSignBits > RegSize-8)
+            isSExt = true, FromVT = MVT::i8;   // ASSERT SEXT 8
+          else if (NumZeroBits >= RegSize-9)
+            isSExt = false, FromVT = MVT::i8;  // ASSERT ZEXT 8
+          else if (NumSignBits > RegSize-16)
+            isSExt = true, FromVT = MVT::i16;   // ASSERT SEXT 16
+          else if (NumZeroBits >= RegSize-17)
+            isSExt = false, FromVT = MVT::i16;  // ASSERT ZEXT 16
+          else if (NumSignBits > RegSize-32)
+            isSExt = true, FromVT = MVT::i32;   // ASSERT SEXT 32
+          else if (NumZeroBits >= RegSize-33)
+            isSExt = false, FromVT = MVT::i32;  // ASSERT ZEXT 32
+          
+          if (FromVT != MVT::Other) {
+            P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
+                            RegisterVT, P, DAG.getValueType(FromVT));
+
+          }
+        }
+      }
+      
       Parts[Part+i] = P;
     }
   
@@ -5218,6 +5274,61 @@
   CheckDAGForTailCallsAndFixThem(DAG, TLI);
 }
 
+void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) {
+  SmallPtrSet<SDNode*, 128> VisitedNodes;
+  SmallVector<SDNode*, 128> Worklist;
+  
+  Worklist.push_back(DAG.getRoot().Val);
+  
+  APInt Mask;
+  APInt KnownZero;
+  APInt KnownOne;
+  
+  while (!Worklist.empty()) {
+    SDNode *N = Worklist.back();
+    Worklist.pop_back();
+    
+    // If we've already seen this node, ignore it.
+    if (!VisitedNodes.insert(N))
+      continue;
+    
+    // Otherwise, add all chain operands to the worklist.
+    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+      if (N->getOperand(i).getValueType() == MVT::Other)
+        Worklist.push_back(N->getOperand(i).Val);
+    
+    // If this is a CopyToReg with a vreg dest, process it.
+    if (N->getOpcode() != ISD::CopyToReg)
+      continue;
+    
+    unsigned DestReg = cast<RegisterSDNode>(N->getOperand(1))->getReg();
+    if (!TargetRegisterInfo::isVirtualRegister(DestReg))
+      continue;
+    
+    // Ignore non-scalar or non-integer values.
+    SDOperand Src = N->getOperand(2);
+    MVT SrcVT = Src.getValueType();
+    if (!SrcVT.isInteger() || SrcVT.isVector())
+      continue;
+    
+    unsigned NumSignBits = DAG.ComputeNumSignBits(Src);
+    Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits());
+    DAG.ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
+    
+    // Only install this information if it tells us something.
+    if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) {
+      DestReg -= TargetRegisterInfo::FirstVirtualRegister;
+      FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo();
+      if (DestReg >= FLI.LiveOutRegInfo.size())
+        FLI.LiveOutRegInfo.resize(DestReg+1);
+      FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[DestReg];
+      LOI.NumSignBits = NumSignBits;
+      LOI.KnownOne = NumSignBits;
+      LOI.KnownZero = NumSignBits;
+    }
+  }
+}
+
 void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) {
   DOUT << "Lowered selection DAG:\n";
   DEBUG(DAG.dump());
@@ -5246,6 +5357,9 @@
   DEBUG(DAG.dump());
 
   if (ViewISelDAGs) DAG.viewGraph();
+  
+  if (EnableValueProp)  // FIXME: Only do this if !fast.
+    ComputeLiveOutVRegInfo(DAG);
 
   // Third, instruction select all of the operations to machine code, adding the
   // code to the MachineBasicBlock.
@@ -5259,7 +5373,8 @@
                                         FunctionLoweringInfo &FuncInfo) {
   std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
   {
-    SelectionDAG DAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG DAG(TLI, MF, FuncInfo, 
+                     getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &DAG;
   
     // First step, lower LLVM code to some DAG.  This DAG may use operations and
@@ -5293,7 +5408,8 @@
   for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) {
     // Lower header first, if it wasn't already lowered
     if (!BitTestCases[i].Emitted) {
-      SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG HSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
       SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5306,7 +5422,8 @@
     }    
 
     for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
-      SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG BSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &BSDAG;
       SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5363,7 +5480,8 @@
   for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
     // Lower header first, if it wasn't already lowered
     if (!JTCases[i].first.Emitted) {
-      SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+      SelectionDAG HSDAG(TLI, MF, FuncInfo, 
+                         getAnalysisToUpdate<MachineModuleInfo>());
       CurDAG = &HSDAG;
       SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI);
       // Set the current basic block to the mbb we wish to insert the code into
@@ -5375,7 +5493,8 @@
       CodeGenAndEmitDAG(HSDAG);
     }
     
-    SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG JSDAG(TLI, MF, FuncInfo, 
+                       getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &JSDAG;
     SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI);
     // Set the current basic block to the mbb we wish to insert the code into
@@ -5423,7 +5542,8 @@
   // If we generated any switch lowering information, build and codegen any
   // additional DAGs necessary.
   for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
-    SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+    SelectionDAG SDAG(TLI, MF, FuncInfo, 
+                      getAnalysisToUpdate<MachineModuleInfo>());
     CurDAG = &SDAG;
     SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI);
     





More information about the llvm-commits mailing list