Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -44,7 +44,8 @@ #define DEBUG_TYPE "gisel-emitter" STATISTIC(NumPatternTotal, "Total number of patterns"); -STATISTIC(NumPatternSkipped, "Number of patterns skipped"); +STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG"); +STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped"); STATISTIC(NumPatternEmitted, "Number of patterns emitted"); static cl::opt WarnOnSkippedPatterns( @@ -54,6 +55,7 @@ cl::init(false)); namespace { +class RuleMatcher; class GlobalISelEmitter { public: @@ -78,14 +80,15 @@ /// Analyze pattern \p P, possibly emitting matching code for it to \p OS. /// Otherwise, return a reason why this pattern was skipped for emission. - Optional runOnPattern(const PatternToMatch &P, - raw_ostream &OS); + Optional runOnPattern(std::vector &Rules, + const PatternToMatch &P, raw_ostream &OS); }; } // end anonymous namespace //===- Helper functions ---------------------------------------------------===// +namespace { /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...). static Optional MVTToLLT(MVT::SimpleValueType SVT) { @@ -107,9 +110,11 @@ static bool isTrivialOperatorNode(const TreePatternNode *N) { return !N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn(); } +} // end anonymous namespace //===- Matchers -----------------------------------------------------------===// +namespace { template class PredicateListMatcher { private: typedef std::vector> PredicateVec; @@ -283,8 +288,11 @@ } }; +} // end anonymous namespace + //===- Actions ------------------------------------------------------------===// +namespace { /// An action taken when all Matcher predicates succeeded for a parent rule. /// /// Typical actions include: @@ -350,7 +358,7 @@ return *static_cast(Actions.back().get()); } - void emit(raw_ostream &OS) { + void emit(raw_ostream &OS) const { if (Matchers.empty()) llvm_unreachable("Unexpected empty matcher!"); @@ -380,6 +388,8 @@ } }; +} // end anonymous namespace + //===- GlobalISelEmitter class --------------------------------------------===// void GlobalISelEmitter::gatherNodeEquivs() { @@ -399,7 +409,8 @@ //===- Emitter ------------------------------------------------------------===// Optional -GlobalISelEmitter::runOnPattern(const PatternToMatch &P, raw_ostream &OS) { +GlobalISelEmitter::runOnPattern(std::vector &Rules, + const PatternToMatch &P, raw_ostream &OS) { // Keep track of the matchers and actions to emit. RuleMatcher M; @@ -518,9 +529,9 @@ ++OpIdx; } - // We're done with this pattern! Emit the processed result. - M.emit(OS); - ++NumPatternEmitted; + Rules.push_back(std::move(M)); + ++NumPatternImported; + return None; } @@ -535,18 +546,26 @@ "(MachineInstr &I) const {\n const MachineRegisterInfo &MRI = " "I.getParent()->getParent()->getRegInfo();\n\n"; + std::vector Rules; // Look through the SelectionDAG patterns we found, possibly emitting some. for (const PatternToMatch &Pat : CGP.ptms()) { ++NumPatternTotal; - if (auto SkipReason = runOnPattern(Pat, OS)) { + if (auto SkipReason = runOnPattern(Rules, Pat, OS)) { if (WarnOnSkippedPatterns) { PrintWarning(Pat.getSrcRecord()->getLoc(), "Skipped pattern: " + SkipReason->Reason); } - ++NumPatternSkipped; + ++NumPatternImportsSkipped; + continue; } } + for (const auto &Rule : Rules) { + // We're done with this pattern! Emit the processed result. + Rule.emit(OS); + ++NumPatternEmitted; + } + OS << " return false;\n}\n"; }