From 1f818d2e250ec7ffff6037d9fb287afdaa656fd1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 17 Feb 2010 00:31:50 +0000 Subject: [PATCH] make the new isel generator plop out a CheckComplexPattern function for evaluating complex patterns. Some cleanup has to happen before this can be used though. llvm-svn: 96419 --- utils/TableGen/DAGISelEmitter.cpp | 2 +- utils/TableGen/DAGISelMatcher.h | 2 ++ utils/TableGen/DAGISelMatcherEmitter.cpp | 42 ++++++++++++++++++++++-- utils/TableGen/DAGISelMatcherGen.cpp | 12 +++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index a62905e9ec1..cba2fc6f263 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -697,7 +697,7 @@ void PatternCodeEmitter::EmitMatchCode(TreePatternNode *N, TreePatternNode *P, Code += ", CPTmp" + RootName + "_" + utostr(i); if (CP->hasProperty(SDNPHasChain)) { ChainName = "Chain" + ChainSuffix; - Code += ", CPInChain, Chain" + ChainSuffix; + Code += ", CPInChain, " + ChainName; } emitCheck(Code + ")"); } diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index 68737e2796b..b5dabafa524 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -317,6 +317,8 @@ public: CheckComplexPatMatcherNode(const ComplexPattern &pattern) : MatcherNodeWithChild(CheckComplexPat), Pattern(pattern) {} + const ComplexPattern &getPattern() const { return Pattern; } + static inline bool classof(const MatcherNode *N) { return N->getKind() == CheckComplexPat; } diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index c414918a33e..8e004f33558 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -13,6 +13,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/FormattedStream.h" @@ -69,7 +70,9 @@ class MatcherTableEmitter { StringMap NodePredicateMap, PatternPredicateMap; std::vector NodePredicates, PatternPredicates; - + + DenseMap ComplexPatternMap; + std::vector ComplexPatterns; public: MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {} @@ -95,6 +98,15 @@ private: } return Entry-1; } + + unsigned getComplexPat(const ComplexPattern &P) { + unsigned &Entry = ComplexPatternMap[&P]; + if (Entry == 0) { + ComplexPatterns.push_back(&P); + Entry = ComplexPatterns.size(); + } + return Entry-1; + } }; } // end anonymous namespace. @@ -169,7 +181,9 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) { return 2; case MatcherNode::CheckComplexPat: - OS << "OPC_CheckComplexPat, 0/*XXX*/,\n"; + OS << "OPC_CheckComplexPat, " + << getComplexPat(cast(N)->getPattern()) + << ",\n"; return 2; case MatcherNode::CheckAndImm: { @@ -238,6 +252,7 @@ EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) { } void MatcherTableEmitter::EmitPredicateFunctions() { + // Emit pattern predicates. OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n"; OS << " switch (PredNo) {\n"; OS << " default: assert(0 && \"Invalid predicate in table?\");\n"; @@ -246,6 +261,7 @@ void MatcherTableEmitter::EmitPredicateFunctions() { OS << " }\n"; OS << "}\n\n"; + // Emit Node predicates. OS << "bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {\n"; OS << " switch (PredNo) {\n"; OS << " default: assert(0 && \"Invalid predicate in table?\");\n"; @@ -253,6 +269,28 @@ void MatcherTableEmitter::EmitPredicateFunctions() { OS << " case " << i << ": return " << NodePredicates[i] << "(N);\n"; OS << " }\n"; OS << "}\n\n"; + + // Emit CompletePattern matchers. + + OS << "bool CheckComplexPattern(SDNode *Root, SDValue N,\n"; + OS << " unsigned PatternNo, SmallVectorImpl &Result) {\n"; + OS << " switch (PatternNo) {\n"; + OS << " default: assert(0 && \"Invalid pattern # in table?\");\n"; + for (unsigned i = 0, e = ComplexPatterns.size(); i != e; ++i) { + const ComplexPattern &P = *ComplexPatterns[i]; + unsigned NumOps = P.getNumOperands(); + if (P.hasProperty(SDNPHasChain)) + NumOps += 2; // Input and output chains. + OS << " case " << i << ":\n"; + OS << " Result.resize(Result.size()+" << NumOps << ");\n"; + OS << " return " << P.getSelectFunc() << "(Root, N"; + for (unsigned i = 0; i != NumOps; ++i) + OS << ", Result[Result.size()-" << (NumOps-i) << ']'; + OS << ");\n"; + } + OS << " }\n"; + OS << "}\n\n"; + } diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 532d3c16468..c44be1cad02 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -273,19 +273,25 @@ void MatcherGen::EmitMatchCode(const TreePatternNode *N, if (!N->getName().empty()) { unsigned &VarMapEntry = VariableMap[N->getName()]; if (VarMapEntry == 0) { - VarMapEntry = ++NextRecordedOperandNo; + VarMapEntry = NextRecordedOperandNo+1; + + unsigned NumRecorded; // If this is a complex pattern, the match operation for it will // implicitly record all of the outputs of it (which may be more than // one). if (const ComplexPattern *AM = N->getComplexPatternInfo(CGP)) { // Record the right number of operands. - // FIXME: Does this include chain? - VarMapEntry += AM->getNumOperands()-1; + NumRecorded = AM->getNumOperands()-1; + + if (AM->hasProperty(SDNPHasChain)) + NumRecorded += 2; // Input and output chains. } else { // If it is a normal named node, we must emit a 'Record' opcode. AddMatcherNode(new RecordMatcherNode()); + NumRecorded = 1; } + NextRecordedOperandNo += NumRecorded; } else { // If we get here, this is a second reference to a specific name. Since