diff --git a/llvm/include/llvm/CodeGen/DAGISelHeader.h b/llvm/include/llvm/CodeGen/DAGISelHeader.h index 7fda6f76e1cf..f4514b07fddf 100644 --- a/llvm/include/llvm/CodeGen/DAGISelHeader.h +++ b/llvm/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/llvm/utils/TableGen/DAGISelMatcher.cpp b/llvm/utils/TableGen/DAGISelMatcher.cpp index 3f75558e3dc2..d7519cec292b 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.cpp +++ b/llvm/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/llvm/utils/TableGen/DAGISelMatcher.h b/llvm/utils/TableGen/DAGISelMatcher.h index b40fbf9cd0e1..68737e2796b4 100644 --- a/llvm/utils/TableGen/DAGISelMatcher.h +++ b/llvm/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/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index c0ad16934e79..c414918a33ed 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/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/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp index 07ab4729a6b2..fac5824f4cc5 100644 --- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp +++ b/llvm/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()); } }