1 //===- GlobalCombinerEmitter.cpp - Generate a combiner --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 /// \file Generate a combiner implementation for GlobalISel from a declarative
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/SmallSet.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/ADT/StringSet.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/ScopedPrinter.h"
20 #include "llvm/Support/Timer.h"
21 #include "llvm/TableGen/Error.h"
22 #include "llvm/TableGen/StringMatcher.h"
23 #include "llvm/TableGen/TableGenBackend.h"
24 #include "CodeGenTarget.h"
25 #include "GlobalISel/CodeExpander.h"
26 #include "GlobalISel/CodeExpansions.h"
27 #include "GlobalISel/GIMatchDag.h"
28 #include "GlobalISel/GIMatchTree.h"
33 #define DEBUG_TYPE "gicombiner-emitter"
35 // FIXME: Use ALWAYS_ENABLED_STATISTIC once it's available.
36 unsigned NumPatternTotal
= 0;
37 STATISTIC(NumPatternTotalStatistic
, "Total number of patterns");
40 GICombinerEmitterCat("Options for -gen-global-isel-combiner");
41 static cl::list
<std::string
>
42 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
43 cl::cat(GICombinerEmitterCat
), cl::CommaSeparated
);
44 static cl::opt
<bool> ShowExpansions(
45 "gicombiner-show-expansions",
46 cl::desc("Use C++ comments to indicate occurence of code expansion"),
47 cl::cat(GICombinerEmitterCat
));
48 static cl::opt
<bool> StopAfterParse(
49 "gicombiner-stop-after-parse",
50 cl::desc("Stop processing after parsing rules and dump state"),
51 cl::cat(GICombinerEmitterCat
));
52 static cl::opt
<bool> StopAfterBuild(
53 "gicombiner-stop-after-build",
54 cl::desc("Stop processing after building the match tree"),
55 cl::cat(GICombinerEmitterCat
));
58 typedef uint64_t RuleID
;
60 // We're going to be referencing the same small strings quite a lot for operand
61 // names and the like. Make their lifetime management simple with a global
65 StringRef
insertStrTab(StringRef S
) {
68 return StrTab
.insert(S
).first
->first();
71 class format_partition_name
{
72 const GIMatchTree
&Tree
;
76 format_partition_name(const GIMatchTree
&Tree
, unsigned Idx
)
77 : Tree(Tree
), Idx(Idx
) {}
78 void print(raw_ostream
&OS
) const {
79 Tree
.getPartitioner()->emitPartitionName(OS
, Idx
);
82 raw_ostream
&operator<<(raw_ostream
&OS
, const format_partition_name
&Fmt
) {
87 /// Declares data that is passed from the match stage to the apply stage.
89 /// The symbol used in the tablegen patterns
90 StringRef PatternSymbol
;
91 /// The data type for the variable
93 /// The name of the variable as declared in the generated matcher.
94 std::string VariableName
;
97 MatchDataInfo(StringRef PatternSymbol
, StringRef Type
, StringRef VariableName
)
98 : PatternSymbol(PatternSymbol
), Type(Type
), VariableName(VariableName
) {}
100 StringRef
getPatternSymbol() const { return PatternSymbol
; };
101 StringRef
getType() const { return Type
; };
102 StringRef
getVariableName() const { return VariableName
; };
106 StringRef PatternSymbol
;
109 RootInfo(StringRef PatternSymbol
) : PatternSymbol(PatternSymbol
) {}
111 StringRef
getPatternSymbol() const { return PatternSymbol
; }
117 using const_matchdata_iterator
= std::vector
<MatchDataInfo
>::const_iterator
;
120 const GIMatchDagInstr
*N
;
121 const GIMatchDagOperand
*Op
;
122 const DagInit
*Matcher
;
125 VarInfo(const GIMatchDagInstr
*N
, const GIMatchDagOperand
*Op
,
126 const DagInit
*Matcher
)
127 : N(N
), Op(Op
), Matcher(Matcher
) {}
131 /// A unique ID for this rule
132 /// ID's are used for debugging and run-time disabling of rules among other
136 /// A unique ID that can be used for anonymous objects belonging to this rule.
137 /// Used to create unique names in makeNameForAnon*() without making tests
141 /// The record defining this rule.
142 const Record
&TheDef
;
144 /// The roots of a match. These are the leaves of the DAG that are closest to
145 /// the end of the function. I.e. the nodes that are encountered without
146 /// following any edges of the DAG described by the pattern as we work our way
147 /// from the bottom of the function to the top.
148 std::vector
<RootInfo
> Roots
;
152 /// A block of arbitrary C++ to finish testing the match.
153 /// FIXME: This is a temporary measure until we have actual pattern matching
154 const StringInit
*MatchingFixupCode
= nullptr;
156 /// The MatchData defined by the match stage and required by the apply stage.
157 /// This allows the plumbing of arbitrary data from C++ predicates between the
160 /// For example, suppose you have:
161 /// %A = <some-constant-expr>
162 /// %0 = G_ADD %1, %A
163 /// you could define a GIMatchPredicate that walks %A, constant folds as much
164 /// as possible and returns an APInt containing the discovered constant. You
165 /// could then declare:
166 /// def apint : GIDefMatchData<"APInt">;
167 /// add it to the rule with:
168 /// (defs root:$root, apint:$constant)
169 /// evaluate it in the pattern with a C++ function that takes a
170 /// MachineOperand& and an APInt& with:
171 /// (match [{MIR %root = G_ADD %0, %A }],
172 /// (constantfold operand:$A, apint:$constant))
173 /// and finally use it in the apply stage with:
174 /// (apply (create_operand
175 /// [{ MachineOperand::CreateImm(${constant}.getZExtValue());
176 /// ]}, apint:$constant),
177 /// [{MIR %root = FOO %0, %constant }])
178 std::vector
<MatchDataInfo
> MatchDataDecls
;
180 void declareMatchData(StringRef PatternSymbol
, StringRef Type
,
183 bool parseInstructionMatcher(const CodeGenTarget
&Target
, StringInit
*ArgName
,
185 StringMap
<std::vector
<VarInfo
>> &NamedEdgeDefs
,
186 StringMap
<std::vector
<VarInfo
>> &NamedEdgeUses
);
187 bool parseWipMatchOpcodeMatcher(const CodeGenTarget
&Target
,
188 StringInit
*ArgName
, const Init
&Arg
);
191 CombineRule(const CodeGenTarget
&Target
, GIMatchDagContext
&Ctx
, RuleID ID
,
193 : ID(ID
), TheDef(R
), MatchDag(Ctx
) {}
194 CombineRule(const CombineRule
&) = delete;
197 bool parseMatcher(const CodeGenTarget
&Target
);
199 RuleID
getID() const { return ID
; }
200 unsigned allocUID() { return UID
++; }
201 StringRef
getName() const { return TheDef
.getName(); }
202 const Record
&getDef() const { return TheDef
; }
203 const StringInit
*getMatchingFixupCode() const { return MatchingFixupCode
; }
204 size_t getNumRoots() const { return Roots
.size(); }
206 GIMatchDag
&getMatchDag() { return MatchDag
; }
207 const GIMatchDag
&getMatchDag() const { return MatchDag
; }
209 using const_root_iterator
= std::vector
<RootInfo
>::const_iterator
;
210 const_root_iterator
roots_begin() const { return Roots
.begin(); }
211 const_root_iterator
roots_end() const { return Roots
.end(); }
212 iterator_range
<const_root_iterator
> roots() const {
213 return llvm::make_range(Roots
.begin(), Roots
.end());
216 iterator_range
<const_matchdata_iterator
> matchdata_decls() const {
217 return make_range(MatchDataDecls
.begin(), MatchDataDecls
.end());
220 /// Export expansions for this rule
221 void declareExpansions(CodeExpansions
&Expansions
) const {
222 for (const auto &I
: matchdata_decls())
223 Expansions
.declare(I
.getPatternSymbol(), I
.getVariableName());
226 /// The matcher will begin from the roots and will perform the match by
227 /// traversing the edges to cover the whole DAG. This function reverses DAG
228 /// edges such that everything is reachable from a root. This is part of the
229 /// preparation work for flattening the DAG into a tree.
230 void reorientToRoots() {
231 SmallSet
<const GIMatchDagInstr
*, 5> Roots
;
232 SmallSet
<const GIMatchDagInstr
*, 5> Visited
;
233 SmallSet
<GIMatchDagEdge
*, 20> EdgesRemaining
;
235 for (auto &I
: MatchDag
.roots()) {
239 for (auto &I
: MatchDag
.edges())
240 EdgesRemaining
.insert(I
);
242 bool Progressed
= false;
243 SmallSet
<GIMatchDagEdge
*, 20> EdgesToRemove
;
244 while (!EdgesRemaining
.empty()) {
245 for (auto *EI
: EdgesRemaining
) {
246 if (Visited
.count(EI
->getFromMI())) {
247 if (Roots
.count(EI
->getToMI()))
248 PrintError(TheDef
.getLoc(), "One or more roots are unnecessary");
249 Visited
.insert(EI
->getToMI());
250 EdgesToRemove
.insert(EI
);
254 for (GIMatchDagEdge
*ToRemove
: EdgesToRemove
)
255 EdgesRemaining
.erase(ToRemove
);
256 EdgesToRemove
.clear();
258 for (auto EI
= EdgesRemaining
.begin(), EE
= EdgesRemaining
.end();
260 if (Visited
.count((*EI
)->getToMI())) {
262 Visited
.insert((*EI
)->getToMI());
263 EdgesToRemove
.insert(*EI
);
266 for (GIMatchDagEdge
*ToRemove
: EdgesToRemove
)
267 EdgesRemaining
.erase(ToRemove
);
268 EdgesToRemove
.clear();
272 LLVM_DEBUG(dbgs() << "No progress\n");
280 /// A convenience function to check that an Init refers to a specific def. This
281 /// is primarily useful for testing for defs and similar in DagInit's since
282 /// DagInit's support any type inside them.
283 static bool isSpecificDef(const Init
&N
, StringRef Def
) {
284 if (const DefInit
*OpI
= dyn_cast
<DefInit
>(&N
))
285 if (OpI
->getDef()->getName() == Def
)
290 /// A convenience function to check that an Init refers to a def that is a
291 /// subclass of the given class and coerce it to a def if it is. This is
292 /// primarily useful for testing for subclasses of GIMatchKind and similar in
293 /// DagInit's since DagInit's support any type inside them.
294 static Record
*getDefOfSubClass(const Init
&N
, StringRef Cls
) {
295 if (const DefInit
*OpI
= dyn_cast
<DefInit
>(&N
))
296 if (OpI
->getDef()->isSubClassOf(Cls
))
297 return OpI
->getDef();
301 /// A convenience function to check that an Init refers to a dag whose operator
302 /// is a specific def and coerce it to a dag if it is. This is primarily useful
303 /// for testing for subclasses of GIMatchKind and similar in DagInit's since
304 /// DagInit's support any type inside them.
305 static const DagInit
*getDagWithSpecificOperator(const Init
&N
,
307 if (const DagInit
*I
= dyn_cast
<DagInit
>(&N
))
308 if (I
->getNumArgs() > 0)
309 if (const DefInit
*OpI
= dyn_cast
<DefInit
>(I
->getOperator()))
310 if (OpI
->getDef()->getName() == Name
)
315 /// A convenience function to check that an Init refers to a dag whose operator
316 /// is a def that is a subclass of the given class and coerce it to a dag if it
317 /// is. This is primarily useful for testing for subclasses of GIMatchKind and
318 /// similar in DagInit's since DagInit's support any type inside them.
319 static const DagInit
*getDagWithOperatorOfSubClass(const Init
&N
,
321 if (const DagInit
*I
= dyn_cast
<DagInit
>(&N
))
322 if (I
->getNumArgs() > 0)
323 if (const DefInit
*OpI
= dyn_cast
<DefInit
>(I
->getOperator()))
324 if (OpI
->getDef()->isSubClassOf(Cls
))
329 StringRef
makeNameForAnonInstr(CombineRule
&Rule
) {
330 return insertStrTab(to_string(
331 format("__anon%" PRIu64
"_%u", Rule
.getID(), Rule
.allocUID())));
334 StringRef
makeDebugName(CombineRule
&Rule
, StringRef Name
) {
335 return insertStrTab(Name
.empty() ? makeNameForAnonInstr(Rule
) : StringRef(Name
));
338 StringRef
makeNameForAnonPredicate(CombineRule
&Rule
) {
339 return insertStrTab(to_string(
340 format("__anonpred%" PRIu64
"_%u", Rule
.getID(), Rule
.allocUID())));
343 void CombineRule::declareMatchData(StringRef PatternSymbol
, StringRef Type
,
345 MatchDataDecls
.emplace_back(PatternSymbol
, Type
, VarName
);
348 bool CombineRule::parseDefs() {
349 DagInit
*Defs
= TheDef
.getValueAsDag("Defs");
351 if (Defs
->getOperatorAsDef(TheDef
.getLoc())->getName() != "defs") {
352 PrintError(TheDef
.getLoc(), "Expected defs operator");
356 for (unsigned I
= 0, E
= Defs
->getNumArgs(); I
< E
; ++I
) {
357 // Roots should be collected into Roots
358 if (isSpecificDef(*Defs
->getArg(I
), "root")) {
359 Roots
.emplace_back(Defs
->getArgNameStr(I
));
363 // Subclasses of GIDefMatchData should declare that this rule needs to pass
364 // data from the match stage to the apply stage, and ensure that the
365 // generated matcher has a suitable variable for it to do so.
366 if (Record
*MatchDataRec
=
367 getDefOfSubClass(*Defs
->getArg(I
), "GIDefMatchData")) {
368 declareMatchData(Defs
->getArgNameStr(I
),
369 MatchDataRec
->getValueAsString("Type"),
370 llvm::to_string(llvm::format("MatchData%" PRIu64
, ID
)));
374 // Otherwise emit an appropriate error message.
375 if (getDefOfSubClass(*Defs
->getArg(I
), "GIDefKind"))
376 PrintError(TheDef
.getLoc(),
377 "This GIDefKind not implemented in tablegen");
378 else if (getDefOfSubClass(*Defs
->getArg(I
), "GIDefKindWithArgs"))
379 PrintError(TheDef
.getLoc(),
380 "This GIDefKindWithArgs not implemented in tablegen");
382 PrintError(TheDef
.getLoc(),
383 "Expected a subclass of GIDefKind or a sub-dag whose "
384 "operator is of type GIDefKindWithArgs");
389 PrintError(TheDef
.getLoc(), "Combine rules must have at least one root");
395 // Parse an (Instruction $a:Arg1, $b:Arg2, ...) matcher. Edges are formed
396 // between matching operand names between different matchers.
397 bool CombineRule::parseInstructionMatcher(
398 const CodeGenTarget
&Target
, StringInit
*ArgName
, const Init
&Arg
,
399 StringMap
<std::vector
<VarInfo
>> &NamedEdgeDefs
,
400 StringMap
<std::vector
<VarInfo
>> &NamedEdgeUses
) {
401 if (const DagInit
*Matcher
=
402 getDagWithOperatorOfSubClass(Arg
, "Instruction")) {
404 Target
.getInstruction(Matcher
->getOperatorAsDef(TheDef
.getLoc()));
406 StringRef Name
= ArgName
? ArgName
->getValue() : "";
409 MatchDag
.addInstrNode(makeDebugName(*this, Name
), insertStrTab(Name
),
410 MatchDag
.getContext().makeOperandList(Instr
));
412 N
->setOpcodeAnnotation(&Instr
);
413 const auto &P
= MatchDag
.addPredicateNode
<GIMatchDagOpcodePredicate
>(
414 makeNameForAnonPredicate(*this), Instr
);
415 MatchDag
.addPredicateDependency(N
, nullptr, P
, &P
->getOperandInfo()["mi"]);
417 for (const auto &NameInit
: Matcher
->getArgNames()) {
418 StringRef Name
= insertStrTab(NameInit
->getAsUnquotedString());
421 N
->assignNameToOperand(OpIdx
, Name
);
423 // Record the endpoints of any named edges. We'll add the cartesian
424 // product of edges later.
425 const auto &InstrOperand
= N
->getOperandInfo()[OpIdx
];
426 if (InstrOperand
.isDef()) {
427 NamedEdgeDefs
.try_emplace(Name
);
428 NamedEdgeDefs
[Name
].emplace_back(N
, &InstrOperand
, Matcher
);
430 NamedEdgeUses
.try_emplace(Name
);
431 NamedEdgeUses
[Name
].emplace_back(N
, &InstrOperand
, Matcher
);
434 if (InstrOperand
.isDef()) {
435 if (any_of(Roots
, [&](const RootInfo
&X
) {
436 return X
.getPatternSymbol() == Name
;
450 // Parse the wip_match_opcode placeholder that's temporarily present in lieu of
451 // implementing macros or choices between two matchers.
452 bool CombineRule::parseWipMatchOpcodeMatcher(const CodeGenTarget
&Target
,
455 if (const DagInit
*Matcher
=
456 getDagWithSpecificOperator(Arg
, "wip_match_opcode")) {
457 StringRef Name
= ArgName
? ArgName
->getValue() : "";
460 MatchDag
.addInstrNode(makeDebugName(*this, Name
), insertStrTab(Name
),
461 MatchDag
.getContext().makeEmptyOperandList());
463 if (any_of(Roots
, [&](const RootInfo
&X
) {
464 return ArgName
&& X
.getPatternSymbol() == ArgName
->getValue();
469 const auto &P
= MatchDag
.addPredicateNode
<GIMatchDagOneOfOpcodesPredicate
>(
470 makeNameForAnonPredicate(*this));
471 MatchDag
.addPredicateDependency(N
, nullptr, P
, &P
->getOperandInfo()["mi"]);
472 // Each argument is an opcode that will pass this predicate. Add them all to
473 // the predicate implementation
474 for (const auto &Arg
: Matcher
->getArgs()) {
475 Record
*OpcodeDef
= getDefOfSubClass(*Arg
, "Instruction");
477 P
->addOpcode(&Target
.getInstruction(OpcodeDef
));
480 PrintError(TheDef
.getLoc(),
481 "Arguments to wip_match_opcode must be instructions");
488 bool CombineRule::parseMatcher(const CodeGenTarget
&Target
) {
489 StringMap
<std::vector
<VarInfo
>> NamedEdgeDefs
;
490 StringMap
<std::vector
<VarInfo
>> NamedEdgeUses
;
491 DagInit
*Matchers
= TheDef
.getValueAsDag("Match");
493 if (Matchers
->getOperatorAsDef(TheDef
.getLoc())->getName() != "match") {
494 PrintError(TheDef
.getLoc(), "Expected match operator");
498 if (Matchers
->getNumArgs() == 0) {
499 PrintError(TheDef
.getLoc(), "Matcher is empty");
503 // The match section consists of a list of matchers and predicates. Parse each
504 // one and add the equivalent GIMatchDag nodes, predicates, and edges.
505 for (unsigned I
= 0; I
< Matchers
->getNumArgs(); ++I
) {
506 if (parseInstructionMatcher(Target
, Matchers
->getArgName(I
),
507 *Matchers
->getArg(I
), NamedEdgeDefs
,
511 if (parseWipMatchOpcodeMatcher(Target
, Matchers
->getArgName(I
),
512 *Matchers
->getArg(I
)))
516 // Parse arbitrary C++ code we have in lieu of supporting MIR matching
517 if (const StringInit
*StringI
= dyn_cast
<StringInit
>(Matchers
->getArg(I
))) {
518 assert(!MatchingFixupCode
&&
519 "Only one block of arbitrary code is currently permitted");
520 MatchingFixupCode
= StringI
;
521 MatchDag
.setHasPostMatchPredicate(true);
525 PrintError(TheDef
.getLoc(),
526 "Expected a subclass of GIMatchKind or a sub-dag whose "
527 "operator is either of a GIMatchKindWithArgs or Instruction");
528 PrintNote("Pattern was `" + Matchers
->getArg(I
)->getAsString() + "'");
532 // Add the cartesian product of use -> def edges.
533 bool FailedToAddEdges
= false;
534 for (const auto &NameAndDefs
: NamedEdgeDefs
) {
535 if (NameAndDefs
.getValue().size() > 1) {
536 PrintError(TheDef
.getLoc(),
537 "Two different MachineInstrs cannot def the same vreg");
538 for (const auto &NameAndDefOp
: NameAndDefs
.getValue())
539 PrintNote("in " + to_string(*NameAndDefOp
.N
) + " created from " +
540 to_string(*NameAndDefOp
.Matcher
) + "");
541 FailedToAddEdges
= true;
543 const auto &Uses
= NamedEdgeUses
[NameAndDefs
.getKey()];
544 for (const VarInfo
&DefVar
: NameAndDefs
.getValue()) {
545 for (const VarInfo
&UseVar
: Uses
) {
546 MatchDag
.addEdge(insertStrTab(NameAndDefs
.getKey()), UseVar
.N
, UseVar
.Op
,
547 DefVar
.N
, DefVar
.Op
);
551 if (FailedToAddEdges
)
554 // If a variable is referenced in multiple use contexts then we need a
555 // predicate to confirm they are the same operand. We can elide this if it's
556 // also referenced in a def context and we're traversing the def-use chain
557 // from the def to the uses but we can't know which direction we're going
558 // until after reorientToRoots().
559 for (const auto &NameAndUses
: NamedEdgeUses
) {
560 const auto &Uses
= NameAndUses
.getValue();
561 if (Uses
.size() > 1) {
562 const auto &LeadingVar
= Uses
.front();
563 for (const auto &Var
: ArrayRef
<VarInfo
>(Uses
).drop_front()) {
564 // Add a predicate for each pair until we've covered the whole
565 // equivalence set. We could test the whole set in a single predicate
566 // but that means we can't test any equivalence until all the MO's are
567 // available which can lead to wasted work matching the DAG when this
568 // predicate can already be seen to have failed.
570 // We have a similar problem due to the need to wait for a particular MO
571 // before being able to test any of them. However, that is mitigated by
572 // the order in which we build the DAG. We build from the roots outwards
573 // so by using the first recorded use in all the predicates, we are
574 // making the dependency on one of the earliest visited references in
575 // the DAG. It's not guaranteed once the generated matcher is optimized
576 // (because the factoring the common portions of rules might change the
577 // visit order) but this should mean that these predicates depend on the
578 // first MO to become available.
579 const auto &P
= MatchDag
.addPredicateNode
<GIMatchDagSameMOPredicate
>(
580 makeNameForAnonPredicate(*this));
581 MatchDag
.addPredicateDependency(LeadingVar
.N
, LeadingVar
.Op
, P
,
582 &P
->getOperandInfo()["mi0"]);
583 MatchDag
.addPredicateDependency(Var
.N
, Var
.Op
, P
,
584 &P
->getOperandInfo()["mi1"]);
591 class GICombinerEmitter
{
592 RecordKeeper
&Records
;
594 const CodeGenTarget
&Target
;
596 std::vector
<std::unique_ptr
<CombineRule
>> Rules
;
597 GIMatchDagContext MatchDagCtx
;
599 std::unique_ptr
<CombineRule
> makeCombineRule(const Record
&R
);
601 void gatherRules(std::vector
<std::unique_ptr
<CombineRule
>> &ActiveRules
,
602 const std::vector
<Record
*> &&RulesAndGroups
);
605 explicit GICombinerEmitter(RecordKeeper
&RK
, const CodeGenTarget
&Target
,
606 StringRef Name
, Record
*Combiner
);
607 ~GICombinerEmitter() {}
609 StringRef
getClassName() const {
610 return Combiner
->getValueAsString("Classname");
612 void run(raw_ostream
&OS
);
614 /// Emit the name matcher (guarded by #ifndef NDEBUG) used to disable rules in
615 /// response to the generated cl::opt.
616 void emitNameMatcher(raw_ostream
&OS
) const;
618 void generateCodeForTree(raw_ostream
&OS
, const GIMatchTree
&Tree
,
619 StringRef Indent
) const;
622 GICombinerEmitter::GICombinerEmitter(RecordKeeper
&RK
,
623 const CodeGenTarget
&Target
,
624 StringRef Name
, Record
*Combiner
)
625 : Records(RK
), Name(Name
), Target(Target
), Combiner(Combiner
) {}
627 void GICombinerEmitter::emitNameMatcher(raw_ostream
&OS
) const {
628 std::vector
<std::pair
<std::string
, std::string
>> Cases
;
629 Cases
.reserve(Rules
.size());
631 for (const CombineRule
&EnumeratedRule
: make_pointee_range(Rules
)) {
633 raw_string_ostream
SS(Code
);
634 SS
<< "return " << EnumeratedRule
.getID() << ";\n";
636 std::make_pair(std::string(EnumeratedRule
.getName()), SS
.str()));
639 OS
<< "static Optional<uint64_t> getRuleIdxForIdentifier(StringRef "
640 "RuleIdentifier) {\n"
642 << " // getAtInteger(...) returns false on success\n"
643 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
646 << "#ifndef NDEBUG\n";
647 StringMatcher
Matcher("RuleIdentifier", Cases
, OS
);
649 OS
<< "#endif // ifndef NDEBUG\n\n"
654 std::unique_ptr
<CombineRule
>
655 GICombinerEmitter::makeCombineRule(const Record
&TheDef
) {
656 std::unique_ptr
<CombineRule
> Rule
=
657 std::make_unique
<CombineRule
>(Target
, MatchDagCtx
, NumPatternTotal
, TheDef
);
659 if (!Rule
->parseDefs())
661 if (!Rule
->parseMatcher(Target
))
664 Rule
->reorientToRoots();
667 dbgs() << "Parsed rule defs/match for '" << Rule
->getName() << "'\n";
668 Rule
->getMatchDag().dump();
669 Rule
->getMatchDag().writeDOTGraph(dbgs(), Rule
->getName());
674 // For now, don't support traversing from def to use. We'll come back to
675 // this later once we have the algorithm changes to support it.
676 bool EmittedDefToUseError
= false;
677 for (const auto &E
: Rule
->getMatchDag().edges()) {
678 if (E
->isDefToUse()) {
679 if (!EmittedDefToUseError
) {
682 "Generated state machine cannot lookup uses from a def (yet)");
683 EmittedDefToUseError
= true;
685 PrintNote("Node " + to_string(*E
->getFromMI()));
686 PrintNote("Node " + to_string(*E
->getToMI()));
687 PrintNote("Edge " + to_string(*E
));
690 if (EmittedDefToUseError
)
693 // For now, don't support multi-root rules. We'll come back to this later
694 // once we have the algorithm changes to support it.
695 if (Rule
->getNumRoots() > 1) {
696 PrintError(TheDef
.getLoc(), "Multi-root matches are not supported (yet)");
702 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
703 void GICombinerEmitter::gatherRules(
704 std::vector
<std::unique_ptr
<CombineRule
>> &ActiveRules
,
705 const std::vector
<Record
*> &&RulesAndGroups
) {
706 for (Record
*R
: RulesAndGroups
) {
707 if (R
->isValueUnset("Rules")) {
708 std::unique_ptr
<CombineRule
> Rule
= makeCombineRule(*R
);
709 if (Rule
== nullptr) {
710 PrintError(R
->getLoc(), "Failed to parse rule");
713 ActiveRules
.emplace_back(std::move(Rule
));
716 gatherRules(ActiveRules
, R
->getValueAsListOfDefs("Rules"));
720 void GICombinerEmitter::generateCodeForTree(raw_ostream
&OS
,
721 const GIMatchTree
&Tree
,
722 StringRef Indent
) const {
723 if (Tree
.getPartitioner() != nullptr) {
724 Tree
.getPartitioner()->generatePartitionSelectorCode(OS
, Indent
);
725 for (const auto &EnumChildren
: enumerate(Tree
.children())) {
726 OS
<< Indent
<< "if (Partition == " << EnumChildren
.index() << " /* "
727 << format_partition_name(Tree
, EnumChildren
.index()) << " */) {\n";
728 generateCodeForTree(OS
, EnumChildren
.value(), (Indent
+ " ").str());
729 OS
<< Indent
<< "}\n";
734 bool AnyFullyTested
= false;
735 for (const auto &Leaf
: Tree
.possible_leaves()) {
736 OS
<< Indent
<< "// Leaf name: " << Leaf
.getName() << "\n";
738 const CombineRule
*Rule
= Leaf
.getTargetData
<CombineRule
>();
739 const Record
&RuleDef
= Rule
->getDef();
741 OS
<< Indent
<< "// Rule: " << RuleDef
.getName() << "\n"
742 << Indent
<< "if (!RuleConfig->isRuleDisabled(" << Rule
->getID()
745 CodeExpansions Expansions
;
746 for (const auto &VarBinding
: Leaf
.var_bindings()) {
747 if (VarBinding
.isInstr())
748 Expansions
.declare(VarBinding
.getName(),
749 "MIs[" + to_string(VarBinding
.getInstrID()) + "]");
751 Expansions
.declare(VarBinding
.getName(),
752 "MIs[" + to_string(VarBinding
.getInstrID()) +
754 to_string(VarBinding
.getOpIdx()) + ")");
756 Rule
->declareExpansions(Expansions
);
758 DagInit
*Applyer
= RuleDef
.getValueAsDag("Apply");
759 if (Applyer
->getOperatorAsDef(RuleDef
.getLoc())->getName() !=
761 PrintError(RuleDef
.getLoc(), "Expected 'apply' operator in Apply DAG");
765 OS
<< Indent
<< " if (1\n";
767 // Attempt to emit code for any untested predicates left over. Note that
768 // isFullyTested() will remain false even if we succeed here and therefore
769 // combine rule elision will not be performed. This is because we do not
770 // know if there's any connection between the predicates for each leaf and
771 // therefore can't tell if one makes another unreachable. Ideally, the
772 // partitioner(s) would be sufficiently complete to prevent us from having
773 // untested predicates left over.
774 for (const GIMatchDagPredicate
*Predicate
: Leaf
.untested_predicates()) {
775 if (Predicate
->generateCheckCode(OS
, (Indent
+ " ").str(),
778 PrintError(RuleDef
.getLoc(),
779 "Unable to test predicate used in rule");
781 "This indicates an incomplete implementation in tablegen");
782 Predicate
->print(errs());
785 << "llvm_unreachable(\"TableGen did not emit complete code for this "
790 if (Rule
->getMatchingFixupCode() &&
791 !Rule
->getMatchingFixupCode()->getValue().empty()) {
792 // FIXME: Single-use lambda's like this are a serious compile-time
793 // performance and memory issue. It's convenient for this early stage to
794 // defer some work to successive patches but we need to eliminate this
795 // before the ruleset grows to small-moderate size. Last time, it became
796 // a big problem for low-mem systems around the 500 rule mark but by the
797 // time we grow that large we should have merged the ISel match table
798 // mechanism with the Combiner.
799 OS
<< Indent
<< " && [&]() {\n"
801 << CodeExpander(Rule
->getMatchingFixupCode()->getValue(), Expansions
,
802 RuleDef
.getLoc(), ShowExpansions
)
804 << Indent
<< " return true;\n"
807 OS
<< ") {\n" << Indent
<< " ";
809 if (const StringInit
*Code
= dyn_cast
<StringInit
>(Applyer
->getArg(0))) {
810 OS
<< CodeExpander(Code
->getAsUnquotedString(), Expansions
,
811 RuleDef
.getLoc(), ShowExpansions
)
813 << Indent
<< " return true;\n"
816 PrintError(RuleDef
.getLoc(), "Expected apply code block");
820 OS
<< Indent
<< "}\n";
822 assert(Leaf
.isFullyTraversed());
824 // If we didn't have any predicates left over and we're not using the
825 // trap-door we have to support arbitrary C++ code while we're migrating to
826 // the declarative style then we know that subsequent leaves are
828 if (Leaf
.isFullyTested() &&
829 (!Rule
->getMatchingFixupCode() ||
830 Rule
->getMatchingFixupCode()->getValue().empty())) {
831 AnyFullyTested
= true;
833 << "llvm_unreachable(\"Combine rule elision was incorrect\");\n"
834 << Indent
<< "return false;\n";
838 OS
<< Indent
<< "return false;\n";
841 static void emitAdditionalHelperMethodArguments(raw_ostream
&OS
,
843 for (Record
*Arg
: Combiner
->getValueAsListOfDefs("AdditionalArguments"))
844 OS
<< ",\n " << Arg
->getValueAsString("Type")
845 << Arg
->getValueAsString("Name");
848 void GICombinerEmitter::run(raw_ostream
&OS
) {
849 Records
.startTimer("Gather rules");
850 gatherRules(Rules
, Combiner
->getValueAsListOfDefs("Rules"));
851 if (StopAfterParse
) {
852 MatchDagCtx
.print(errs());
853 PrintNote(Combiner
->getLoc(),
854 "Terminating due to -gicombiner-stop-after-parse");
858 PrintFatalError(Combiner
->getLoc(), "Failed to parse one or more rules");
859 LLVM_DEBUG(dbgs() << "Optimizing tree for " << Rules
.size() << " rules\n");
860 std::unique_ptr
<GIMatchTree
> Tree
;
861 Records
.startTimer("Optimize combiner");
863 GIMatchTreeBuilder
TreeBuilder(0);
864 for (const auto &Rule
: Rules
) {
865 bool HadARoot
= false;
866 for (const auto &Root
: enumerate(Rule
->getMatchDag().roots())) {
867 TreeBuilder
.addLeaf(Rule
->getName(), Root
.index(), Rule
->getMatchDag(),
872 PrintFatalError(Rule
->getDef().getLoc(), "All rules must have a root");
875 Tree
= TreeBuilder
.run();
877 if (StopAfterBuild
) {
878 Tree
->writeDOTGraph(outs());
879 PrintNote(Combiner
->getLoc(),
880 "Terminating due to -gicombiner-stop-after-build");
884 Records
.startTimer("Emit combiner");
885 OS
<< "#ifdef " << Name
.upper() << "_GENCOMBINERHELPER_DEPS\n"
886 << "#include \"llvm/ADT/SparseBitVector.h\"\n"
887 << "namespace llvm {\n"
888 << "extern cl::OptionCategory GICombinerOptionCategory;\n"
889 << "} // end namespace llvm\n"
890 << "#endif // ifdef " << Name
.upper() << "_GENCOMBINERHELPER_DEPS\n\n";
892 OS
<< "#ifdef " << Name
.upper() << "_GENCOMBINERHELPER_H\n"
893 << "class " << getClassName() << "RuleConfig {\n"
894 << " SparseBitVector<> DisabledRules;\n"
897 << " bool parseCommandLineOption();\n"
898 << " bool isRuleDisabled(unsigned ID) const;\n"
899 << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
900 << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
903 << "class " << getClassName();
904 StringRef StateClass
= Combiner
->getValueAsString("StateClass");
905 if (!StateClass
.empty())
906 OS
<< " : public " << StateClass
;
908 << " const " << getClassName() << "RuleConfig *RuleConfig;\n"
911 << " template <typename... Args>" << getClassName() << "(const "
912 << getClassName() << "RuleConfig &RuleConfig, Args &&... args) : ";
913 if (!StateClass
.empty())
914 OS
<< StateClass
<< "(std::forward<Args>(args)...), ";
915 OS
<< "RuleConfig(&RuleConfig) {}\n"
917 << " bool tryCombineAll(\n"
918 << " GISelChangeObserver &Observer,\n"
919 << " MachineInstr &MI,\n"
920 << " MachineIRBuilder &B";
921 emitAdditionalHelperMethodArguments(OS
, Combiner
);
927 OS
<< "static Optional<std::pair<uint64_t, uint64_t>> "
928 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
929 << " std::pair<StringRef, StringRef> RangePair = "
930 "RuleIdentifier.split('-');\n"
931 << " if (!RangePair.second.empty()) {\n"
932 << " const auto First = "
933 "getRuleIdxForIdentifier(RangePair.first);\n"
934 << " const auto Last = "
935 "getRuleIdxForIdentifier(RangePair.second);\n"
936 << " if (!First.hasValue() || !Last.hasValue())\n"
938 << " if (First >= Last)\n"
939 << " report_fatal_error(\"Beginning of range should be before "
941 << " return {{*First, *Last + 1}};\n"
942 << " } else if (RangePair.first == \"*\") {\n"
943 << " return {{0, " << Rules
.size() << "}};\n"
945 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
946 << " if (!I.hasValue())\n"
948 << " return {{*I, *I + 1}};\n"
953 for (bool Enabled
: {true, false}) {
954 OS
<< "bool " << getClassName() << "RuleConfig::setRule"
955 << (Enabled
? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
956 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
957 << " if (!MaybeRange.hasValue())\n"
958 << " return false;\n"
959 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
960 << " DisabledRules." << (Enabled
? "reset" : "set") << "(I);\n"
965 OS
<< "bool " << getClassName()
966 << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n"
967 << " return DisabledRules.test(RuleID);\n"
969 OS
<< "#endif // ifdef " << Name
.upper() << "_GENCOMBINERHELPER_H\n\n";
971 OS
<< "#ifdef " << Name
.upper() << "_GENCOMBINERHELPER_CPP\n"
973 << "std::vector<std::string> " << Name
<< "Option;\n"
974 << "cl::list<std::string> " << Name
<< "DisableOption(\n"
975 << " \"" << Name
.lower() << "-disable-rule\",\n"
976 << " cl::desc(\"Disable one or more combiner rules temporarily in "
977 << "the " << Name
<< " pass\"),\n"
978 << " cl::CommaSeparated,\n"
980 << " cl::cat(GICombinerOptionCategory),\n"
981 << " cl::callback([](const std::string &Str) {\n"
982 << " " << Name
<< "Option.push_back(Str);\n"
984 << "cl::list<std::string> " << Name
<< "OnlyEnableOption(\n"
985 << " \"" << Name
.lower() << "-only-enable-rule\",\n"
986 << " cl::desc(\"Disable all rules in the " << Name
987 << " pass then re-enable the specified ones\"),\n"
989 << " cl::cat(GICombinerOptionCategory),\n"
990 << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
991 << " StringRef Str = CommaSeparatedArg;\n"
992 << " " << Name
<< "Option.push_back(\"*\");\n"
994 << " auto X = Str.split(\",\");\n"
995 << " " << Name
<< "Option.push_back((\"!\" + X.first).str());\n"
996 << " Str = X.second;\n"
997 << " } while (!Str.empty());\n"
1000 << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n"
1001 << " for (StringRef Identifier : " << Name
<< "Option) {\n"
1002 << " bool Enabled = Identifier.consume_front(\"!\");\n"
1003 << " if (Enabled && !setRuleEnabled(Identifier))\n"
1004 << " return false;\n"
1005 << " if (!Enabled && !setRuleDisabled(Identifier))\n"
1006 << " return false;\n"
1008 << " return true;\n"
1011 OS
<< "bool " << getClassName() << "::tryCombineAll(\n"
1012 << " GISelChangeObserver &Observer,\n"
1013 << " MachineInstr &MI,\n"
1014 << " MachineIRBuilder &B";
1015 emitAdditionalHelperMethodArguments(OS
, Combiner
);
1017 << " MachineBasicBlock *MBB = MI.getParent();\n"
1018 << " MachineFunction *MF = MBB->getParent();\n"
1019 << " MachineRegisterInfo &MRI = MF->getRegInfo();\n"
1020 << " SmallVector<MachineInstr *, 8> MIs = {&MI};\n\n"
1021 << " (void)MBB; (void)MF; (void)MRI; (void)RuleConfig;\n\n";
1023 OS
<< " // Match data\n";
1024 for (const auto &Rule
: Rules
)
1025 for (const auto &I
: Rule
->matchdata_decls())
1026 OS
<< " " << I
.getType() << " " << I
.getVariableName() << ";\n";
1029 OS
<< " int Partition = -1;\n";
1030 generateCodeForTree(OS
, *Tree
, " ");
1031 OS
<< "\n return false;\n"
1033 << "#endif // ifdef " << Name
.upper() << "_GENCOMBINERHELPER_CPP\n";
1036 } // end anonymous namespace
1038 //===----------------------------------------------------------------------===//
1041 void EmitGICombiner(RecordKeeper
&RK
, raw_ostream
&OS
) {
1042 CodeGenTarget
Target(RK
);
1043 emitSourceFileHeader("Global Combiner", OS
);
1045 if (SelectedCombiners
.empty())
1046 PrintFatalError("No combiners selected with -combiners");
1047 for (const auto &Combiner
: SelectedCombiners
) {
1048 Record
*CombinerDef
= RK
.getDef(Combiner
);
1050 PrintFatalError("Could not find " + Combiner
);
1051 GICombinerEmitter(RK
, Target
, Combiner
, CombinerDef
).run(OS
);
1053 NumPatternTotalStatistic
= NumPatternTotal
;