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