void MatcherTableEmitter::EmitNodePredicatesFunction( const std::vector<TreePredicateFn> &Preds, StringRef Decl, raw_ostream &OS) { if (Preds.empty()) return; BeginEmitFunction(OS, "bool", Decl, true/*AddOverride*/); OS << "{\n"; OS << " switch (PredNo) {\n"; OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = Preds.size(); i != e; ++i) { // Emit the predicate code corresponding to this pattern. TreePredicateFn PredFn = Preds[i]; assert(!PredFn.isAlwaysTrue() && "No code in this predicate"); OS << " case " << i << ": { \n"; for (auto *SimilarPred : NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()]) OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n'; OS << PredFn.getCodeToRunOnSDNode() << "\n }\n"; } OS << " }\n"; OS << "}\n"; EndEmitFunction(OS); }
void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { // Emit pattern predicates. if (!PatternPredicates.empty()) { OS << "bool CheckPatternPredicate(unsigned PredNo) const override {\n"; OS << " switch (PredNo) {\n"; OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i) OS << " case " << i << ": return " << PatternPredicates[i] << ";\n"; OS << " }\n"; OS << "}\n\n"; } // Emit Node predicates. if (!NodePredicates.empty()) { OS << "bool CheckNodePredicate(SDNode *Node,\n"; OS << " unsigned PredNo) const override {\n"; OS << " switch (PredNo) {\n"; OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) { // Emit the predicate code corresponding to this pattern. TreePredicateFn PredFn = NodePredicates[i]; assert(!PredFn.isAlwaysTrue() && "No code in this predicate"); OS << " case " << i << ": { \n"; for (auto *SimilarPred : NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()]) OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n'; OS << PredFn.getCodeToRunOnSDNode() << "\n }\n"; } OS << " }\n"; OS << "}\n\n"; } // Emit CompletePattern matchers. // FIXME: This should be const. if (!ComplexPatterns.empty()) { OS << "bool CheckComplexPattern(SDNode *Root, SDNode *Parent,\n"; OS << " SDValue N, unsigned PatternNo,\n"; OS << " SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) override {\n"; OS << " unsigned NextRes = Result.size();\n"; OS << " switch (PatternNo) {\n"; OS << " default: llvm_unreachable(\"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; // Get the chained node too. OS << " case " << i << ":\n"; OS << " Result.resize(NextRes+" << NumOps << ");\n"; OS << " return " << P.getSelectFunc(); OS << "("; // If the complex pattern wants the root of the match, pass it in as the // first argument. if (P.hasProperty(SDNPWantRoot)) OS << "Root, "; // If the complex pattern wants the parent of the operand being matched, // pass it in as the next argument. if (P.hasProperty(SDNPWantParent)) OS << "Parent, "; OS << "N"; for (unsigned i = 0; i != NumOps; ++i) OS << ", Result[NextRes+" << i << "].first"; OS << ");\n"; } OS << " }\n"; OS << "}\n\n"; } // Emit SDNodeXForm handlers. // FIXME: This should be const. if (!NodeXForms.empty()) { OS << "SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) override {\n"; OS << " switch (XFormNo) {\n"; OS << " default: llvm_unreachable(\"Invalid xform # in table?\");\n"; // FIXME: The node xform could take SDValue's instead of SDNode*'s. for (unsigned i = 0, e = NodeXForms.size(); i != e; ++i) { const CodeGenDAGPatterns::NodeXForm &Entry = CGP.getSDNodeTransform(NodeXForms[i]); Record *SDNode = Entry.first; const std::string &Code = Entry.second; OS << " case " << i << ": { "; if (!OmitComments) OS << "// " << NodeXForms[i]->getName(); OS << '\n'; std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName(); if (ClassName == "SDNode") OS << " SDNode *N = V.getNode();\n"; else OS << " " << ClassName << " *N = cast<" << ClassName << ">(V.getNode());\n"; OS << Code << "\n }\n"; } OS << " }\n"; OS << "}\n\n"; } }