[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