diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-08-05 18:10:27 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-08-05 18:10:27 +0000 |
| commit | 82299e70977500209c951404e354510feffb8efa (patch) | |
| tree | 795dcd677081c6fdf8266132b525f352e6b28bc8 /lib/CodeGen | |
| parent | c534395cb22202e66f27abe99dd9c153b4a68b14 (diff) | |
Change FindEarliestCallSeqEnd (used by libcall insertion) to use a set to
avoid revisiting nodes more than once. This eliminates a source of
potentially exponential behavior. For a small function in 191.fma3d
(hexah_stress_divergence_), this speeds up isel from taking > 20mins to
taking 0.07s.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22680 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 147692bb26..e3f8e0911e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -21,6 +21,7 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include <iostream> +#include <set> using namespace llvm; //===----------------------------------------------------------------------===// @@ -2285,8 +2286,10 @@ static void FindLatestCallSeqStart(SDNode *Node, SDNode *&Found) { /// FindEarliestCallSeqEnd - Scan down the dag to find the earliest (lowest /// NodeDepth) node that is an CallSeqEnd operation and occurs more recent /// than Found. -static void FindEarliestCallSeqEnd(SDNode *Node, SDNode *&Found) { - if (Found && Node->getNodeDepth() >= Found->getNodeDepth()) return; +static void FindEarliestCallSeqEnd(SDNode *Node, SDNode *&Found, + std::set<SDNode*> &Visited) { + if ((Found && Node->getNodeDepth() >= Found->getNodeDepth()) || + !Visited.insert(Node).second) return; // If we found an CALLSEQ_END, we already know this node occurs earlier // than the Found node. Just remember this node and return. @@ -2299,10 +2302,10 @@ static void FindEarliestCallSeqEnd(SDNode *Node, SDNode *&Found) { SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); if (UI == E) return; for (--E; UI != E; ++UI) - FindEarliestCallSeqEnd(*UI, Found); + FindEarliestCallSeqEnd(*UI, Found, Visited); // Tail recurse for the last iteration. - FindEarliestCallSeqEnd(*UI, Found); + FindEarliestCallSeqEnd(*UI, Found, Visited); } /// FindCallSeqEnd - Given a chained node that is part of a call sequence, @@ -2372,7 +2375,8 @@ static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain, // Finally, find the first call that this must come before, first we find the // CallSeqEnd that ends the call. OutChain = 0; - FindEarliestCallSeqEnd(OpNode, OutChain); + std::set<SDNode*> Visited; + FindEarliestCallSeqEnd(OpNode, OutChain, Visited); // If we found one, translate from the adj up to the callseq_start. if (OutChain) |
