[llvm] r259315 - [SelectionDAG] Eliminate exponential behavior in WalkChainUsers
Tim Shen via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 30 19:59:34 PST 2016
Author: timshen
Date: Sat Jan 30 21:59:34 2016
New Revision: 259315
URL: http://llvm.org/viewvc/llvm-project?rev=259315&view=rev
Log:
[SelectionDAG] Eliminate exponential behavior in WalkChainUsers
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=259315&r1=259314&r2=259315&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Jan 30 21:59:34 2016
@@ -2108,8 +2108,9 @@ enum ChainResult {
/// already selected nodes "below" us.
static ChainResult
WalkChainUsers(const SDNode *ChainedNode,
- SmallVectorImpl<SDNode*> &ChainedNodesInPattern,
- SmallVectorImpl<SDNode*> &InteriorChainedNodes) {
+ SmallVectorImpl<SDNode *> &ChainedNodesInPattern,
+ DenseMap<const SDNode *, ChainResult> &TokenFactorResult,
+ SmallVectorImpl<SDNode *> &InteriorChainedNodes) {
ChainResult Result = CR_Simple;
for (SDNode::use_iterator UI = ChainedNode->use_begin(),
@@ -2190,7 +2191,15 @@ WalkChainUsers(const SDNode *ChainedNode
// as a new TokenFactor.
//
// To distinguish these two cases, do a recursive walk down the uses.
- switch (WalkChainUsers(User, ChainedNodesInPattern, InteriorChainedNodes)) {
+ auto MemoizeResult = TokenFactorResult.find(User);
+ bool Visited = MemoizeResult != TokenFactorResult.end();
+ // Recursively walk chain users only if the result is not memoized.
+ if (!Visited) {
+ auto Res = WalkChainUsers(User, ChainedNodesInPattern, TokenFactorResult,
+ InteriorChainedNodes);
+ MemoizeResult = TokenFactorResult.insert(std::make_pair(User, Res)).first;
+ }
+ switch (MemoizeResult->second) {
case CR_Simple:
// If the uses of the TokenFactor are just already-selected nodes, ignore
// it, it is "below" our pattern.
@@ -2210,8 +2219,10 @@ WalkChainUsers(const SDNode *ChainedNode
// ultimate chain result of the generated code. We will also add its chain
// inputs as inputs to the ultimate TokenFactor we create.
Result = CR_LeadsToInteriorNode;
- ChainedNodesInPattern.push_back(User);
- InteriorChainedNodes.push_back(User);
+ if (!Visited) {
+ ChainedNodesInPattern.push_back(User);
+ InteriorChainedNodes.push_back(User);
+ }
continue;
}
@@ -2227,12 +2238,16 @@ WalkChainUsers(const SDNode *ChainedNode
static SDValue
HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
SelectionDAG *CurDAG) {
+ // Used for memoization. Without it WalkChainUsers could take exponential
+ // time to run.
+ DenseMap<const SDNode *, ChainResult> TokenFactorResult;
// Walk all of the chained nodes we've matched, recursively scanning down the
// users of the chain result. This adds any TokenFactor nodes that are caught
// in between chained nodes to the chained and interior nodes list.
SmallVector<SDNode*, 3> InteriorChainedNodes;
for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
if (WalkChainUsers(ChainNodesMatched[i], ChainNodesMatched,
+ TokenFactorResult,
InteriorChainedNodes) == CR_InducesCycle)
return SDValue(); // Would induce a cycle.
}
More information about the llvm-commits
mailing list