From 21390d79843050ae8b3226860cadc16ff51d0dcf Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Feb 2010 19:15:55 +0000 Subject: convert the new matcher to check intermediate nodes for a single use and only call IsProfitableToFold/IsLegalToFold on the load being folded, like the old dagiselemitter does. This substantially simplifies the code and improves opportunities for sharing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96368 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/DAGISelHeader.h | 27 ++++++++++++++++++--------- utils/TableGen/DAGISelMatcher.cpp | 11 +++-------- utils/TableGen/DAGISelMatcher.h | 28 +++++++--------------------- utils/TableGen/DAGISelMatcherEmitter.cpp | 7 ++----- utils/TableGen/DAGISelMatcherGen.cpp | 6 ++---- 5 files changed, 32 insertions(+), 47 deletions(-) diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 7fda6f7..f4514b0 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -209,8 +209,7 @@ enum BuiltinOpcodes { OPC_CheckComplexPat, OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8, OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8, - OPC_IsProfitableToFold, - OPC_IsLegalToFold + OPC_CheckFoldableChainNode }; struct MatchScope { @@ -382,19 +381,29 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break; continue; - case OPC_IsProfitableToFold: + case OPC_CheckFoldableChainNode: { assert(!NodeStack.size() == 1 && "No parent node"); + // Verify that all intermediate nodes between the root and this one have + // a single use. + bool HasMultipleUses = false; + for (unsigned i = 1, e = NodeStack.size()-1; i != e; ++i) + if (!NodeStack[i].hasOneUse()) { + HasMultipleUses = true; + break; + } + if (HasMultipleUses) break; + + // Check to see that the target thinks this is profitable to fold and that + // we can fold it without inducing cycles in the graph. if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(), - NodeToMatch)) - break; - continue; - case OPC_IsLegalToFold: - assert(!NodeStack.size() == 1 && "No parent node"); - if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(), + NodeToMatch) || + !IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(), NodeToMatch)) break; + continue; } + } // If the code reached this point, then the match failed pop out to the next // match scope. diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp index 3f75558..d7519ce 100644 --- a/utils/TableGen/DAGISelMatcher.cpp +++ b/utils/TableGen/DAGISelMatcher.cpp @@ -106,13 +106,8 @@ void CheckOrImmMatcherNode::print(raw_ostream &OS, unsigned indent) const { printChild(OS, indent); } -void CheckProfitableToFoldMatcherNode::print(raw_ostream &OS, - unsigned indent) const { - OS.indent(indent) << "CheckProfitableToFold\n"; - printChild(OS, indent); -} - -void CheckLegalToFoldMatcherNode::print(raw_ostream &OS, unsigned indent) const{ - OS.indent(indent) << "CheckLegalToFold\n"; +void CheckFoldableChainNodeMatcherNode::print(raw_ostream &OS, + unsigned indent) const { + OS.indent(indent) << "CheckFoldableChainNode\n"; printChild(OS, indent); } diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index b40fbf9..68737e2 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -50,8 +50,7 @@ public: CheckComplexPat, CheckAndImm, CheckOrImm, - CheckProfitableToFold, - CheckLegalToFold + CheckFoldableChainNode }; const KindTy Kind; @@ -359,33 +358,20 @@ public: virtual void print(raw_ostream &OS, unsigned indent = 0) const; }; -/// CheckProfitableToFoldMatcherNode - This checks to see if the current node is -/// worthwhile to try to fold into a large pattern. -class CheckProfitableToFoldMatcherNode : public MatcherNodeWithChild { +/// CheckFoldableChainNodeMatcherNode - This checks to see if the current node +/// (which defines a chain operand) is safe to fold into a larger pattern. +class CheckFoldableChainNodeMatcherNode : public MatcherNodeWithChild { public: - CheckProfitableToFoldMatcherNode() - : MatcherNodeWithChild(CheckProfitableToFold) {} + CheckFoldableChainNodeMatcherNode() + : MatcherNodeWithChild(CheckFoldableChainNode) {} static inline bool classof(const MatcherNode *N) { - return N->getKind() == CheckProfitableToFold; + return N->getKind() == CheckFoldableChainNode; } virtual void print(raw_ostream &OS, unsigned indent = 0) const; }; -/// CheckLegalToFoldMatcherNode - This checks to see if the current node is -/// legal to try to fold into a large pattern. -class CheckLegalToFoldMatcherNode : public MatcherNodeWithChild { -public: - CheckLegalToFoldMatcherNode() - : MatcherNodeWithChild(CheckLegalToFold) {} - - static inline bool classof(const MatcherNode *N) { - return N->getKind() == CheckLegalToFold; - } - - virtual void print(raw_ostream &OS, unsigned indent = 0) const; -}; } // end namespace llvm #endif diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index c0ad169..c414918 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -183,11 +183,8 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) { OS << "OPC_CheckOrImm" << ClassifyInt(Val) << ", "; return EmitInt(Val, OS)+1; } - case MatcherNode::CheckProfitableToFold: - OS << "OPC_IsProfitableToFold,\n"; - return 1; - case MatcherNode::CheckLegalToFold: - OS << "OPC_IsLegalToFold,\n"; + case MatcherNode::CheckFoldableChainNode: + OS << "OPC_CheckFoldableChainNode,\n"; return 1; } assert(0 && "Unreachable"); diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 07ab472..fac5824 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -212,9 +212,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N, const TreePatternNode *Root = Pattern.getSrcPattern(); if (N != Root && // Not the root of the pattern. N->TreeHasProperty(SDNPHasChain, CGP)) { // Has a chain somewhere in tree. - - AddMatcherNode(new CheckProfitableToFoldMatcherNode()); - + // If this non-root node produces a chain, we may need to emit a validity // check. if (OpNo != 0) { @@ -239,7 +237,7 @@ void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N, } if (NeedCheck) - AddMatcherNode(new CheckLegalToFoldMatcherNode()); + AddMatcherNode(new CheckFoldableChainNodeMatcherNode()); } } -- cgit v1.1