GICombinerEmitter.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. //===- GlobalCombinerEmitter.cpp - Generate a combiner --------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file Generate a combiner implementation for GlobalISel from a declarative
  10. /// syntax
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "CodeGenTarget.h"
  14. #include "GlobalISel/CodeExpander.h"
  15. #include "GlobalISel/CodeExpansions.h"
  16. #include "GlobalISel/GIMatchDag.h"
  17. #include "GlobalISel/GIMatchDagPredicate.h"
  18. #include "GlobalISel/GIMatchTree.h"
  19. #include "llvm/ADT/SmallSet.h"
  20. #include "llvm/ADT/Statistic.h"
  21. #include "llvm/ADT/StringSet.h"
  22. #include "llvm/Support/CommandLine.h"
  23. #include "llvm/Support/Debug.h"
  24. #include "llvm/Support/ScopedPrinter.h"
  25. #include "llvm/TableGen/Error.h"
  26. #include "llvm/TableGen/StringMatcher.h"
  27. #include "llvm/TableGen/TableGenBackend.h"
  28. #include <cstdint>
  29. using namespace llvm;
  30. #define DEBUG_TYPE "gicombiner-emitter"
  31. // FIXME: Use ALWAYS_ENABLED_STATISTIC once it's available.
  32. unsigned NumPatternTotal = 0;
  33. STATISTIC(NumPatternTotalStatistic, "Total number of patterns");
  34. cl::OptionCategory
  35. GICombinerEmitterCat("Options for -gen-global-isel-combiner");
  36. static cl::list<std::string>
  37. SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
  38. cl::cat(GICombinerEmitterCat), cl::CommaSeparated);
  39. static cl::opt<bool> ShowExpansions(
  40. "gicombiner-show-expansions",
  41. cl::desc("Use C++ comments to indicate occurence of code expansion"),
  42. cl::cat(GICombinerEmitterCat));
  43. static cl::opt<bool> StopAfterParse(
  44. "gicombiner-stop-after-parse",
  45. cl::desc("Stop processing after parsing rules and dump state"),
  46. cl::cat(GICombinerEmitterCat));
  47. static cl::opt<bool> StopAfterBuild(
  48. "gicombiner-stop-after-build",
  49. cl::desc("Stop processing after building the match tree"),
  50. cl::cat(GICombinerEmitterCat));
  51. namespace {
  52. typedef uint64_t RuleID;
  53. // We're going to be referencing the same small strings quite a lot for operand
  54. // names and the like. Make their lifetime management simple with a global
  55. // string table.
  56. StringSet<> StrTab;
  57. StringRef insertStrTab(StringRef S) {
  58. if (S.empty())
  59. return S;
  60. return StrTab.insert(S).first->first();
  61. }
  62. class format_partition_name {
  63. const GIMatchTree &Tree;
  64. unsigned Idx;
  65. public:
  66. format_partition_name(const GIMatchTree &Tree, unsigned Idx)
  67. : Tree(Tree), Idx(Idx) {}
  68. void print(raw_ostream &OS) const {
  69. Tree.getPartitioner()->emitPartitionName(OS, Idx);
  70. }
  71. };
  72. raw_ostream &operator<<(raw_ostream &OS, const format_partition_name &Fmt) {
  73. Fmt.print(OS);
  74. return OS;
  75. }
  76. /// Declares data that is passed from the match stage to the apply stage.
  77. class MatchDataInfo {
  78. /// The symbol used in the tablegen patterns
  79. StringRef PatternSymbol;
  80. /// The data type for the variable
  81. StringRef Type;
  82. /// The name of the variable as declared in the generated matcher.
  83. std::string VariableName;
  84. public:
  85. MatchDataInfo(StringRef PatternSymbol, StringRef Type, StringRef VariableName)
  86. : PatternSymbol(PatternSymbol), Type(Type), VariableName(VariableName) {}
  87. StringRef getPatternSymbol() const { return PatternSymbol; };
  88. StringRef getType() const { return Type; };
  89. StringRef getVariableName() const { return VariableName; };
  90. };
  91. class RootInfo {
  92. StringRef PatternSymbol;
  93. public:
  94. RootInfo(StringRef PatternSymbol) : PatternSymbol(PatternSymbol) {}
  95. StringRef getPatternSymbol() const { return PatternSymbol; }
  96. };
  97. class CombineRule {
  98. public:
  99. using const_matchdata_iterator = std::vector<MatchDataInfo>::const_iterator;
  100. struct VarInfo {
  101. const GIMatchDagInstr *N;
  102. const GIMatchDagOperand *Op;
  103. const DagInit *Matcher;
  104. public:
  105. VarInfo(const GIMatchDagInstr *N, const GIMatchDagOperand *Op,
  106. const DagInit *Matcher)
  107. : N(N), Op(Op), Matcher(Matcher) {}
  108. };
  109. protected:
  110. /// A unique ID for this rule
  111. /// ID's are used for debugging and run-time disabling of rules among other
  112. /// things.
  113. RuleID ID;
  114. /// A unique ID that can be used for anonymous objects belonging to this rule.
  115. /// Used to create unique names in makeNameForAnon*() without making tests
  116. /// overly fragile.
  117. unsigned UID = 0;
  118. /// The record defining this rule.
  119. const Record &TheDef;
  120. /// The roots of a match. These are the leaves of the DAG that are closest to
  121. /// the end of the function. I.e. the nodes that are encountered without
  122. /// following any edges of the DAG described by the pattern as we work our way
  123. /// from the bottom of the function to the top.
  124. std::vector<RootInfo> Roots;
  125. GIMatchDag MatchDag;
  126. /// A block of arbitrary C++ to finish testing the match.
  127. /// FIXME: This is a temporary measure until we have actual pattern matching
  128. const StringInit *MatchingFixupCode = nullptr;
  129. /// The MatchData defined by the match stage and required by the apply stage.
  130. /// This allows the plumbing of arbitrary data from C++ predicates between the
  131. /// stages.
  132. ///
  133. /// For example, suppose you have:
  134. /// %A = <some-constant-expr>
  135. /// %0 = G_ADD %1, %A
  136. /// you could define a GIMatchPredicate that walks %A, constant folds as much
  137. /// as possible and returns an APInt containing the discovered constant. You
  138. /// could then declare:
  139. /// def apint : GIDefMatchData<"APInt">;
  140. /// add it to the rule with:
  141. /// (defs root:$root, apint:$constant)
  142. /// evaluate it in the pattern with a C++ function that takes a
  143. /// MachineOperand& and an APInt& with:
  144. /// (match [{MIR %root = G_ADD %0, %A }],
  145. /// (constantfold operand:$A, apint:$constant))
  146. /// and finally use it in the apply stage with:
  147. /// (apply (create_operand
  148. /// [{ MachineOperand::CreateImm(${constant}.getZExtValue());
  149. /// ]}, apint:$constant),
  150. /// [{MIR %root = FOO %0, %constant }])
  151. std::vector<MatchDataInfo> MatchDataDecls;
  152. void declareMatchData(StringRef PatternSymbol, StringRef Type,
  153. StringRef VarName);
  154. bool parseInstructionMatcher(const CodeGenTarget &Target, StringInit *ArgName,
  155. const Init &Arg,
  156. StringMap<std::vector<VarInfo>> &NamedEdgeDefs,
  157. StringMap<std::vector<VarInfo>> &NamedEdgeUses);
  158. bool parseWipMatchOpcodeMatcher(const CodeGenTarget &Target,
  159. StringInit *ArgName, const Init &Arg);
  160. public:
  161. CombineRule(const CodeGenTarget &Target, GIMatchDagContext &Ctx, RuleID ID,
  162. const Record &R)
  163. : ID(ID), TheDef(R), MatchDag(Ctx) {}
  164. CombineRule(const CombineRule &) = delete;
  165. bool parseDefs();
  166. bool parseMatcher(const CodeGenTarget &Target);
  167. RuleID getID() const { return ID; }
  168. unsigned allocUID() { return UID++; }
  169. StringRef getName() const { return TheDef.getName(); }
  170. const Record &getDef() const { return TheDef; }
  171. const StringInit *getMatchingFixupCode() const { return MatchingFixupCode; }
  172. size_t getNumRoots() const { return Roots.size(); }
  173. GIMatchDag &getMatchDag() { return MatchDag; }
  174. const GIMatchDag &getMatchDag() const { return MatchDag; }
  175. using const_root_iterator = std::vector<RootInfo>::const_iterator;
  176. const_root_iterator roots_begin() const { return Roots.begin(); }
  177. const_root_iterator roots_end() const { return Roots.end(); }
  178. iterator_range<const_root_iterator> roots() const {
  179. return llvm::make_range(Roots.begin(), Roots.end());
  180. }
  181. iterator_range<const_matchdata_iterator> matchdata_decls() const {
  182. return make_range(MatchDataDecls.begin(), MatchDataDecls.end());
  183. }
  184. /// Export expansions for this rule
  185. void declareExpansions(CodeExpansions &Expansions) const {
  186. for (const auto &I : matchdata_decls())
  187. Expansions.declare(I.getPatternSymbol(), I.getVariableName());
  188. }
  189. /// The matcher will begin from the roots and will perform the match by
  190. /// traversing the edges to cover the whole DAG. This function reverses DAG
  191. /// edges such that everything is reachable from a root. This is part of the
  192. /// preparation work for flattening the DAG into a tree.
  193. void reorientToRoots() {
  194. SmallSet<const GIMatchDagInstr *, 5> Roots;
  195. SmallSet<const GIMatchDagInstr *, 5> Visited;
  196. SmallSet<GIMatchDagEdge *, 20> EdgesRemaining;
  197. for (auto &I : MatchDag.roots()) {
  198. Roots.insert(I);
  199. Visited.insert(I);
  200. }
  201. for (auto &I : MatchDag.edges())
  202. EdgesRemaining.insert(I);
  203. bool Progressed = false;
  204. SmallSet<GIMatchDagEdge *, 20> EdgesToRemove;
  205. while (!EdgesRemaining.empty()) {
  206. for (auto *EI : EdgesRemaining) {
  207. if (Visited.count(EI->getFromMI())) {
  208. if (Roots.count(EI->getToMI()))
  209. PrintError(TheDef.getLoc(), "One or more roots are unnecessary");
  210. Visited.insert(EI->getToMI());
  211. EdgesToRemove.insert(EI);
  212. Progressed = true;
  213. }
  214. }
  215. for (GIMatchDagEdge *ToRemove : EdgesToRemove)
  216. EdgesRemaining.erase(ToRemove);
  217. EdgesToRemove.clear();
  218. for (auto EI = EdgesRemaining.begin(), EE = EdgesRemaining.end();
  219. EI != EE; ++EI) {
  220. if (Visited.count((*EI)->getToMI())) {
  221. (*EI)->reverse();
  222. Visited.insert((*EI)->getToMI());
  223. EdgesToRemove.insert(*EI);
  224. Progressed = true;
  225. }
  226. for (GIMatchDagEdge *ToRemove : EdgesToRemove)
  227. EdgesRemaining.erase(ToRemove);
  228. EdgesToRemove.clear();
  229. }
  230. if (!Progressed) {
  231. LLVM_DEBUG(dbgs() << "No progress\n");
  232. return;
  233. }
  234. Progressed = false;
  235. }
  236. }
  237. };
  238. /// A convenience function to check that an Init refers to a specific def. This
  239. /// is primarily useful for testing for defs and similar in DagInit's since
  240. /// DagInit's support any type inside them.
  241. static bool isSpecificDef(const Init &N, StringRef Def) {
  242. if (const DefInit *OpI = dyn_cast<DefInit>(&N))
  243. if (OpI->getDef()->getName() == Def)
  244. return true;
  245. return false;
  246. }
  247. /// A convenience function to check that an Init refers to a def that is a
  248. /// subclass of the given class and coerce it to a def if it is. This is
  249. /// primarily useful for testing for subclasses of GIMatchKind and similar in
  250. /// DagInit's since DagInit's support any type inside them.
  251. static Record *getDefOfSubClass(const Init &N, StringRef Cls) {
  252. if (const DefInit *OpI = dyn_cast<DefInit>(&N))
  253. if (OpI->getDef()->isSubClassOf(Cls))
  254. return OpI->getDef();
  255. return nullptr;
  256. }
  257. /// A convenience function to check that an Init refers to a dag whose operator
  258. /// is a specific def and coerce it to a dag if it is. This is primarily useful
  259. /// for testing for subclasses of GIMatchKind and similar in DagInit's since
  260. /// DagInit's support any type inside them.
  261. static const DagInit *getDagWithSpecificOperator(const Init &N,
  262. StringRef Name) {
  263. if (const DagInit *I = dyn_cast<DagInit>(&N))
  264. if (I->getNumArgs() > 0)
  265. if (const DefInit *OpI = dyn_cast<DefInit>(I->getOperator()))
  266. if (OpI->getDef()->getName() == Name)
  267. return I;
  268. return nullptr;
  269. }
  270. /// A convenience function to check that an Init refers to a dag whose operator
  271. /// is a def that is a subclass of the given class and coerce it to a dag if it
  272. /// is. This is primarily useful for testing for subclasses of GIMatchKind and
  273. /// similar in DagInit's since DagInit's support any type inside them.
  274. static const DagInit *getDagWithOperatorOfSubClass(const Init &N,
  275. StringRef Cls) {
  276. if (const DagInit *I = dyn_cast<DagInit>(&N))
  277. if (I->getNumArgs() > 0)
  278. if (const DefInit *OpI = dyn_cast<DefInit>(I->getOperator()))
  279. if (OpI->getDef()->isSubClassOf(Cls))
  280. return I;
  281. return nullptr;
  282. }
  283. StringRef makeNameForAnonInstr(CombineRule &Rule) {
  284. return insertStrTab(to_string(
  285. format("__anon%" PRIu64 "_%u", Rule.getID(), Rule.allocUID())));
  286. }
  287. StringRef makeDebugName(CombineRule &Rule, StringRef Name) {
  288. return insertStrTab(Name.empty() ? makeNameForAnonInstr(Rule) : StringRef(Name));
  289. }
  290. StringRef makeNameForAnonPredicate(CombineRule &Rule) {
  291. return insertStrTab(to_string(
  292. format("__anonpred%" PRIu64 "_%u", Rule.getID(), Rule.allocUID())));
  293. }
  294. void CombineRule::declareMatchData(StringRef PatternSymbol, StringRef Type,
  295. StringRef VarName) {
  296. MatchDataDecls.emplace_back(PatternSymbol, Type, VarName);
  297. }
  298. bool CombineRule::parseDefs() {
  299. DagInit *Defs = TheDef.getValueAsDag("Defs");
  300. if (Defs->getOperatorAsDef(TheDef.getLoc())->getName() != "defs") {
  301. PrintError(TheDef.getLoc(), "Expected defs operator");
  302. return false;
  303. }
  304. for (unsigned I = 0, E = Defs->getNumArgs(); I < E; ++I) {
  305. // Roots should be collected into Roots
  306. if (isSpecificDef(*Defs->getArg(I), "root")) {
  307. Roots.emplace_back(Defs->getArgNameStr(I));
  308. continue;
  309. }
  310. // Subclasses of GIDefMatchData should declare that this rule needs to pass
  311. // data from the match stage to the apply stage, and ensure that the
  312. // generated matcher has a suitable variable for it to do so.
  313. if (Record *MatchDataRec =
  314. getDefOfSubClass(*Defs->getArg(I), "GIDefMatchData")) {
  315. declareMatchData(Defs->getArgNameStr(I),
  316. MatchDataRec->getValueAsString("Type"),
  317. llvm::to_string(llvm::format("MatchData%" PRIu64, ID)));
  318. continue;
  319. }
  320. // Otherwise emit an appropriate error message.
  321. if (getDefOfSubClass(*Defs->getArg(I), "GIDefKind"))
  322. PrintError(TheDef.getLoc(),
  323. "This GIDefKind not implemented in tablegen");
  324. else if (getDefOfSubClass(*Defs->getArg(I), "GIDefKindWithArgs"))
  325. PrintError(TheDef.getLoc(),
  326. "This GIDefKindWithArgs not implemented in tablegen");
  327. else
  328. PrintError(TheDef.getLoc(),
  329. "Expected a subclass of GIDefKind or a sub-dag whose "
  330. "operator is of type GIDefKindWithArgs");
  331. return false;
  332. }
  333. if (Roots.empty()) {
  334. PrintError(TheDef.getLoc(), "Combine rules must have at least one root");
  335. return false;
  336. }
  337. return true;
  338. }
  339. // Parse an (Instruction $a:Arg1, $b:Arg2, ...) matcher. Edges are formed
  340. // between matching operand names between different matchers.
  341. bool CombineRule::parseInstructionMatcher(
  342. const CodeGenTarget &Target, StringInit *ArgName, const Init &Arg,
  343. StringMap<std::vector<VarInfo>> &NamedEdgeDefs,
  344. StringMap<std::vector<VarInfo>> &NamedEdgeUses) {
  345. if (const DagInit *Matcher =
  346. getDagWithOperatorOfSubClass(Arg, "Instruction")) {
  347. auto &Instr =
  348. Target.getInstruction(Matcher->getOperatorAsDef(TheDef.getLoc()));
  349. StringRef Name = ArgName ? ArgName->getValue() : "";
  350. GIMatchDagInstr *N =
  351. MatchDag.addInstrNode(makeDebugName(*this, Name), insertStrTab(Name),
  352. MatchDag.getContext().makeOperandList(Instr));
  353. N->setOpcodeAnnotation(&Instr);
  354. const auto &P = MatchDag.addPredicateNode<GIMatchDagOpcodePredicate>(
  355. makeNameForAnonPredicate(*this), Instr);
  356. MatchDag.addPredicateDependency(N, nullptr, P, &P->getOperandInfo()["mi"]);
  357. unsigned OpIdx = 0;
  358. for (const auto &NameInit : Matcher->getArgNames()) {
  359. StringRef Name = insertStrTab(NameInit->getAsUnquotedString());
  360. if (Name.empty())
  361. continue;
  362. N->assignNameToOperand(OpIdx, Name);
  363. // Record the endpoints of any named edges. We'll add the cartesian
  364. // product of edges later.
  365. const auto &InstrOperand = N->getOperandInfo()[OpIdx];
  366. if (InstrOperand.isDef()) {
  367. NamedEdgeDefs.try_emplace(Name);
  368. NamedEdgeDefs[Name].emplace_back(N, &InstrOperand, Matcher);
  369. } else {
  370. NamedEdgeUses.try_emplace(Name);
  371. NamedEdgeUses[Name].emplace_back(N, &InstrOperand, Matcher);
  372. }
  373. if (InstrOperand.isDef()) {
  374. if (any_of(Roots, [&](const RootInfo &X) {
  375. return X.getPatternSymbol() == Name;
  376. })) {
  377. N->setMatchRoot();
  378. }
  379. }
  380. OpIdx++;
  381. }
  382. return true;
  383. }
  384. return false;
  385. }
  386. // Parse the wip_match_opcode placeholder that's temporarily present in lieu of
  387. // implementing macros or choices between two matchers.
  388. bool CombineRule::parseWipMatchOpcodeMatcher(const CodeGenTarget &Target,
  389. StringInit *ArgName,
  390. const Init &Arg) {
  391. if (const DagInit *Matcher =
  392. getDagWithSpecificOperator(Arg, "wip_match_opcode")) {
  393. StringRef Name = ArgName ? ArgName->getValue() : "";
  394. GIMatchDagInstr *N =
  395. MatchDag.addInstrNode(makeDebugName(*this, Name), insertStrTab(Name),
  396. MatchDag.getContext().makeEmptyOperandList());
  397. if (any_of(Roots, [&](const RootInfo &X) {
  398. return ArgName && X.getPatternSymbol() == ArgName->getValue();
  399. })) {
  400. N->setMatchRoot();
  401. }
  402. const auto &P = MatchDag.addPredicateNode<GIMatchDagOneOfOpcodesPredicate>(
  403. makeNameForAnonPredicate(*this));
  404. MatchDag.addPredicateDependency(N, nullptr, P, &P->getOperandInfo()["mi"]);
  405. // Each argument is an opcode that will pass this predicate. Add them all to
  406. // the predicate implementation
  407. for (const auto &Arg : Matcher->getArgs()) {
  408. Record *OpcodeDef = getDefOfSubClass(*Arg, "Instruction");
  409. if (OpcodeDef) {
  410. P->addOpcode(&Target.getInstruction(OpcodeDef));
  411. continue;
  412. }
  413. PrintError(TheDef.getLoc(),
  414. "Arguments to wip_match_opcode must be instructions");
  415. return false;
  416. }
  417. return true;
  418. }
  419. return false;
  420. }
  421. bool CombineRule::parseMatcher(const CodeGenTarget &Target) {
  422. StringMap<std::vector<VarInfo>> NamedEdgeDefs;
  423. StringMap<std::vector<VarInfo>> NamedEdgeUses;
  424. DagInit *Matchers = TheDef.getValueAsDag("Match");
  425. if (Matchers->getOperatorAsDef(TheDef.getLoc())->getName() != "match") {
  426. PrintError(TheDef.getLoc(), "Expected match operator");
  427. return false;
  428. }
  429. if (Matchers->getNumArgs() == 0) {
  430. PrintError(TheDef.getLoc(), "Matcher is empty");
  431. return false;
  432. }
  433. // The match section consists of a list of matchers and predicates. Parse each
  434. // one and add the equivalent GIMatchDag nodes, predicates, and edges.
  435. for (unsigned I = 0; I < Matchers->getNumArgs(); ++I) {
  436. if (parseInstructionMatcher(Target, Matchers->getArgName(I),
  437. *Matchers->getArg(I), NamedEdgeDefs,
  438. NamedEdgeUses))
  439. continue;
  440. if (parseWipMatchOpcodeMatcher(Target, Matchers->getArgName(I),
  441. *Matchers->getArg(I)))
  442. continue;
  443. // Parse arbitrary C++ code we have in lieu of supporting MIR matching
  444. if (const StringInit *StringI = dyn_cast<StringInit>(Matchers->getArg(I))) {
  445. assert(!MatchingFixupCode &&
  446. "Only one block of arbitrary code is currently permitted");
  447. MatchingFixupCode = StringI;
  448. MatchDag.setHasPostMatchPredicate(true);
  449. continue;
  450. }
  451. PrintError(TheDef.getLoc(),
  452. "Expected a subclass of GIMatchKind or a sub-dag whose "
  453. "operator is either of a GIMatchKindWithArgs or Instruction");
  454. PrintNote("Pattern was `" + Matchers->getArg(I)->getAsString() + "'");
  455. return false;
  456. }
  457. // Add the cartesian product of use -> def edges.
  458. bool FailedToAddEdges = false;
  459. for (const auto &NameAndDefs : NamedEdgeDefs) {
  460. if (NameAndDefs.getValue().size() > 1) {
  461. PrintError(TheDef.getLoc(),
  462. "Two different MachineInstrs cannot def the same vreg");
  463. for (const auto &NameAndDefOp : NameAndDefs.getValue())
  464. PrintNote("in " + to_string(*NameAndDefOp.N) + " created from " +
  465. to_string(*NameAndDefOp.Matcher) + "");
  466. FailedToAddEdges = true;
  467. }
  468. const auto &Uses = NamedEdgeUses[NameAndDefs.getKey()];
  469. for (const VarInfo &DefVar : NameAndDefs.getValue()) {
  470. for (const VarInfo &UseVar : Uses) {
  471. MatchDag.addEdge(insertStrTab(NameAndDefs.getKey()), UseVar.N, UseVar.Op,
  472. DefVar.N, DefVar.Op);
  473. }
  474. }
  475. }
  476. if (FailedToAddEdges)
  477. return false;
  478. // If a variable is referenced in multiple use contexts then we need a
  479. // predicate to confirm they are the same operand. We can elide this if it's
  480. // also referenced in a def context and we're traversing the def-use chain
  481. // from the def to the uses but we can't know which direction we're going
  482. // until after reorientToRoots().
  483. for (const auto &NameAndUses : NamedEdgeUses) {
  484. const auto &Uses = NameAndUses.getValue();
  485. if (Uses.size() > 1) {
  486. const auto &LeadingVar = Uses.front();
  487. for (const auto &Var : ArrayRef<VarInfo>(Uses).drop_front()) {
  488. // Add a predicate for each pair until we've covered the whole
  489. // equivalence set. We could test the whole set in a single predicate
  490. // but that means we can't test any equivalence until all the MO's are
  491. // available which can lead to wasted work matching the DAG when this
  492. // predicate can already be seen to have failed.
  493. //
  494. // We have a similar problem due to the need to wait for a particular MO
  495. // before being able to test any of them. However, that is mitigated by
  496. // the order in which we build the DAG. We build from the roots outwards
  497. // so by using the first recorded use in all the predicates, we are
  498. // making the dependency on one of the earliest visited references in
  499. // the DAG. It's not guaranteed once the generated matcher is optimized
  500. // (because the factoring the common portions of rules might change the
  501. // visit order) but this should mean that these predicates depend on the
  502. // first MO to become available.
  503. const auto &P = MatchDag.addPredicateNode<GIMatchDagSameMOPredicate>(
  504. makeNameForAnonPredicate(*this));
  505. MatchDag.addPredicateDependency(LeadingVar.N, LeadingVar.Op, P,
  506. &P->getOperandInfo()["mi0"]);
  507. MatchDag.addPredicateDependency(Var.N, Var.Op, P,
  508. &P->getOperandInfo()["mi1"]);
  509. }
  510. }
  511. }
  512. return true;
  513. }
  514. class GICombinerEmitter {
  515. RecordKeeper &Records;
  516. StringRef Name;
  517. const CodeGenTarget &Target;
  518. Record *Combiner;
  519. std::vector<std::unique_ptr<CombineRule>> Rules;
  520. GIMatchDagContext MatchDagCtx;
  521. std::unique_ptr<CombineRule> makeCombineRule(const Record &R);
  522. void gatherRules(std::vector<std::unique_ptr<CombineRule>> &ActiveRules,
  523. const std::vector<Record *> &&RulesAndGroups);
  524. public:
  525. explicit GICombinerEmitter(RecordKeeper &RK, const CodeGenTarget &Target,
  526. StringRef Name, Record *Combiner);
  527. ~GICombinerEmitter() {}
  528. StringRef getClassName() const {
  529. return Combiner->getValueAsString("Classname");
  530. }
  531. void run(raw_ostream &OS);
  532. /// Emit the name matcher (guarded by #ifndef NDEBUG) used to disable rules in
  533. /// response to the generated cl::opt.
  534. void emitNameMatcher(raw_ostream &OS) const;
  535. void generateCodeForTree(raw_ostream &OS, const GIMatchTree &Tree,
  536. StringRef Indent) const;
  537. };
  538. GICombinerEmitter::GICombinerEmitter(RecordKeeper &RK,
  539. const CodeGenTarget &Target,
  540. StringRef Name, Record *Combiner)
  541. : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {}
  542. void GICombinerEmitter::emitNameMatcher(raw_ostream &OS) const {
  543. std::vector<std::pair<std::string, std::string>> Cases;
  544. Cases.reserve(Rules.size());
  545. for (const CombineRule &EnumeratedRule : make_pointee_range(Rules)) {
  546. std::string Code;
  547. raw_string_ostream SS(Code);
  548. SS << "return " << EnumeratedRule.getID() << ";\n";
  549. Cases.push_back(
  550. std::make_pair(std::string(EnumeratedRule.getName()), Code));
  551. }
  552. OS << "static Optional<uint64_t> getRuleIdxForIdentifier(StringRef "
  553. "RuleIdentifier) {\n"
  554. << " uint64_t I;\n"
  555. << " // getAtInteger(...) returns false on success\n"
  556. << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
  557. << " if (Parsed)\n"
  558. << " return I;\n\n"
  559. << "#ifndef NDEBUG\n";
  560. StringMatcher Matcher("RuleIdentifier", Cases, OS);
  561. Matcher.Emit();
  562. OS << "#endif // ifndef NDEBUG\n\n"
  563. << " return None;\n"
  564. << "}\n";
  565. }
  566. std::unique_ptr<CombineRule>
  567. GICombinerEmitter::makeCombineRule(const Record &TheDef) {
  568. std::unique_ptr<CombineRule> Rule =
  569. std::make_unique<CombineRule>(Target, MatchDagCtx, NumPatternTotal, TheDef);
  570. if (!Rule->parseDefs())
  571. return nullptr;
  572. if (!Rule->parseMatcher(Target))
  573. return nullptr;
  574. Rule->reorientToRoots();
  575. LLVM_DEBUG({
  576. dbgs() << "Parsed rule defs/match for '" << Rule->getName() << "'\n";
  577. Rule->getMatchDag().dump();
  578. Rule->getMatchDag().writeDOTGraph(dbgs(), Rule->getName());
  579. });
  580. if (StopAfterParse)
  581. return Rule;
  582. // For now, don't support traversing from def to use. We'll come back to
  583. // this later once we have the algorithm changes to support it.
  584. bool EmittedDefToUseError = false;
  585. for (const auto &E : Rule->getMatchDag().edges()) {
  586. if (E->isDefToUse()) {
  587. if (!EmittedDefToUseError) {
  588. PrintError(
  589. TheDef.getLoc(),
  590. "Generated state machine cannot lookup uses from a def (yet)");
  591. EmittedDefToUseError = true;
  592. }
  593. PrintNote("Node " + to_string(*E->getFromMI()));
  594. PrintNote("Node " + to_string(*E->getToMI()));
  595. PrintNote("Edge " + to_string(*E));
  596. }
  597. }
  598. if (EmittedDefToUseError)
  599. return nullptr;
  600. // For now, don't support multi-root rules. We'll come back to this later
  601. // once we have the algorithm changes to support it.
  602. if (Rule->getNumRoots() > 1) {
  603. PrintError(TheDef.getLoc(), "Multi-root matches are not supported (yet)");
  604. return nullptr;
  605. }
  606. return Rule;
  607. }
  608. /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
  609. void GICombinerEmitter::gatherRules(
  610. std::vector<std::unique_ptr<CombineRule>> &ActiveRules,
  611. const std::vector<Record *> &&RulesAndGroups) {
  612. for (Record *R : RulesAndGroups) {
  613. if (R->isValueUnset("Rules")) {
  614. std::unique_ptr<CombineRule> Rule = makeCombineRule(*R);
  615. if (Rule == nullptr) {
  616. PrintError(R->getLoc(), "Failed to parse rule");
  617. continue;
  618. }
  619. ActiveRules.emplace_back(std::move(Rule));
  620. ++NumPatternTotal;
  621. } else
  622. gatherRules(ActiveRules, R->getValueAsListOfDefs("Rules"));
  623. }
  624. }
  625. void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
  626. const GIMatchTree &Tree,
  627. StringRef Indent) const {
  628. if (Tree.getPartitioner() != nullptr) {
  629. Tree.getPartitioner()->generatePartitionSelectorCode(OS, Indent);
  630. for (const auto &EnumChildren : enumerate(Tree.children())) {
  631. OS << Indent << "if (Partition == " << EnumChildren.index() << " /* "
  632. << format_partition_name(Tree, EnumChildren.index()) << " */) {\n";
  633. generateCodeForTree(OS, EnumChildren.value(), (Indent + " ").str());
  634. OS << Indent << "}\n";
  635. }
  636. return;
  637. }
  638. bool AnyFullyTested = false;
  639. for (const auto &Leaf : Tree.possible_leaves()) {
  640. OS << Indent << "// Leaf name: " << Leaf.getName() << "\n";
  641. const CombineRule *Rule = Leaf.getTargetData<CombineRule>();
  642. const Record &RuleDef = Rule->getDef();
  643. OS << Indent << "// Rule: " << RuleDef.getName() << "\n"
  644. << Indent << "if (!RuleConfig->isRuleDisabled(" << Rule->getID()
  645. << ")) {\n";
  646. CodeExpansions Expansions;
  647. for (const auto &VarBinding : Leaf.var_bindings()) {
  648. if (VarBinding.isInstr())
  649. Expansions.declare(VarBinding.getName(),
  650. "MIs[" + to_string(VarBinding.getInstrID()) + "]");
  651. else
  652. Expansions.declare(VarBinding.getName(),
  653. "MIs[" + to_string(VarBinding.getInstrID()) +
  654. "]->getOperand(" +
  655. to_string(VarBinding.getOpIdx()) + ")");
  656. }
  657. Rule->declareExpansions(Expansions);
  658. DagInit *Applyer = RuleDef.getValueAsDag("Apply");
  659. if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() !=
  660. "apply") {
  661. PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG");
  662. return;
  663. }
  664. OS << Indent << " if (1\n";
  665. // Attempt to emit code for any untested predicates left over. Note that
  666. // isFullyTested() will remain false even if we succeed here and therefore
  667. // combine rule elision will not be performed. This is because we do not
  668. // know if there's any connection between the predicates for each leaf and
  669. // therefore can't tell if one makes another unreachable. Ideally, the
  670. // partitioner(s) would be sufficiently complete to prevent us from having
  671. // untested predicates left over.
  672. for (const GIMatchDagPredicate *Predicate : Leaf.untested_predicates()) {
  673. if (Predicate->generateCheckCode(OS, (Indent + " ").str(),
  674. Expansions))
  675. continue;
  676. PrintError(RuleDef.getLoc(),
  677. "Unable to test predicate used in rule");
  678. PrintNote(SMLoc(),
  679. "This indicates an incomplete implementation in tablegen");
  680. Predicate->print(errs());
  681. errs() << "\n";
  682. OS << Indent
  683. << "llvm_unreachable(\"TableGen did not emit complete code for this "
  684. "path\");\n";
  685. break;
  686. }
  687. if (Rule->getMatchingFixupCode() &&
  688. !Rule->getMatchingFixupCode()->getValue().empty()) {
  689. // FIXME: Single-use lambda's like this are a serious compile-time
  690. // performance and memory issue. It's convenient for this early stage to
  691. // defer some work to successive patches but we need to eliminate this
  692. // before the ruleset grows to small-moderate size. Last time, it became
  693. // a big problem for low-mem systems around the 500 rule mark but by the
  694. // time we grow that large we should have merged the ISel match table
  695. // mechanism with the Combiner.
  696. OS << Indent << " && [&]() {\n"
  697. << Indent << " "
  698. << CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions,
  699. RuleDef.getLoc(), ShowExpansions)
  700. << "\n"
  701. << Indent << " return true;\n"
  702. << Indent << " }()";
  703. }
  704. OS << ") {\n" << Indent << " ";
  705. if (const StringInit *Code = dyn_cast<StringInit>(Applyer->getArg(0))) {
  706. OS << CodeExpander(Code->getAsUnquotedString(), Expansions,
  707. RuleDef.getLoc(), ShowExpansions)
  708. << "\n"
  709. << Indent << " return true;\n"
  710. << Indent << " }\n";
  711. } else {
  712. PrintError(RuleDef.getLoc(), "Expected apply code block");
  713. return;
  714. }
  715. OS << Indent << "}\n";
  716. assert(Leaf.isFullyTraversed());
  717. // If we didn't have any predicates left over and we're not using the
  718. // trap-door we have to support arbitrary C++ code while we're migrating to
  719. // the declarative style then we know that subsequent leaves are
  720. // unreachable.
  721. if (Leaf.isFullyTested() &&
  722. (!Rule->getMatchingFixupCode() ||
  723. Rule->getMatchingFixupCode()->getValue().empty())) {
  724. AnyFullyTested = true;
  725. OS << Indent
  726. << "llvm_unreachable(\"Combine rule elision was incorrect\");\n"
  727. << Indent << "return false;\n";
  728. }
  729. }
  730. if (!AnyFullyTested)
  731. OS << Indent << "return false;\n";
  732. }
  733. static void emitAdditionalHelperMethodArguments(raw_ostream &OS,
  734. Record *Combiner) {
  735. for (Record *Arg : Combiner->getValueAsListOfDefs("AdditionalArguments"))
  736. OS << ",\n " << Arg->getValueAsString("Type")
  737. << Arg->getValueAsString("Name");
  738. }
  739. void GICombinerEmitter::run(raw_ostream &OS) {
  740. Records.startTimer("Gather rules");
  741. gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
  742. if (StopAfterParse) {
  743. MatchDagCtx.print(errs());
  744. PrintNote(Combiner->getLoc(),
  745. "Terminating due to -gicombiner-stop-after-parse");
  746. return;
  747. }
  748. if (ErrorsPrinted)
  749. PrintFatalError(Combiner->getLoc(), "Failed to parse one or more rules");
  750. LLVM_DEBUG(dbgs() << "Optimizing tree for " << Rules.size() << " rules\n");
  751. std::unique_ptr<GIMatchTree> Tree;
  752. Records.startTimer("Optimize combiner");
  753. {
  754. GIMatchTreeBuilder TreeBuilder(0);
  755. for (const auto &Rule : Rules) {
  756. bool HadARoot = false;
  757. for (const auto &Root : enumerate(Rule->getMatchDag().roots())) {
  758. TreeBuilder.addLeaf(Rule->getName(), Root.index(), Rule->getMatchDag(),
  759. Rule.get());
  760. HadARoot = true;
  761. }
  762. if (!HadARoot)
  763. PrintFatalError(Rule->getDef().getLoc(), "All rules must have a root");
  764. }
  765. Tree = TreeBuilder.run();
  766. }
  767. if (StopAfterBuild) {
  768. Tree->writeDOTGraph(outs());
  769. PrintNote(Combiner->getLoc(),
  770. "Terminating due to -gicombiner-stop-after-build");
  771. return;
  772. }
  773. Records.startTimer("Emit combiner");
  774. OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n"
  775. << "#include \"llvm/ADT/SparseBitVector.h\"\n"
  776. << "namespace llvm {\n"
  777. << "extern cl::OptionCategory GICombinerOptionCategory;\n"
  778. << "} // end namespace llvm\n"
  779. << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n\n";
  780. OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n"
  781. << "class " << getClassName() << "RuleConfig {\n"
  782. << " SparseBitVector<> DisabledRules;\n"
  783. << "\n"
  784. << "public:\n"
  785. << " bool parseCommandLineOption();\n"
  786. << " bool isRuleDisabled(unsigned ID) const;\n"
  787. << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
  788. << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
  789. << "};\n"
  790. << "\n"
  791. << "class " << getClassName();
  792. StringRef StateClass = Combiner->getValueAsString("StateClass");
  793. if (!StateClass.empty())
  794. OS << " : public " << StateClass;
  795. OS << " {\n"
  796. << " const " << getClassName() << "RuleConfig *RuleConfig;\n"
  797. << "\n"
  798. << "public:\n"
  799. << " template <typename... Args>" << getClassName() << "(const "
  800. << getClassName() << "RuleConfig &RuleConfig, Args &&... args) : ";
  801. if (!StateClass.empty())
  802. OS << StateClass << "(std::forward<Args>(args)...), ";
  803. OS << "RuleConfig(&RuleConfig) {}\n"
  804. << "\n"
  805. << " bool tryCombineAll(\n"
  806. << " GISelChangeObserver &Observer,\n"
  807. << " MachineInstr &MI,\n"
  808. << " MachineIRBuilder &B";
  809. emitAdditionalHelperMethodArguments(OS, Combiner);
  810. OS << ") const;\n";
  811. OS << "};\n\n";
  812. emitNameMatcher(OS);
  813. OS << "static Optional<std::pair<uint64_t, uint64_t>> "
  814. "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
  815. << " std::pair<StringRef, StringRef> RangePair = "
  816. "RuleIdentifier.split('-');\n"
  817. << " if (!RangePair.second.empty()) {\n"
  818. << " const auto First = "
  819. "getRuleIdxForIdentifier(RangePair.first);\n"
  820. << " const auto Last = "
  821. "getRuleIdxForIdentifier(RangePair.second);\n"
  822. << " if (!First.hasValue() || !Last.hasValue())\n"
  823. << " return None;\n"
  824. << " if (First >= Last)\n"
  825. << " report_fatal_error(\"Beginning of range should be before "
  826. "end of range\");\n"
  827. << " return {{*First, *Last + 1}};\n"
  828. << " } else if (RangePair.first == \"*\") {\n"
  829. << " return {{0, " << Rules.size() << "}};\n"
  830. << " } else {\n"
  831. << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
  832. << " if (!I.hasValue())\n"
  833. << " return None;\n"
  834. << " return {{*I, *I + 1}};\n"
  835. << " }\n"
  836. << " return None;\n"
  837. << "}\n\n";
  838. for (bool Enabled : {true, false}) {
  839. OS << "bool " << getClassName() << "RuleConfig::setRule"
  840. << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
  841. << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
  842. << " if (!MaybeRange.hasValue())\n"
  843. << " return false;\n"
  844. << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
  845. << " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n"
  846. << " return true;\n"
  847. << "}\n\n";
  848. }
  849. OS << "bool " << getClassName()
  850. << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n"
  851. << " return DisabledRules.test(RuleID);\n"
  852. << "}\n";
  853. OS << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n\n";
  854. OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n"
  855. << "\n"
  856. << "std::vector<std::string> " << Name << "Option;\n"
  857. << "cl::list<std::string> " << Name << "DisableOption(\n"
  858. << " \"" << Name.lower() << "-disable-rule\",\n"
  859. << " cl::desc(\"Disable one or more combiner rules temporarily in "
  860. << "the " << Name << " pass\"),\n"
  861. << " cl::CommaSeparated,\n"
  862. << " cl::Hidden,\n"
  863. << " cl::cat(GICombinerOptionCategory),\n"
  864. << " cl::callback([](const std::string &Str) {\n"
  865. << " " << Name << "Option.push_back(Str);\n"
  866. << " }));\n"
  867. << "cl::list<std::string> " << Name << "OnlyEnableOption(\n"
  868. << " \"" << Name.lower() << "-only-enable-rule\",\n"
  869. << " cl::desc(\"Disable all rules in the " << Name
  870. << " pass then re-enable the specified ones\"),\n"
  871. << " cl::Hidden,\n"
  872. << " cl::cat(GICombinerOptionCategory),\n"
  873. << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
  874. << " StringRef Str = CommaSeparatedArg;\n"
  875. << " " << Name << "Option.push_back(\"*\");\n"
  876. << " do {\n"
  877. << " auto X = Str.split(\",\");\n"
  878. << " " << Name << "Option.push_back((\"!\" + X.first).str());\n"
  879. << " Str = X.second;\n"
  880. << " } while (!Str.empty());\n"
  881. << " }));\n"
  882. << "\n"
  883. << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n"
  884. << " for (StringRef Identifier : " << Name << "Option) {\n"
  885. << " bool Enabled = Identifier.consume_front(\"!\");\n"
  886. << " if (Enabled && !setRuleEnabled(Identifier))\n"
  887. << " return false;\n"
  888. << " if (!Enabled && !setRuleDisabled(Identifier))\n"
  889. << " return false;\n"
  890. << " }\n"
  891. << " return true;\n"
  892. << "}\n\n";
  893. OS << "bool " << getClassName() << "::tryCombineAll(\n"
  894. << " GISelChangeObserver &Observer,\n"
  895. << " MachineInstr &MI,\n"
  896. << " MachineIRBuilder &B";
  897. emitAdditionalHelperMethodArguments(OS, Combiner);
  898. OS << ") const {\n"
  899. << " MachineBasicBlock *MBB = MI.getParent();\n"
  900. << " MachineFunction *MF = MBB->getParent();\n"
  901. << " MachineRegisterInfo &MRI = MF->getRegInfo();\n"
  902. << " SmallVector<MachineInstr *, 8> MIs = {&MI};\n\n"
  903. << " (void)MBB; (void)MF; (void)MRI; (void)RuleConfig;\n\n";
  904. OS << " // Match data\n";
  905. for (const auto &Rule : Rules)
  906. for (const auto &I : Rule->matchdata_decls())
  907. OS << " " << I.getType() << " " << I.getVariableName() << ";\n";
  908. OS << "\n";
  909. OS << " int Partition = -1;\n";
  910. generateCodeForTree(OS, *Tree, " ");
  911. OS << "\n return false;\n"
  912. << "}\n"
  913. << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n";
  914. }
  915. } // end anonymous namespace
  916. //===----------------------------------------------------------------------===//
  917. namespace llvm {
  918. void EmitGICombiner(RecordKeeper &RK, raw_ostream &OS) {
  919. CodeGenTarget Target(RK);
  920. emitSourceFileHeader("Global Combiner", OS);
  921. if (SelectedCombiners.empty())
  922. PrintFatalError("No combiners selected with -combiners");
  923. for (const auto &Combiner : SelectedCombiners) {
  924. Record *CombinerDef = RK.getDef(Combiner);
  925. if (!CombinerDef)
  926. PrintFatalError("Could not find " + Combiner);
  927. GICombinerEmitter(RK, Target, Combiner, CombinerDef).run(OS);
  928. }
  929. NumPatternTotalStatistic = NumPatternTotal;
  930. }
  931. } // namespace llvm