[llvm-commits] [llvm] r55549 - /llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Evan Cheng evan.cheng at apple.com
Fri Aug 29 15:21:44 PDT 2008


Author: evancheng
Date: Fri Aug 29 17:21:44 2008
New Revision: 55549

URL: http://llvm.org/viewvc/llvm-project?rev=55549&view=rev
Log:
Back out 55498. It broken Apple style bootstrapping.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Aug 29 17:21:44 2008
@@ -53,31 +53,12 @@
     bool AfterLegalize;
     bool Fast;
 
-    // Create a dummy node (which is not added to allnodes), that adds a reference
-    // to the root node, preventing it from being deleted, and tracking any
-    // changes of the root.
-    HandleSDNode Dummy;
-  
     // Worklist of all of the nodes that need to be simplified.
-    SmallVector<SDNode*, 8> WorkList;
-
-    // The current position of our iteration through the allnodes list.
-    SelectionDAG::allnodes_iterator CurNode;
+    std::vector<SDNode*> WorkList;
 
     // AA - Used for DAG load/store alias analysis.
     AliasAnalysis &AA;
 
-    /// AdvanceCurNode - Update CurNode to point to the next node to process.
-    ///
-    void AdvanceCurNode() {
-      // We start at the end of the list and work towards the front. Setting
-      // CurNode to DAG.allnodes_end() indicates that we're done.
-      if (CurNode == DAG.allnodes_begin())
-        CurNode = DAG.allnodes_end();
-      else
-        --CurNode;
-    }
-
     /// AddUsersToWorkList - When an instruction is simplified, add all users of
     /// the instruction to the work lists because they might get more simplified
     /// now.
@@ -105,10 +86,6 @@
     void removeFromWorkList(SDNode *N) {
       WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), N),
                      WorkList.end());
-      // If the next node we were planning to process is deleted,
-      // skip past it.
-      if (N == CurNode)
-        AdvanceCurNode();
     }
     
     SDValue CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
@@ -148,9 +125,9 @@
     // Visitation implementation - Implement dag node combining for different
     // node types.  The semantics are as follows:
     // Return Value:
-    //   SDValue.getNode() == 0   - No change was made
-    //   SDValue.getNode() == N   - N was replaced, is dead, and is already handled.
-    //   otherwise            - N should be replaced by the returned Operand.
+    //   SDValue.getNode() == 0 - No change was made
+    //   SDValue.getNode() == N - N was replaced, is dead and has been handled.
+    //   otherwise              - N should be replaced by the returned Operand.
     //
     SDValue visitTokenFactor(SDNode *N);
     SDValue visitMERGE_VALUES(SDNode *N);
@@ -266,14 +243,10 @@
         TLI(D.getTargetLoweringInfo()),
         AfterLegalize(false),
         Fast(fast),
-        Dummy(D.getRoot()),
         AA(A) {}
     
     /// Run - runs the dag combiner on all nodes in the work list
     void Run(bool RunningAfterLegalize); 
-
-    /// ProcessNode - runs the dag combiner on a node
-    void ProcessNode(SDNode *N);
   };
 }
 
@@ -602,89 +575,91 @@
 //  Main DAG Combiner implementation
 //===----------------------------------------------------------------------===//
 
-void DAGCombiner::ProcessNode(SDNode *N) {
-  // If N has no uses, it is dead.  Make sure to revisit all N's operands once
-  // N is deleted from the DAG, since they too may now be dead or may have a
-  // reduced number of uses, allowing other xforms.
-  if (N->use_empty() && N != &Dummy) {
-    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
-      AddToWorkList(N->getOperand(i).getNode());
-    
-    DAG.DeleteNode(N);
-    return;
-  }
-    
-  SDValue RV = combine(N);
-  
-  if (RV.getNode() == 0)
-    return;
-  
-  ++NodesCombined;
-  
-  // If we get back the same node we passed in, rather than a new node or
-  // zero, we know that the node must have defined multiple values and
-  // CombineTo was used.  Since CombineTo takes care of the worklist 
-  // mechanics for us, we have no work to do in this case.
-  if (RV.getNode() == N)
-    return;
-  
-  assert(N->getOpcode() != ISD::DELETED_NODE &&
-         RV.getNode()->getOpcode() != ISD::DELETED_NODE &&
-         "Node was deleted but visit returned new node!");
-
-  DOUT << "\nReplacing.3 "; DEBUG(N->dump(&DAG));
-  DOUT << "\nWith: "; DEBUG(RV.getNode()->dump(&DAG));
-  DOUT << '\n';
-
-  if (N->getNumValues() == RV.getNode()->getNumValues())
-    DAG.ReplaceAllUsesWith(N, RV.getNode());
-  else {
-    assert(N->getValueType(0) == RV.getValueType() &&
-           N->getNumValues() == 1 && "Type mismatch");
-    SDValue OpV = RV;
-    DAG.ReplaceAllUsesWith(N, &OpV);
-  }
-
-  // Delete the old node.
-  removeFromWorkList(N);
-  DAG.DeleteNode(N);
-
-  // Push the new node and any users onto the worklist
-  AddToWorkList(RV.getNode());
-  AddUsersToWorkList(RV.getNode());
-}
-
 void DAGCombiner::Run(bool RunningAfterLegalize) {
   // set the instance variable, so that the various visit routines may use it.
   AfterLegalize = RunningAfterLegalize;
 
+  // Add all the dag nodes to the worklist.
+  WorkList.reserve(DAG.allnodes_size());
+  for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
+       E = DAG.allnodes_end(); I != E; ++I)
+    WorkList.push_back(I);
+  
+  // Create a dummy node (which is not added to allnodes), that adds a reference
+  // to the root node, preventing it from being deleted, and tracking any
+  // changes of the root.
+  HandleSDNode Dummy(DAG.getRoot());
+  
   // The root of the dag may dangle to deleted nodes until the dag combiner is
   // done.  Set it to null to avoid confusion.
   DAG.setRoot(SDValue());
   
-  // Process all the original dag nodes. We process starting from the
-  // end of the list and working forward, which is in roughly topological
-  // order. Starting at the end and working forward means we won't
-  // accidentally revisit nodes created during the dagcombine process.
-  CurNode = prior(DAG.allnodes_end());
-  do {
-    SDNode *N = &*CurNode;
-    AdvanceCurNode();
-    ProcessNode(N);
-    // Processing the node may have resulted in nodes being added to the
-    // worklist, because the were newly created or because one of their 
-    // operands changed or some other reason they should be revisited.
-    // While the worklist isn't empty, inspect the node on the end of it
-    // and try and combine it.
-    while (!WorkList.empty()) {
-      SDNode *N = WorkList.back();
-      WorkList.pop_back();
-      if (N == CurNode)
-        AdvanceCurNode();
-      ProcessNode(N);
+  // while the worklist isn't empty, inspect the node on the end of it and
+  // try and combine it.
+  while (!WorkList.empty()) {
+    SDNode *N = WorkList.back();
+    WorkList.pop_back();
+    
+    // If N has no uses, it is dead.  Make sure to revisit all N's operands once
+    // N is deleted from the DAG, since they too may now be dead or may have a
+    // reduced number of uses, allowing other xforms.
+    if (N->use_empty() && N != &Dummy) {
+      for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+        AddToWorkList(N->getOperand(i).getNode());
+      
+      DAG.DeleteNode(N);
+      continue;
     }
-  } while (CurNode != DAG.allnodes_end());
+    
+    SDValue RV = combine(N);
+    
+    if (RV.getNode() == 0)
+      continue;
+    
+    ++NodesCombined;
+    
+    // If we get back the same node we passed in, rather than a new node or
+    // zero, we know that the node must have defined multiple values and
+    // CombineTo was used.  Since CombineTo takes care of the worklist 
+    // mechanics for us, we have no work to do in this case.
+    if (RV.getNode() == N)
+      continue;
+    
+    assert(N->getOpcode() != ISD::DELETED_NODE &&
+           RV.getNode()->getOpcode() != ISD::DELETED_NODE &&
+           "Node was deleted but visit returned new node!");
 
+    DOUT << "\nReplacing.3 "; DEBUG(N->dump(&DAG));
+    DOUT << "\nWith: "; DEBUG(RV.getNode()->dump(&DAG));
+    DOUT << '\n';
+    WorkListRemover DeadNodes(*this);
+    if (N->getNumValues() == RV.getNode()->getNumValues())
+      DAG.ReplaceAllUsesWith(N, RV.getNode(), &DeadNodes);
+    else {
+      assert(N->getValueType(0) == RV.getValueType() &&
+             N->getNumValues() == 1 && "Type mismatch");
+      SDValue OpV = RV;
+      DAG.ReplaceAllUsesWith(N, &OpV, &DeadNodes);
+    }
+      
+    // Push the new node and any users onto the worklist
+    AddToWorkList(RV.getNode());
+    AddUsersToWorkList(RV.getNode());
+    
+    // Add any uses of the old node to the worklist in case this node is the
+    // last one that uses them.  They may become dead after this node is
+    // deleted.
+    for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+      AddToWorkList(N->getOperand(i).getNode());
+      
+    // Nodes can be reintroduced into the worklist.  Make sure we do not
+    // process a node that has been replaced.
+    removeFromWorkList(N);
+    
+    // Finally, since the node is now dead, remove it from the graph.
+    DAG.DeleteNode(N);
+  }
+  
   // If the root changed (e.g. it was a dead load, update the root).
   DAG.setRoot(Dummy.getValue());
 }
@@ -3453,7 +3428,7 @@
     }
   }
   
-  // If the input is a constant, let getNode() fold it.
+  // If the input is a constant, let Val fold it.
   if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
     SDValue Res = DAG.getNode(ISD::BIT_CONVERT, VT, N0);
     if (Res.getNode() != N) return Res;





More information about the llvm-commits mailing list