[llvm-commits] [llvm] r55498 - in /llvm/trunk: lib/CodeGen/SelectionDAG/DAGCombiner.cpp test/CodeGen/X86/alloca-align-rounding.ll

Evan Cheng evan.cheng at apple.com
Fri Aug 29 15:05:28 PDT 2008


Hi Dan,

This patch broke llvm-gcc bootstrapping. I'm going to back it out for  
now.

Evan

On Aug 28, 2008, at 2:01 PM, Dan Gohman wrote:

> Author: djg
> Date: Thu Aug 28 16:01:56 2008
> New Revision: 55498
>
> URL: http://llvm.org/viewvc/llvm-project?rev=55498&view=rev
> Log:
> Optimize DAGCombiner's worklist processing. Previously it started
> its work by putting all nodes in the worklist, requiring a big
> dynamic allocation. Now, DAGCombiner just iterates over the AllNodes
> list and maintains a worklist for nodes that are newly created or
> need to be revisited. This allows the worklist to stay small in most
> cases, so it can be a SmallVector.
>
> This has the side effect of making DAGCombine not miss a folding
> opportunity in alloca-align-rounding.ll.
>
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>    llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=55498&r1=55497&r2=55498&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Aug 28  
> 16:01:56 2008
> @@ -53,12 +53,31 @@
>     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.
> -    std::vector<SDNode*> WorkList;
> +    SmallVector<SDNode*, 8> WorkList;
> +
> +    // The current position of our iteration through the allnodes  
> list.
> +    SelectionDAG::allnodes_iterator CurNode;
>
>     // 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.
> @@ -86,6 +105,10 @@
>     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,
> @@ -243,10 +266,14 @@
>         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);
>   };
> }
>
> @@ -575,91 +602,89 @@
> //  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).Val);
> +
> +    DAG.DeleteNode(N);
> +    return;
> +  }
> +
> +  SDValue RV = combine(N);
> +
> +  if (RV.Val == 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.Val == N)
> +    return;
> +
> +  assert(N->getOpcode() != ISD::DELETED_NODE &&
> +         RV.Val->getOpcode() != ISD::DELETED_NODE &&
> +         "Node was deleted but visit returned new node!");
> +
> +  DOUT << "\nReplacing.3 "; DEBUG(N->dump(&DAG));
> +  DOUT << "\nWith: "; DEBUG(RV.Val->dump(&DAG));
> +  DOUT << '\n';
> +
> +  if (N->getNumValues() == RV.Val->getNumValues())
> +    DAG.ReplaceAllUsesWith(N, RV.Val);
> +  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.Val);
> +  AddUsersToWorkList(RV.Val);
> +}
> +
> 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());
>
> -  // 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).Val);
> -
> -      DAG.DeleteNode(N);
> -      continue;
> +  // 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);
>     }
> -
> -    SDValue RV = combine(N);
> -
> -    if (RV.Val == 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.Val == N)
> -      continue;
> -
> -    assert(N->getOpcode() != ISD::DELETED_NODE &&
> -           RV.Val->getOpcode() != ISD::DELETED_NODE &&
> -           "Node was deleted but visit returned new node!");
> +  } while (CurNode != DAG.allnodes_end());
>
> -    DOUT << "\nReplacing.3 "; DEBUG(N->dump(&DAG));
> -    DOUT << "\nWith: "; DEBUG(RV.Val->dump(&DAG));
> -    DOUT << '\n';
> -    WorkListRemover DeadNodes(*this);
> -    if (N->getNumValues() == RV.Val->getNumValues())
> -      DAG.ReplaceAllUsesWith(N, RV.Val, &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.Val);
> -    AddUsersToWorkList(RV.Val);
> -
> -    // 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).Val);
> -
> -    // 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());
> }
>
> Modified: llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll?rev=55498&r1=55497&r2=55498&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/alloca-align-rounding.ll Thu Aug 28  
> 16:01:56 2008
> @@ -1,5 +1,5 @@
> ; RUN: llvm-as < %s | llc -march=x86 -mtriple=i686-apple-darwin |  
> grep and | count 1
> -; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=i686-pc-linux |  
> grep and | count 3
> +; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=i686-pc-linux |  
> grep and | count 1
>
> declare void @bar(<2 x i64>* %n)
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list