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

Dan Gohman gohman at apple.com
Thu Mar 27 12:56:20 PDT 2008


Author: djg
Date: Thu Mar 27 14:56:19 2008
New Revision: 48893

URL: http://llvm.org/viewvc/llvm-project?rev=48893&view=rev
Log:
Avoid creating chain dependencies from CopyToReg nodes to load and store
nodes. This doesn't currently have much impact the generated code, but it
does produce simpler-looking SelectionDAGs, and consequently
simpler-looking ScheduleDAGs, because there are fewer spurious
dependencies.

In particular, CopyValueToVirtualRegister now uses the entry node as the
input chain dependency for new CopyToReg nodes instead of calling getRoot
and depending on the most recent memory reference.

Also, rename UnorderedChains to PendingExports and pull it up from being
a local variable in SelectionDAGISel::BuildSelectionDAG to being a
member variable of SelectionDAGISel, so that it doesn't have to be
passed around to all the places that need it.

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

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

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Thu Mar 27 14:56:19 2008
@@ -182,8 +182,7 @@
            std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
                          FunctionLoweringInfo &FuncInfo);
   void CodeGenAndEmitDAG(SelectionDAG &DAG);
-  void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL,
-                      std::vector<SDOperand> &UnorderedChains);
+  void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL);
 
   /// 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=48893&r1=48892&r2=48893&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Mar 27 14:56:19 2008
@@ -339,6 +339,13 @@
   /// analysis.
   std::vector<SDOperand> PendingLoads;
 
+  /// PendingExports - CopyToReg nodes that copy values to virtual registers
+  /// for export to other blocks need to be emitted before any terminator
+  /// instruction, but they have no other ordering requirements. We bunch them
+  /// up and the emit a single tokenfactor for them just before terminator
+  /// instructions.
+  std::vector<SDOperand> PendingExports;
+
   /// Case - A struct to record the Value for a switch case, and the
   /// case's target basic block.
   struct Case {
@@ -440,7 +447,10 @@
       FuncInfo(funcinfo), GCI(gci) {
   }
 
-  /// getRoot - Return the current virtual root of the Selection DAG.
+  /// getRoot - Return the current virtual root of the Selection DAG,
+  /// flushing any PendingLoad items. This must be done before emitting
+  /// a store or any other node that may need to be ordered after any
+  /// prior load instructions.
   ///
   SDOperand getRoot() {
     if (PendingLoads.empty())
@@ -461,7 +471,38 @@
     return Root;
   }
 
-  SDOperand CopyValueToVirtualRegister(Value *V, unsigned Reg);
+  /// getControlRoot - Similar to getRoot, but instead of flushing all the
+  /// PendingLoad items, flush all the PendingExports items. It is necessary
+  /// to do this before emitting a terminator instruction.
+  ///
+  SDOperand getControlRoot() {
+    SDOperand Root = DAG.getRoot();
+
+    if (PendingExports.empty())
+      return Root;
+
+    // Turn all of the CopyToReg chains into one factored node.
+    if (Root.getOpcode() != ISD::EntryToken) {
+      unsigned i = 0, e = PendingExports.size();
+      for (; i != e; ++i) {
+        assert(PendingExports[i].Val->getNumOperands() > 1);
+        if (PendingExports[i].Val->getOperand(0) == Root)
+          break;  // Don't add the root if we already indirectly depend on it.
+      }
+        
+      if (i == e)
+        PendingExports.push_back(Root);
+    }
+
+    Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                       &PendingExports[0],
+                       PendingExports.size());
+    PendingExports.clear();
+    DAG.setRoot(Root);
+    return Root;
+  }
+
+  void CopyValueToVirtualRegister(Value *V, unsigned Reg);
 
   void visit(Instruction &I) { visit(I.getOpcode(), I); }
 
@@ -1032,12 +1073,12 @@
 
 void SelectionDAGLowering::visitRet(ReturnInst &I) {
   if (I.getNumOperands() == 0) {
-    DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getRoot()));
+    DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getControlRoot()));
     return;
   }
   SmallVector<SDOperand, 8> NewValues;
-  NewValues.push_back(getRoot());
-  for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
+  NewValues.push_back(getControlRoot());
+  for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {  
     SDOperand RetOp = getValue(I.getOperand(i));
     MVT::ValueType VT = RetOp.getValueType();
 
@@ -1082,7 +1123,7 @@
   if (FuncInfo.isExportedInst(V)) return;
 
   unsigned Reg = FuncInfo.InitializeRegForValue(V);
-  PendingLoads.push_back(CopyValueToVirtualRegister(V, Reg));
+  CopyValueToVirtualRegister(V, Reg);
 }
 
 bool SelectionDAGLowering::isExportableFromCurrentBlock(Value *V,
@@ -1273,7 +1314,7 @@
   if (I.isUnconditional()) {
     // If this is not a fall-through branch, emit the branch.
     if (Succ0MBB != NextBlock)
-      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
                               DAG.getBasicBlock(Succ0MBB)));
 
     // Update machine-CFG edges.
@@ -1391,7 +1432,7 @@
     SDOperand True = DAG.getConstant(1, Cond.getValueType());
     Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True);
   }
-  SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(), Cond,
+  SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(), Cond,
                                  DAG.getBasicBlock(CB.TrueBB));
   if (CB.FalseBB == NextBlock)
     DAG.setRoot(BrCond);
@@ -1408,7 +1449,7 @@
   // Emit the code for the jump table
   assert(JT.Reg != -1U && "Should lower JT Header first!");
   MVT::ValueType PTy = TLI.getPointerTy();
-  SDOperand Index = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy);
+  SDOperand Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy);
   SDOperand Table = DAG.getJumpTable(JT.JTI, PTy);
   DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1),
                           Table, Index));
@@ -1438,7 +1479,7 @@
     SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
   
   unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
-  SDOperand CopyTo = DAG.getCopyToReg(getRoot(), JumpTableReg, SwitchOp);
+  SDOperand CopyTo = DAG.getCopyToReg(getControlRoot(), JumpTableReg, SwitchOp);
   JT.Reg = JumpTableReg;
 
   // Emit the range check for the jump table, and branch to the default
@@ -1493,7 +1534,7 @@
                                     ShiftOp);
 
   unsigned SwitchReg = FuncInfo.MakeReg(TLI.getPointerTy());
-  SDOperand CopyTo = DAG.getCopyToReg(getRoot(), SwitchReg, SwitchVal);
+  SDOperand CopyTo = DAG.getCopyToReg(getControlRoot(), SwitchReg, SwitchVal);
   B.Reg = SwitchReg;
 
   SDOperand BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
@@ -1524,7 +1565,7 @@
                                             unsigned Reg,
                                             SelectionDAGISel::BitTestCase &B) {
   // Emit bit tests and jumps
-  SDOperand SwitchVal = DAG.getCopyFromReg(getRoot(), Reg, TLI.getPointerTy());
+  SDOperand SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getPointerTy());
   
   SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(),
                                 SwitchVal,
@@ -1533,7 +1574,7 @@
   SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp), AndOp,
                                   DAG.getConstant(0, TLI.getPointerTy()),
                                   ISD::SETNE);
-  SDOperand BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(),
+  SDOperand BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(),
                                 AndCmp, DAG.getBasicBlock(B.TargetBB));
 
   // Set NextBlock to be the MBB immediately after the current one, if any.
@@ -1570,11 +1611,11 @@
   if (!I.use_empty()) {
     DenseMap<const Value*, unsigned>::iterator VMI = FuncInfo.ValueMap.find(&I);
     if (VMI != FuncInfo.ValueMap.end())
-      DAG.setRoot(CopyValueToVirtualRegister(&I, VMI->second));
+      CopyValueToVirtualRegister(&I, VMI->second);
   }
 
   // Drop into normal successor.
-  DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+  DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
                           DAG.getBasicBlock(Return)));
 
   // Update successor info
@@ -2012,7 +2053,7 @@
 }
 
 
-// Clusterify - Transform simple list of Cases into list of CaseRange's
+/// Clusterify - Transform simple list of Cases into list of CaseRange's
 unsigned SelectionDAGLowering::Clusterify(CaseVector& Cases,
                                           const SwitchInst& SI) {
   unsigned numCmps = 0;
@@ -2069,7 +2110,7 @@
 
     // If this is not a fall-through branch, emit the branch.
     if (Default != NextBlock)
-      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
                               DAG.getBasicBlock(Default)));
 
     CurMBB->addSuccessor(Default);
@@ -2864,7 +2905,7 @@
       MMI->setCallsEHReturn(true);
       DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
                               MVT::Other,
-                              getRoot(),
+                              getControlRoot(),
                               getValue(I.getOperand(1)),
                               getValue(I.getOperand(2))));
     } else {
@@ -4597,12 +4638,13 @@
   return true;
 }
 
-SDOperand SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, 
-                                                           unsigned Reg) {
+void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, 
+                                                      unsigned Reg) {
   SDOperand Op = getValue(V);
   assert((Op.getOpcode() != ISD::CopyFromReg ||
           cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) &&
          "Copy from a reg to the same reg!");
+  assert(!TargetRegisterInfo::isPhysicalRegister(Reg) && "Is a physreg");
   
   MVT::ValueType SrcVT = Op.getValueType();
   MVT::ValueType RegisterVT = TLI.getRegisterType(SrcVT);
@@ -4613,13 +4655,13 @@
   // Copy the value by legal parts into sequential virtual registers.
   getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
   for (unsigned i = 0; i != NumRegs; ++i)
-    Chains[i] = DAG.getCopyToReg(getRoot(), Reg + i, Regs[i]);
-  return DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
+    Chains[i] = DAG.getCopyToReg(DAG.getEntryNode(), Reg + i, Regs[i]);
+  SDOperand Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
+  PendingExports.push_back(Ch);
 }
 
 void SelectionDAGISel::
-LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL,
-               std::vector<SDOperand> &UnorderedChains) {
+LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
   // If this is the entry block, emit arguments.
   Function &F = *LLVMBB->getParent();
   FunctionLoweringInfo &FuncInfo = SDL.FuncInfo;
@@ -4636,8 +4678,7 @@
       // whereever we got it to the vreg that other BB's will reference it as.
       DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
       if (VMI != FuncInfo.ValueMap.end()) {
-        SDOperand Copy = SDL.CopyValueToVirtualRegister(AI, VMI->second);
-        UnorderedChains.push_back(Copy);
+        SDL.CopyValueToVirtualRegister(AI, VMI->second);
       }
     }
 
@@ -4706,11 +4747,9 @@
                                          FunctionLoweringInfo &FuncInfo) {
   SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI);
 
-  std::vector<SDOperand> UnorderedChains;
-
   // Lower any arguments needed in this block if this is the entry block.
   if (LLVMBB == &LLVMBB->getParent()->getEntryBlock())
-    LowerArguments(LLVMBB, SDL, UnorderedChains);
+    LowerArguments(LLVMBB, SDL);
 
   BB = FuncInfo.MBBMap[LLVMBB];
   SDL.setCurrentBasicBlock(BB);
@@ -4769,8 +4808,7 @@
     if (!I->use_empty() && !isa<PHINode>(I) && !isa<InvokeInst>(I)) {
       DenseMap<const Value*, unsigned>::iterator VMI =FuncInfo.ValueMap.find(I);
       if (VMI != FuncInfo.ValueMap.end())
-        UnorderedChains.push_back(
-                                SDL.CopyValueToVirtualRegister(I, VMI->second));
+        SDL.CopyValueToVirtualRegister(I, VMI->second);
     }
 
   // Handle PHI nodes in successor blocks.  Emit code into the SelectionDAG to
@@ -4821,8 +4859,7 @@
         unsigned &RegOut = ConstantsOut[C];
         if (RegOut == 0) {
           RegOut = FuncInfo.CreateRegForValue(C);
-          UnorderedChains.push_back(
-                           SDL.CopyValueToVirtualRegister(C, RegOut));
+          SDL.CopyValueToVirtualRegister(C, RegOut);
         }
         Reg = RegOut;
       } else {
@@ -4832,8 +4869,7 @@
                  FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(PHIOp)) &&
                  "Didn't codegen value into a register!??");
           Reg = FuncInfo.CreateRegForValue(PHIOp);
-          UnorderedChains.push_back(
-                           SDL.CopyValueToVirtualRegister(PHIOp, Reg));
+          SDL.CopyValueToVirtualRegister(PHIOp, Reg);
         }
       }
 
@@ -4847,24 +4883,6 @@
   }
   ConstantsOut.clear();
 
-  // Turn all of the unordered chains into one factored node.
-  if (!UnorderedChains.empty()) {
-    SDOperand Root = SDL.getRoot();
-    if (Root.getOpcode() != ISD::EntryToken) {
-      unsigned i = 0, e = UnorderedChains.size();
-      for (; i != e; ++i) {
-        assert(UnorderedChains[i].Val->getNumOperands() > 1);
-        if (UnorderedChains[i].Val->getOperand(0) == Root)
-          break;  // Don't add the root if we already indirectly depend on it.
-      }
-        
-      if (i == e)
-        UnorderedChains.push_back(Root);
-    }
-    DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other,
-                            &UnorderedChains[0], UnorderedChains.size()));
-  }
-
   // Lower the terminator after the copies are emitted.
   SDL.visit(*LLVMBB->getTerminator());
 
@@ -4878,7 +4896,7 @@
   BitTestCases = SDL.BitTestCases;
     
   // Make sure the root of the DAG is up-to-date.
-  DAG.setRoot(SDL.getRoot());
+  DAG.setRoot(SDL.getControlRoot());
 
   // Check whether calls in this block are real tail calls. Fix up CALL nodes
   // with correct tailcall attribute so that the target can rely on the tailcall





More information about the llvm-commits mailing list