1 //===- GlobalISelCombinerMatchTableEmitter.cpp - --------------------------===//
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
10 /// syntax using GlobalISelMatchTable.
12 /// Usually, TableGen backends use "assert is an error" as a means to report
13 /// invalid input. They try to diagnose common case but don't try very hard and
14 /// crashes can be common. This backend aims to behave closer to how a language
15 /// compiler frontend would behave: we try extra hard to diagnose invalid inputs
16 /// early, and any crash should be considered a bug (= a feature or diagnostic
19 /// While this can make the backend a bit more complex than it needs to be, it
20 /// pays off because MIR patterns can get complicated. Giving useful error
21 /// messages to combine writers can help boost their productivity.
23 /// As with anything, a good balance has to be found. We also don't want to
24 /// write hundreds of lines of code to detect edge cases. In practice, crashing
25 /// very occasionally, or giving poor errors in some rare instances, is fine.
27 //===----------------------------------------------------------------------===//
29 #include "CodeGenInstruction.h"
30 #include "CodeGenTarget.h"
31 #include "GlobalISel/CXXPredicates.h"
32 #include "GlobalISel/CodeExpander.h"
33 #include "GlobalISel/CodeExpansions.h"
34 #include "GlobalISel/CombinerUtils.h"
35 #include "GlobalISel/MatchDataInfo.h"
36 #include "GlobalISel/Patterns.h"
37 #include "GlobalISelMatchTable.h"
38 #include "GlobalISelMatchTableExecutorEmitter.h"
39 #include "SubtargetFeatureInfo.h"
40 #include "llvm/ADT/APInt.h"
41 #include "llvm/ADT/EquivalenceClasses.h"
42 #include "llvm/ADT/Hashing.h"
43 #include "llvm/ADT/MapVector.h"
44 #include "llvm/ADT/SetVector.h"
45 #include "llvm/ADT/Statistic.h"
46 #include "llvm/ADT/StringSet.h"
47 #include "llvm/Support/CommandLine.h"
48 #include "llvm/Support/Debug.h"
49 #include "llvm/Support/PrettyStackTrace.h"
50 #include "llvm/Support/ScopedPrinter.h"
51 #include "llvm/TableGen/Error.h"
52 #include "llvm/TableGen/Record.h"
53 #include "llvm/TableGen/StringMatcher.h"
54 #include "llvm/TableGen/TableGenBackend.h"
58 using namespace llvm::gi
;
60 #define DEBUG_TYPE "gicombiner-emitter"
64 GICombinerEmitterCat("Options for -gen-global-isel-combiner");
65 cl::opt
<bool> StopAfterParse(
66 "gicombiner-stop-after-parse",
67 cl::desc("Stop processing after parsing rules and dump state"),
68 cl::cat(GICombinerEmitterCat
));
70 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
71 cl::cat(GICombinerEmitterCat
), cl::CommaSeparated
);
72 cl::opt
<bool> DebugCXXPreds(
73 "gicombiner-debug-cxxpreds",
74 cl::desc("Add Contextual/Debug comments to all C++ predicates"),
75 cl::cat(GICombinerEmitterCat
));
76 cl::opt
<bool> DebugTypeInfer("gicombiner-debug-typeinfer",
77 cl::desc("Print type inference debug logs"),
78 cl::cat(GICombinerEmitterCat
));
80 constexpr StringLiteral CXXApplyPrefix
= "GICXXCustomAction_CombineApply";
81 constexpr StringLiteral CXXPredPrefix
= "GICXXPred_MI_Predicate_";
82 constexpr StringLiteral MIFlagsEnumClassName
= "MIFlagEnum";
84 //===- CodeExpansions Helpers --------------------------------------------===//
86 void declareInstExpansion(CodeExpansions
&CE
, const InstructionMatcher
&IM
,
88 CE
.declare(Name
, "State.MIs[" + to_string(IM
.getInsnVarID()) + "]");
91 void declareInstExpansion(CodeExpansions
&CE
, const BuildMIAction
&A
,
93 // Note: we use redeclare here because this may overwrite a matcher inst
95 CE
.redeclare(Name
, "OutMIs[" + to_string(A
.getInsnID()) + "]");
98 void declareOperandExpansion(CodeExpansions
&CE
, const OperandMatcher
&OM
,
100 CE
.declare(Name
, "State.MIs[" + to_string(OM
.getInsnVarID()) +
101 "]->getOperand(" + to_string(OM
.getOpIdx()) + ")");
104 void declareTempRegExpansion(CodeExpansions
&CE
, unsigned TempRegID
,
106 CE
.declare(Name
, "State.TempRegisters[" + to_string(TempRegID
) + "]");
109 //===- Misc. Helpers -----------------------------------------------------===//
111 /// Copies a StringRef into a static pool to preserve it.
112 /// Most Pattern classes use StringRef so we need this.
113 StringRef
insertStrRef(StringRef S
) {
117 static StringSet
<> Pool
;
118 auto [It
, Inserted
] = Pool
.insert(S
);
122 template <typename Container
> auto keys(Container
&&C
) {
123 return map_range(C
, [](auto &Entry
) -> auto & { return Entry
.first
; });
126 template <typename Container
> auto values(Container
&&C
) {
127 return map_range(C
, [](auto &Entry
) -> auto & { return Entry
.second
; });
130 std::string
getIsEnabledPredicateEnumName(unsigned CombinerRuleID
) {
131 return "GICXXPred_Simple_IsRule" + to_string(CombinerRuleID
) + "Enabled";
134 //===- MatchTable Helpers ------------------------------------------------===//
136 LLTCodeGen
getLLTCodeGen(const PatternType
&PT
) {
137 return *MVTToLLT(getValueType(PT
.getLLTRecord()));
140 LLTCodeGenOrTempType
getLLTCodeGenOrTempType(const PatternType
&PT
,
142 assert(!PT
.isNone());
145 return getLLTCodeGen(PT
);
147 assert(PT
.isTypeOf());
148 auto &OM
= RM
.getOperandMatcher(PT
.getTypeOfOpName());
149 return OM
.getTempTypeIdx(RM
);
152 //===- PrettyStackTrace Helpers ------------------------------------------===//
154 class PrettyStackTraceParse
: public PrettyStackTraceEntry
{
158 PrettyStackTraceParse(const Record
&Def
) : Def(Def
) {}
160 void print(raw_ostream
&OS
) const override
{
161 if (Def
.isSubClassOf("GICombineRule"))
162 OS
<< "Parsing GICombineRule '" << Def
.getName() << "'";
163 else if (Def
.isSubClassOf(PatFrag::ClassName
))
164 OS
<< "Parsing " << PatFrag::ClassName
<< " '" << Def
.getName() << "'";
166 OS
<< "Parsing '" << Def
.getName() << "'";
171 class PrettyStackTraceEmit
: public PrettyStackTraceEntry
{
173 const Pattern
*Pat
= nullptr;
176 PrettyStackTraceEmit(const Record
&Def
, const Pattern
*Pat
= nullptr)
177 : Def(Def
), Pat(Pat
) {}
179 void print(raw_ostream
&OS
) const override
{
180 if (Def
.isSubClassOf("GICombineRule"))
181 OS
<< "Emitting GICombineRule '" << Def
.getName() << "'";
182 else if (Def
.isSubClassOf(PatFrag::ClassName
))
183 OS
<< "Emitting " << PatFrag::ClassName
<< " '" << Def
.getName() << "'";
185 OS
<< "Emitting '" << Def
.getName() << "'";
188 OS
<< " [" << Pat
->getKindName() << " '" << Pat
->getName() << "']";
193 //===- CombineRuleOperandTypeChecker --------------------------------------===//
195 /// This is a wrapper around OperandTypeChecker specialized for Combiner Rules.
196 /// On top of doing the same things as OperandTypeChecker, this also attempts to
197 /// infer as many types as possible for temporary register defs & immediates in
200 /// The inference is trivial and leverages the MCOI OperandTypes encoded in
201 /// CodeGenInstructions to infer types across patterns in a CombineRule. It's
202 /// thus very limited and only supports CodeGenInstructions (but that's the main
203 /// use case so it's fine).
205 /// We only try to infer untyped operands in apply patterns when they're temp
206 /// reg defs, or immediates. Inference always outputs a `TypeOf<$x>` where $x is
207 /// a named operand from a match pattern.
208 class CombineRuleOperandTypeChecker
: private OperandTypeChecker
{
210 CombineRuleOperandTypeChecker(const Record
&RuleDef
,
211 const OperandTable
&MatchOpTable
)
212 : OperandTypeChecker(RuleDef
.getLoc()), RuleDef(RuleDef
),
213 MatchOpTable(MatchOpTable
) {}
215 /// Records and checks a 'match' pattern.
216 bool processMatchPattern(InstructionPattern
&P
);
218 /// Records and checks an 'apply' pattern.
219 bool processApplyPattern(InstructionPattern
&P
);
221 /// Propagates types, then perform type inference and do a second round of
222 /// propagation in the apply patterns only if any types were inferred.
223 void propagateAndInferTypes();
226 /// TypeEquivalenceClasses are groups of operands of an instruction that share
229 /// e.g. [[a, b], [c, d]] means a and b have the same type, and c and
230 /// d have the same type too. b/c and a/d don't have to have the same type,
232 using TypeEquivalenceClasses
= EquivalenceClasses
<StringRef
>;
234 /// \returns true for `OPERAND_GENERIC_` 0 through 5.
235 /// These are the MCOI types that can be registers. The other MCOI types are
236 /// either immediates, or fancier operands used only post-ISel, so we don't
237 /// care about them for combiners.
238 static bool canMCOIOperandTypeBeARegister(StringRef MCOIType
) {
239 // Assume OPERAND_GENERIC_0 through 5 can be registers. The other MCOI
240 // OperandTypes are either never used in gMIR, or not relevant (e.g.
241 // OPERAND_GENERIC_IMM, which is definitely never a register).
242 return MCOIType
.drop_back(1).ends_with("OPERAND_GENERIC_");
245 /// Finds the "MCOI::"" operand types for each operand of \p CGP.
247 /// This is a bit trickier than it looks because we need to handle variadic
251 /// (G_BUILD_VECTOR $vec, $x, $y) ->
252 /// [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
253 /// MCOI::OPERAND_GENERIC_1]
255 /// For unknown types (which can happen in variadics where varargs types are
256 /// inconsistent), a unique name is given, e.g. "unknown_type_0".
257 static std::vector
<std::string
>
258 getMCOIOperandTypes(const CodeGenInstructionPattern
&CGP
);
260 /// Adds the TypeEquivalenceClasses for \p P in \p OutTECs.
261 void getInstEqClasses(const InstructionPattern
&P
,
262 TypeEquivalenceClasses
&OutTECs
) const;
264 /// Calls `getInstEqClasses` on all patterns of the rule to produce the whole
265 /// rule's TypeEquivalenceClasses.
266 TypeEquivalenceClasses
getRuleEqClasses() const;
268 /// Tries to infer the type of the \p ImmOpIdx -th operand of \p IP using \p
271 /// This is achieved by trying to find a named operand in \p IP that shares
272 /// the same type as \p ImmOpIdx, and using \ref inferNamedOperandType on that
275 /// \returns the inferred type or an empty PatternType if inference didn't
277 PatternType
inferImmediateType(const InstructionPattern
&IP
,
279 const TypeEquivalenceClasses
&TECs
) const;
281 /// Looks inside \p TECs to infer \p OpName's type.
283 /// \returns the inferred type or an empty PatternType if inference didn't
285 PatternType
inferNamedOperandType(const InstructionPattern
&IP
,
287 const TypeEquivalenceClasses
&TECs
) const;
289 const Record
&RuleDef
;
290 SmallVector
<InstructionPattern
*, 8> MatchPats
;
291 SmallVector
<InstructionPattern
*, 8> ApplyPats
;
293 const OperandTable
&MatchOpTable
;
296 bool CombineRuleOperandTypeChecker::processMatchPattern(InstructionPattern
&P
) {
297 MatchPats
.push_back(&P
);
298 return check(P
, /*CheckTypeOf*/ [](const auto &) {
299 // GITypeOf in 'match' is currently always rejected by the
300 // CombineRuleBuilder after inference is done.
305 bool CombineRuleOperandTypeChecker::processApplyPattern(InstructionPattern
&P
) {
306 ApplyPats
.push_back(&P
);
307 return check(P
, /*CheckTypeOf*/ [&](const PatternType
&Ty
) {
308 // GITypeOf<"$x"> can only be used if "$x" is a matched operand.
309 const auto OpName
= Ty
.getTypeOfOpName();
310 if (MatchOpTable
.lookup(OpName
).Found
)
313 PrintError(RuleDef
.getLoc(), "'" + OpName
+ "' ('" + Ty
.str() +
314 "') does not refer to a matched operand!");
319 void CombineRuleOperandTypeChecker::propagateAndInferTypes() {
320 /// First step here is to propagate types using the OperandTypeChecker. That
321 /// way we ensure all uses of a given register have consistent types.
324 /// Build the TypeEquivalenceClasses for the whole rule.
325 const TypeEquivalenceClasses TECs
= getRuleEqClasses();
327 /// Look at the apply patterns and find operands that need to be
328 /// inferred. We then try to find an equivalence class that they're a part of
329 /// and select the best operand to use for the `GITypeOf` type. We prioritize
330 /// defs of matched instructions because those are guaranteed to be registers.
331 bool InferredAny
= false;
332 for (auto *Pat
: ApplyPats
) {
333 for (unsigned K
= 0; K
< Pat
->operands_size(); ++K
) {
334 auto &Op
= Pat
->getOperand(K
);
336 // We only want to take a look at untyped defs or immediates.
337 if ((!Op
.isDef() && !Op
.hasImmValue()) || Op
.getType())
340 // Infer defs & named immediates.
341 if (Op
.isDef() || Op
.isNamedImmediate()) {
342 // Check it's not a redefinition of a matched operand.
343 // In such cases, inference is not necessary because we just copy
344 // operands and don't create temporary registers.
345 if (MatchOpTable
.lookup(Op
.getOperandName()).Found
)
348 // Inference is needed here, so try to do it.
350 inferNamedOperandType(*Pat
, Op
.getOperandName(), TECs
)) {
352 errs() << "INFER: " << Op
.describe() << " -> " << Ty
.str() << '\n';
361 if (Op
.hasImmValue()) {
362 if (PatternType Ty
= inferImmediateType(*Pat
, K
, TECs
)) {
364 errs() << "INFER: " << Op
.describe() << " -> " << Ty
.str() << '\n';
373 // If we've inferred any types, we want to propagate them across the apply
374 // patterns. Type inference only adds GITypeOf types that point to Matched
375 // operands, so we definitely don't want to propagate types into the match
376 // patterns as well, otherwise bad things happen.
378 OperandTypeChecker
OTC(RuleDef
.getLoc());
379 for (auto *Pat
: ApplyPats
) {
380 if (!OTC
.check(*Pat
, [&](const auto &) { return true; }))
381 PrintFatalError(RuleDef
.getLoc(),
382 "OperandTypeChecker unexpectedly failed on '" +
383 Pat
->getName() + "' during Type Inference");
385 OTC
.propagateTypes();
387 if (DebugTypeInfer
) {
388 errs() << "Apply patterns for rule " << RuleDef
.getName()
389 << " after inference:\n";
390 for (auto *Pat
: ApplyPats
) {
392 Pat
->print(errs(), /*PrintName*/ true);
400 PatternType
CombineRuleOperandTypeChecker::inferImmediateType(
401 const InstructionPattern
&IP
, unsigned ImmOpIdx
,
402 const TypeEquivalenceClasses
&TECs
) const {
403 // We can only infer CGPs.
404 const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&IP
);
408 // For CGPs, we try to infer immediates by trying to infer another named
409 // operand that shares its type.
412 // Pattern: G_BUILD_VECTOR $x, $y, 0
413 // MCOIs: [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
414 // MCOI::OPERAND_GENERIC_1]
415 // $y has the same type as 0, so we can infer $y and get the type 0 should
418 // We infer immediates by looking for a named operand that shares the same
420 const auto MCOITypes
= getMCOIOperandTypes(*CGP
);
421 StringRef ImmOpTy
= MCOITypes
[ImmOpIdx
];
423 for (const auto &[Idx
, Ty
] : enumerate(MCOITypes
)) {
424 if (Idx
!= ImmOpIdx
&& Ty
== ImmOpTy
) {
425 const auto &Op
= IP
.getOperand(Idx
);
426 if (!Op
.isNamedOperand())
429 // Named operand with the same name, try to infer that.
430 if (PatternType InferTy
=
431 inferNamedOperandType(IP
, Op
.getOperandName(), TECs
))
439 PatternType
CombineRuleOperandTypeChecker::inferNamedOperandType(
440 const InstructionPattern
&IP
, StringRef OpName
,
441 const TypeEquivalenceClasses
&TECs
) const {
442 // This is the simplest possible case, we just need to find a TEC that
443 // contains OpName. Look at all other operands in equivalence class and try to
444 // find a suitable one.
446 // Check for a def of a matched pattern. This is guaranteed to always
447 // be a register so we can blindly use that.
448 StringRef GoodOpName
;
449 for (auto It
= TECs
.findLeader(OpName
); It
!= TECs
.member_end(); ++It
) {
453 const auto LookupRes
= MatchOpTable
.lookup(*It
);
454 if (LookupRes
.Def
) // Favor defs
455 return PatternType::getTypeOf(*It
);
457 // Otherwise just save this in case we don't find any def.
458 if (GoodOpName
.empty() && LookupRes
.Found
)
462 if (!GoodOpName
.empty())
463 return PatternType::getTypeOf(GoodOpName
);
465 // No good operand found, give up.
469 std::vector
<std::string
> CombineRuleOperandTypeChecker::getMCOIOperandTypes(
470 const CodeGenInstructionPattern
&CGP
) {
471 // FIXME?: Should we cache this? We call it twice when inferring immediates.
473 static unsigned UnknownTypeIdx
= 0;
475 std::vector
<std::string
> OpTypes
;
476 auto &CGI
= CGP
.getInst();
477 Record
*VarArgsTy
= CGI
.TheDef
->isSubClassOf("GenericInstruction")
478 ? CGI
.TheDef
->getValueAsOptionalDef("variadicOpsType")
480 std::string VarArgsTyName
=
481 VarArgsTy
? ("MCOI::" + VarArgsTy
->getValueAsString("OperandType")).str()
482 : ("unknown_type_" + Twine(UnknownTypeIdx
++)).str();
484 // First, handle defs.
485 for (unsigned K
= 0; K
< CGI
.Operands
.NumDefs
; ++K
)
486 OpTypes
.push_back(CGI
.Operands
[K
].OperandType
);
488 // Then, handle variadic defs if there are any.
489 if (CGP
.hasVariadicDefs()) {
490 for (unsigned K
= CGI
.Operands
.NumDefs
; K
< CGP
.getNumInstDefs(); ++K
)
491 OpTypes
.push_back(VarArgsTyName
);
494 // If we had variadic defs, the op idx in the pattern won't match the op idx
495 // in the CGI anymore.
496 int CGIOpOffset
= int(CGI
.Operands
.NumDefs
) - CGP
.getNumInstDefs();
497 assert(CGP
.hasVariadicDefs() ? (CGIOpOffset
<= 0) : (CGIOpOffset
== 0));
499 // Handle all remaining use operands, including variadic ones.
500 for (unsigned K
= CGP
.getNumInstDefs(); K
< CGP
.getNumInstOperands(); ++K
) {
501 unsigned CGIOpIdx
= K
+ CGIOpOffset
;
502 if (CGIOpIdx
>= CGI
.Operands
.size()) {
503 assert(CGP
.isVariadic());
504 OpTypes
.push_back(VarArgsTyName
);
506 OpTypes
.push_back(CGI
.Operands
[CGIOpIdx
].OperandType
);
510 assert(OpTypes
.size() == CGP
.operands_size());
514 void CombineRuleOperandTypeChecker::getInstEqClasses(
515 const InstructionPattern
&P
, TypeEquivalenceClasses
&OutTECs
) const {
516 // Determine the TypeEquivalenceClasses by:
517 // - Getting the MCOI Operand Types.
518 // - Creating a Map of MCOI Type -> [Operand Indexes]
519 // - Iterating over the map, filtering types we don't like, and just adding
520 // the array of Operand Indexes to \p OutTECs.
522 // We can only do this on CodeGenInstructions. Other InstructionPatterns have
523 // no type inference information associated with them.
524 // TODO: Could we add some inference information to builtins at least? e.g.
525 // ReplaceReg should always replace with a reg of the same type, for instance.
526 // Though, those patterns are often used alone so it might not be worth the
527 // trouble to infer their types.
528 auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&P
);
532 const auto MCOITypes
= getMCOIOperandTypes(*CGP
);
533 assert(MCOITypes
.size() == P
.operands_size());
535 DenseMap
<StringRef
, std::vector
<unsigned>> TyToOpIdx
;
536 for (const auto &[Idx
, Ty
] : enumerate(MCOITypes
))
537 TyToOpIdx
[Ty
].push_back(Idx
);
540 errs() << "\tGroups for " << P
.getName() << ":\t";
542 for (const auto &[Ty
, Idxs
] : TyToOpIdx
) {
543 if (!canMCOIOperandTypeBeARegister(Ty
))
550 // We only collect named operands.
552 for (unsigned Idx
: Idxs
) {
553 const auto &Op
= P
.getOperand(Idx
);
554 if (!Op
.isNamedOperand())
557 const auto OpName
= Op
.getOperandName();
558 if (DebugTypeInfer
) {
559 errs() << Sep
<< OpName
;
564 OutTECs
.insert((Leader
= OpName
));
566 OutTECs
.unionSets(Leader
, OpName
);
577 CombineRuleOperandTypeChecker::TypeEquivalenceClasses
578 CombineRuleOperandTypeChecker::getRuleEqClasses() const {
579 StringMap
<unsigned> OpNameToEqClassIdx
;
580 TypeEquivalenceClasses TECs
;
583 errs() << "Rule Operand Type Equivalence Classes for " << RuleDef
.getName()
586 for (const auto *Pat
: MatchPats
)
587 getInstEqClasses(*Pat
, TECs
);
588 for (const auto *Pat
: ApplyPats
)
589 getInstEqClasses(*Pat
, TECs
);
591 if (DebugTypeInfer
) {
592 errs() << "Final Type Equivalence Classes: ";
593 for (auto ClassIt
= TECs
.begin(); ClassIt
!= TECs
.end(); ++ClassIt
) {
594 // only print non-empty classes.
595 if (auto MembIt
= TECs
.member_begin(ClassIt
);
596 MembIt
!= TECs
.member_end()) {
599 for (; MembIt
!= TECs
.member_end(); ++MembIt
) {
600 errs() << Sep
<< *MembIt
;
612 //===- CombineRuleBuilder -------------------------------------------------===//
614 /// Parses combine rule and builds a small intermediate representation to tie
615 /// patterns together and emit RuleMatchers to match them. This may emit more
616 /// than one RuleMatcher, e.g. for `wip_match_opcode`.
618 /// Memory management for `Pattern` objects is done through `std::unique_ptr`.
619 /// In most cases, there are two stages to a pattern's lifetime:
620 /// - Creation in a `parse` function
621 /// - The unique_ptr is stored in a variable, and may be destroyed if the
622 /// pattern is found to be semantically invalid.
623 /// - Ownership transfer into a `PatternMap`
624 /// - Once a pattern is moved into either the map of Match or Apply
625 /// patterns, it is known to be valid and it never moves back.
626 class CombineRuleBuilder
{
628 using PatternMap
= MapVector
<StringRef
, std::unique_ptr
<Pattern
>>;
629 using PatternAlternatives
= DenseMap
<const Pattern
*, unsigned>;
631 CombineRuleBuilder(const CodeGenTarget
&CGT
,
632 SubtargetFeatureInfoMap
&SubtargetFeatures
,
633 Record
&RuleDef
, unsigned ID
,
634 std::vector
<RuleMatcher
> &OutRMs
)
635 : CGT(CGT
), SubtargetFeatures(SubtargetFeatures
), RuleDef(RuleDef
),
636 RuleID(ID
), OutRMs(OutRMs
) {}
638 /// Parses all fields in the RuleDef record.
641 /// Emits all RuleMatchers into the vector of RuleMatchers passed in the
643 bool emitRuleMatchers();
645 void print(raw_ostream
&OS
) const;
646 void dump() const { print(dbgs()); }
648 /// Debug-only verification of invariants.
654 const CodeGenInstruction
&getGConstant() const {
655 return CGT
.getInstruction(RuleDef
.getRecords().getDef("G_CONSTANT"));
658 void PrintError(Twine Msg
) const { ::PrintError(&RuleDef
, Msg
); }
659 void PrintWarning(Twine Msg
) const { ::PrintWarning(RuleDef
.getLoc(), Msg
); }
660 void PrintNote(Twine Msg
) const { ::PrintNote(RuleDef
.getLoc(), Msg
); }
662 void print(raw_ostream
&OS
, const PatternAlternatives
&Alts
) const;
664 bool addApplyPattern(std::unique_ptr
<Pattern
> Pat
);
665 bool addMatchPattern(std::unique_ptr
<Pattern
> Pat
);
667 /// Adds the expansions from \see MatchDatas to \p CE.
668 void declareAllMatchDatasExpansions(CodeExpansions
&CE
) const;
670 /// Adds a matcher \p P to \p IM, expanding its code using \p CE.
671 /// Note that the predicate is added on the last InstructionMatcher.
673 /// \p Alts is only used if DebugCXXPreds is enabled.
674 void addCXXPredicate(RuleMatcher
&M
, const CodeExpansions
&CE
,
675 const CXXPattern
&P
, const PatternAlternatives
&Alts
);
677 /// Adds an apply \p P to \p IM, expanding its code using \p CE.
678 void addCXXAction(RuleMatcher
&M
, const CodeExpansions
&CE
,
679 const CXXPattern
&P
);
681 bool hasOnlyCXXApplyPatterns() const;
682 bool hasEraseRoot() const;
684 // Infer machine operand types and check their consistency.
685 bool typecheckPatterns();
687 /// For all PatFragPatterns, add a new entry in PatternAlternatives for each
688 /// PatternList it contains. This is multiplicative, so if we have 2
689 /// PatFrags with 3 alternatives each, we get 2*3 permutations added to
690 /// PermutationsToEmit. The "MaxPermutations" field controls how many
691 /// permutations are allowed before an error is emitted and this function
692 /// returns false. This is a simple safeguard to prevent combination of
693 /// PatFrags from generating enormous amounts of rules.
694 bool buildPermutationsToEmit();
696 /// Checks additional semantics of the Patterns.
697 bool checkSemantics();
699 /// Creates a new RuleMatcher with some boilerplate
700 /// settings/actions/predicates, and and adds it to \p OutRMs.
701 /// \see addFeaturePredicates too.
703 /// \param Alts Current set of alternatives, for debug comment.
704 /// \param AdditionalComment Comment string to be added to the
705 /// `DebugCommentAction`.
706 RuleMatcher
&addRuleMatcher(const PatternAlternatives
&Alts
,
707 Twine AdditionalComment
= "");
708 bool addFeaturePredicates(RuleMatcher
&M
);
711 bool buildRuleOperandsTable();
713 bool parseDefs(const DagInit
&Def
);
715 parsePatternList(const DagInit
&List
,
716 function_ref
<bool(std::unique_ptr
<Pattern
>)> ParseAction
,
717 StringRef Operator
, ArrayRef
<SMLoc
> DiagLoc
,
718 StringRef AnonPatNamePrefix
) const;
720 std::unique_ptr
<Pattern
> parseInstructionPattern(const Init
&Arg
,
721 StringRef PatName
) const;
722 std::unique_ptr
<Pattern
> parseWipMatchOpcodeMatcher(const Init
&Arg
,
723 StringRef PatName
) const;
724 bool parseInstructionPatternOperand(InstructionPattern
&IP
,
726 const StringInit
*OpName
) const;
727 bool parseInstructionPatternMIFlags(InstructionPattern
&IP
,
728 const DagInit
*Op
) const;
729 std::unique_ptr
<PatFrag
> parsePatFragImpl(const Record
*Def
) const;
730 bool parsePatFragParamList(
731 ArrayRef
<SMLoc
> DiagLoc
, const DagInit
&OpsList
,
732 function_ref
<bool(StringRef
, PatFrag::ParamKind
)> ParseAction
) const;
733 const PatFrag
*parsePatFrag(const Record
*Def
) const;
735 bool emitMatchPattern(CodeExpansions
&CE
, const PatternAlternatives
&Alts
,
736 const InstructionPattern
&IP
);
737 bool emitMatchPattern(CodeExpansions
&CE
, const PatternAlternatives
&Alts
,
738 const AnyOpcodePattern
&AOP
);
740 bool emitPatFragMatchPattern(CodeExpansions
&CE
,
741 const PatternAlternatives
&Alts
, RuleMatcher
&RM
,
742 InstructionMatcher
*IM
,
743 const PatFragPattern
&PFP
,
744 DenseSet
<const Pattern
*> &SeenPats
);
746 bool emitApplyPatterns(CodeExpansions
&CE
, RuleMatcher
&M
);
748 // Recursively visits InstructionPatterns from P to build up the
749 // RuleMatcher actions.
750 bool emitInstructionApplyPattern(CodeExpansions
&CE
, RuleMatcher
&M
,
751 const InstructionPattern
&P
,
752 DenseSet
<const Pattern
*> &SeenPats
,
753 StringMap
<unsigned> &OperandToTempRegID
);
755 bool emitCodeGenInstructionApplyImmOperand(RuleMatcher
&M
,
756 BuildMIAction
&DstMI
,
757 const CodeGenInstructionPattern
&P
,
758 const InstructionOperand
&O
);
760 bool emitBuiltinApplyPattern(CodeExpansions
&CE
, RuleMatcher
&M
,
761 const BuiltinPattern
&P
,
762 StringMap
<unsigned> &OperandToTempRegID
);
764 // Recursively visits CodeGenInstructionPattern from P to build up the
765 // RuleMatcher/InstructionMatcher. May create new InstructionMatchers as
767 using OperandMapperFnRef
=
768 function_ref
<InstructionOperand(const InstructionOperand
&)>;
769 using OperandDefLookupFn
=
770 function_ref
<const InstructionPattern
*(StringRef
)>;
771 bool emitCodeGenInstructionMatchPattern(
772 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&M
,
773 InstructionMatcher
&IM
, const CodeGenInstructionPattern
&P
,
774 DenseSet
<const Pattern
*> &SeenPats
, OperandDefLookupFn LookupOperandDef
,
775 OperandMapperFnRef OperandMapper
= [](const auto &O
) { return O
; });
777 const CodeGenTarget
&CGT
;
778 SubtargetFeatureInfoMap
&SubtargetFeatures
;
780 const unsigned RuleID
;
781 std::vector
<RuleMatcher
> &OutRMs
;
783 // For InstructionMatcher::addOperand
784 unsigned AllocatedTemporariesBaseID
= 0;
786 /// The root of the pattern.
789 /// These maps have ownership of the actual Pattern objects.
790 /// They both map a Pattern's name to the Pattern instance.
791 PatternMap MatchPats
;
792 PatternMap ApplyPats
;
794 /// Operand tables to tie match/apply patterns together.
795 OperandTable MatchOpTable
;
796 OperandTable ApplyOpTable
;
798 /// Set by findRoots.
799 Pattern
*MatchRoot
= nullptr;
800 SmallDenseSet
<InstructionPattern
*, 2> ApplyRoots
;
802 SmallVector
<MatchDataInfo
, 2> MatchDatas
;
803 SmallVector
<PatternAlternatives
, 1> PermutationsToEmit
;
805 // print()/debug-only members.
806 mutable SmallPtrSet
<const PatFrag
*, 2> SeenPatFrags
;
809 bool CombineRuleBuilder::parseAll() {
810 auto StackTrace
= PrettyStackTraceParse(RuleDef
);
812 if (!parseDefs(*RuleDef
.getValueAsDag("Defs")))
815 if (!parsePatternList(
816 *RuleDef
.getValueAsDag("Match"),
817 [this](auto Pat
) { return addMatchPattern(std::move(Pat
)); }, "match",
818 RuleDef
.getLoc(), (RuleDef
.getName() + "_match").str()))
821 if (!parsePatternList(
822 *RuleDef
.getValueAsDag("Apply"),
823 [this](auto Pat
) { return addApplyPattern(std::move(Pat
)); }, "apply",
824 RuleDef
.getLoc(), (RuleDef
.getName() + "_apply").str()))
827 if (!buildRuleOperandsTable() || !typecheckPatterns() || !findRoots() ||
828 !checkSemantics() || !buildPermutationsToEmit())
830 LLVM_DEBUG(verify());
834 bool CombineRuleBuilder::emitRuleMatchers() {
835 auto StackTrace
= PrettyStackTraceEmit(RuleDef
);
839 declareAllMatchDatasExpansions(CE
);
841 assert(!PermutationsToEmit
.empty());
842 for (const auto &Alts
: PermutationsToEmit
) {
843 switch (MatchRoot
->getKind()) {
844 case Pattern::K_AnyOpcode
: {
845 if (!emitMatchPattern(CE
, Alts
, *cast
<AnyOpcodePattern
>(MatchRoot
)))
849 case Pattern::K_PatFrag
:
850 case Pattern::K_Builtin
:
851 case Pattern::K_CodeGenInstruction
:
852 if (!emitMatchPattern(CE
, Alts
, *cast
<InstructionPattern
>(MatchRoot
)))
856 PrintError("C++ code cannot be the root of a rule!");
859 llvm_unreachable("unknown pattern kind!");
866 void CombineRuleBuilder::print(raw_ostream
&OS
) const {
867 OS
<< "(CombineRule name:" << RuleDef
.getName() << " id:" << RuleID
868 << " root:" << RootName
<< '\n';
870 if (!MatchDatas
.empty()) {
871 OS
<< " (MatchDatas\n";
872 for (const auto &MD
: MatchDatas
) {
880 if (!SeenPatFrags
.empty()) {
881 OS
<< " (PatFrags\n";
882 for (const auto *PF
: SeenPatFrags
) {
883 PF
->print(OS
, /*Indent=*/" ");
889 const auto DumpPats
= [&](StringRef Name
, const PatternMap
&Pats
) {
890 OS
<< " (" << Name
<< " ";
897 for (const auto &[Name
, Pat
] : Pats
) {
899 if (Pat
.get() == MatchRoot
)
900 OS
<< "<match_root>";
901 if (isa
<InstructionPattern
>(Pat
.get()) &&
902 ApplyRoots
.contains(cast
<InstructionPattern
>(Pat
.get())))
903 OS
<< "<apply_root>";
905 Pat
->print(OS
, /*PrintName=*/false);
911 DumpPats("MatchPats", MatchPats
);
912 DumpPats("ApplyPats", ApplyPats
);
914 MatchOpTable
.print(OS
, "MatchPats", /*Indent*/ " ");
915 ApplyOpTable
.print(OS
, "ApplyPats", /*Indent*/ " ");
917 if (PermutationsToEmit
.size() > 1) {
918 OS
<< " (PermutationsToEmit\n";
919 for (const auto &Perm
: PermutationsToEmit
) {
931 void CombineRuleBuilder::verify() const {
932 const auto VerifyPats
= [&](const PatternMap
&Pats
) {
933 for (const auto &[Name
, Pat
] : Pats
) {
935 PrintFatalError("null pattern in pattern map!");
937 if (Name
!= Pat
->getName()) {
939 PrintFatalError("Pattern name mismatch! Map name: " + Name
+
940 ", Pat name: " + Pat
->getName());
943 // Sanity check: the map should point to the same data as the Pattern.
944 // Both strings are allocated in the pool using insertStrRef.
945 if (Name
.data() != Pat
->getName().data()) {
946 dbgs() << "Map StringRef: '" << Name
<< "' @ "
947 << (const void *)Name
.data() << '\n';
948 dbgs() << "Pat String: '" << Pat
->getName() << "' @ "
949 << (const void *)Pat
->getName().data() << '\n';
950 PrintFatalError("StringRef stored in the PatternMap is not referencing "
951 "the same string as its Pattern!");
956 VerifyPats(MatchPats
);
957 VerifyPats(ApplyPats
);
959 // Check there are no wip_match_opcode patterns in the "apply" patterns.
960 if (any_of(ApplyPats
,
961 [&](auto &E
) { return isa
<AnyOpcodePattern
>(E
.second
.get()); })) {
964 "illegal wip_match_opcode pattern in the 'apply' patterns!");
967 // Check there are no nullptrs in ApplyRoots.
968 if (ApplyRoots
.contains(nullptr)) {
970 "CombineRuleBuilder's ApplyRoots set contains a null pointer!");
975 void CombineRuleBuilder::print(raw_ostream
&OS
,
976 const PatternAlternatives
&Alts
) const {
977 SmallVector
<std::string
, 1> Strings(
978 map_range(Alts
, [](const auto &PatAndPerm
) {
979 return PatAndPerm
.first
->getName().str() + "[" +
980 to_string(PatAndPerm
.second
) + "]";
982 // Sort so output is deterministic for tests. Otherwise it's sorted by pointer
985 OS
<< "[" << join(Strings
, ", ") << "]";
988 bool CombineRuleBuilder::addApplyPattern(std::unique_ptr
<Pattern
> Pat
) {
989 StringRef Name
= Pat
->getName();
990 if (ApplyPats
.contains(Name
)) {
991 PrintError("'" + Name
+ "' apply pattern defined more than once!");
995 if (isa
<AnyOpcodePattern
>(Pat
.get())) {
996 PrintError("'" + Name
+
997 "': wip_match_opcode is not supported in apply patterns");
1001 if (isa
<PatFragPattern
>(Pat
.get())) {
1002 PrintError("'" + Name
+ "': using " + PatFrag::ClassName
+
1003 " is not supported in apply patterns");
1007 if (auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
.get()))
1008 CXXPat
->setIsApply();
1010 ApplyPats
[Name
] = std::move(Pat
);
1014 bool CombineRuleBuilder::addMatchPattern(std::unique_ptr
<Pattern
> Pat
) {
1015 StringRef Name
= Pat
->getName();
1016 if (MatchPats
.contains(Name
)) {
1017 PrintError("'" + Name
+ "' match pattern defined more than once!");
1021 // For now, none of the builtins can appear in 'match'.
1022 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(Pat
.get())) {
1023 PrintError("'" + BP
->getInstName() +
1024 "' cannot be used in a 'match' pattern");
1028 MatchPats
[Name
] = std::move(Pat
);
1032 void CombineRuleBuilder::declareAllMatchDatasExpansions(
1033 CodeExpansions
&CE
) const {
1034 for (const auto &MD
: MatchDatas
)
1035 CE
.declare(MD
.getPatternSymbol(), MD
.getQualifiedVariableName());
1038 void CombineRuleBuilder::addCXXPredicate(RuleMatcher
&M
,
1039 const CodeExpansions
&CE
,
1040 const CXXPattern
&P
,
1041 const PatternAlternatives
&Alts
) {
1042 // FIXME: Hack so C++ code is executed last. May not work for more complex
1044 auto &IM
= *std::prev(M
.insnmatchers().end());
1045 auto Loc
= RuleDef
.getLoc();
1046 const auto AddComment
= [&](raw_ostream
&OS
) {
1047 OS
<< "// Pattern Alternatives: ";
1051 const auto &ExpandedCode
=
1052 DebugCXXPreds
? P
.expandCode(CE
, Loc
, AddComment
) : P
.expandCode(CE
, Loc
);
1053 IM
->addPredicate
<GenericInstructionPredicateMatcher
>(
1054 ExpandedCode
.getEnumNameWithPrefix(CXXPredPrefix
));
1057 void CombineRuleBuilder::addCXXAction(RuleMatcher
&M
, const CodeExpansions
&CE
,
1058 const CXXPattern
&P
) {
1059 const auto &ExpandedCode
= P
.expandCode(CE
, RuleDef
.getLoc());
1060 M
.addAction
<CustomCXXAction
>(
1061 ExpandedCode
.getEnumNameWithPrefix(CXXApplyPrefix
));
1064 bool CombineRuleBuilder::hasOnlyCXXApplyPatterns() const {
1065 return all_of(ApplyPats
, [&](auto &Entry
) {
1066 return isa
<CXXPattern
>(Entry
.second
.get());
1070 bool CombineRuleBuilder::hasEraseRoot() const {
1071 return any_of(ApplyPats
, [&](auto &Entry
) {
1072 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(Entry
.second
.get()))
1073 return BP
->getBuiltinKind() == BI_EraseRoot
;
1078 bool CombineRuleBuilder::typecheckPatterns() {
1079 CombineRuleOperandTypeChecker
OTC(RuleDef
, MatchOpTable
);
1081 for (auto &Pat
: values(MatchPats
)) {
1082 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
1083 if (!OTC
.processMatchPattern(*IP
))
1088 for (auto &Pat
: values(ApplyPats
)) {
1089 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
1090 if (!OTC
.processApplyPattern(*IP
))
1095 OTC
.propagateAndInferTypes();
1097 // Always check this after in case inference adds some special types to the
1099 for (auto &Pat
: values(MatchPats
)) {
1100 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
1101 if (IP
->diagnoseAllSpecialTypes(
1102 RuleDef
.getLoc(), PatternType::SpecialTyClassName
+
1103 " is not supported in 'match' patterns")) {
1111 bool CombineRuleBuilder::buildPermutationsToEmit() {
1112 PermutationsToEmit
.clear();
1114 // Start with one empty set of alternatives.
1115 PermutationsToEmit
.emplace_back();
1116 for (const auto &Pat
: values(MatchPats
)) {
1117 unsigned NumAlts
= 0;
1118 // Note: technically, AnyOpcodePattern also needs permutations, but:
1119 // - We only allow a single one of them in the root.
1120 // - They cannot be mixed with any other pattern other than C++ code.
1121 // So we don't really need to take them into account here. We could, but
1122 // that pattern is a hack anyway and the less it's involved, the better.
1123 if (const auto *PFP
= dyn_cast
<PatFragPattern
>(Pat
.get()))
1124 NumAlts
= PFP
->getPatFrag().num_alternatives();
1128 // For each pattern that needs permutations, multiply the current set of
1130 auto CurPerms
= PermutationsToEmit
;
1131 PermutationsToEmit
.clear();
1133 for (const auto &Perm
: CurPerms
) {
1134 assert(!Perm
.count(Pat
.get()) && "Pattern already emitted?");
1135 for (unsigned K
= 0; K
< NumAlts
; ++K
) {
1136 PatternAlternatives NewPerm
= Perm
;
1137 NewPerm
[Pat
.get()] = K
;
1138 PermutationsToEmit
.emplace_back(std::move(NewPerm
));
1143 if (int64_t MaxPerms
= RuleDef
.getValueAsInt("MaxPermutations");
1145 if ((int64_t)PermutationsToEmit
.size() > MaxPerms
) {
1146 PrintError("cannot emit rule '" + RuleDef
.getName() + "'; " +
1147 Twine(PermutationsToEmit
.size()) +
1148 " permutations would be emitted, but the max is " +
1154 // Ensure we always have a single empty entry, it simplifies the emission
1155 // logic so it doesn't need to handle the case where there are no perms.
1156 if (PermutationsToEmit
.empty()) {
1157 PermutationsToEmit
.emplace_back();
1164 bool CombineRuleBuilder::checkSemantics() {
1165 assert(MatchRoot
&& "Cannot call this before findRoots()");
1167 bool UsesWipMatchOpcode
= false;
1168 for (const auto &Match
: MatchPats
) {
1169 const auto *Pat
= Match
.second
.get();
1171 if (const auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
)) {
1172 if (!CXXPat
->getRawCode().contains("return "))
1173 PrintWarning("'match' C++ code does not seem to return!");
1177 // MIFlags in match cannot use the following syntax: (MIFlags $mi)
1178 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(Pat
)) {
1179 if (auto *FI
= CGP
->getMIFlagsInfo()) {
1180 if (!FI
->copy_flags().empty()) {
1182 "'match' patterns cannot refer to flags from other instructions");
1183 PrintNote("MIFlags in '" + CGP
->getName() +
1184 "' refer to: " + join(FI
->copy_flags(), ", "));
1190 const auto *AOP
= dyn_cast
<AnyOpcodePattern
>(Pat
);
1194 if (UsesWipMatchOpcode
) {
1195 PrintError("wip_opcode_match can only be present once");
1199 UsesWipMatchOpcode
= true;
1202 for (const auto &Apply
: ApplyPats
) {
1203 assert(Apply
.second
.get());
1204 const auto *IP
= dyn_cast
<InstructionPattern
>(Apply
.second
.get());
1208 if (UsesWipMatchOpcode
) {
1209 PrintError("cannot use wip_match_opcode in combination with apply "
1210 "instruction patterns!");
1214 // Check that the insts mentioned in copy_flags exist.
1215 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(IP
)) {
1216 if (auto *FI
= CGP
->getMIFlagsInfo()) {
1217 for (auto InstName
: FI
->copy_flags()) {
1218 auto It
= MatchPats
.find(InstName
);
1219 if (It
== MatchPats
.end()) {
1220 PrintError("unknown instruction '$" + InstName
+
1221 "' referenced in MIFlags of '" + CGP
->getName() + "'");
1225 if (!isa
<CodeGenInstructionPattern
>(It
->second
.get())) {
1228 "' does not refer to a CodeGenInstruction in MIFlags of '" +
1229 CGP
->getName() + "'");
1236 const auto *BIP
= dyn_cast
<BuiltinPattern
>(IP
);
1239 StringRef Name
= BIP
->getInstName();
1241 // (GIEraseInst) has to be the only apply pattern, or it can not be used at
1242 // all. The root cannot have any defs either.
1243 switch (BIP
->getBuiltinKind()) {
1244 case BI_EraseRoot
: {
1245 if (ApplyPats
.size() > 1) {
1246 PrintError(Name
+ " must be the only 'apply' pattern");
1250 const auto *IRoot
= dyn_cast
<CodeGenInstructionPattern
>(MatchRoot
);
1253 " can only be used if the root is a CodeGenInstruction");
1257 if (IRoot
->getNumInstDefs() != 0) {
1258 PrintError(Name
+ " can only be used if on roots that do "
1259 "not have any output operand");
1260 PrintNote("'" + IRoot
->getInstName() + "' has " +
1261 Twine(IRoot
->getNumInstDefs()) + " output operands");
1266 case BI_ReplaceReg
: {
1267 // (GIReplaceReg can only be used on the root instruction)
1268 // TODO: When we allow rewriting non-root instructions, also allow this.
1269 StringRef OldRegName
= BIP
->getOperand(0).getOperandName();
1270 auto *Def
= MatchOpTable
.getDef(OldRegName
);
1272 PrintError(Name
+ " cannot find a matched pattern that defines '" +
1276 if (MatchOpTable
.getDef(OldRegName
) != MatchRoot
) {
1277 PrintError(Name
+ " cannot replace '" + OldRegName
+
1278 "': this builtin can only replace a register defined by the "
1290 RuleMatcher
&CombineRuleBuilder::addRuleMatcher(const PatternAlternatives
&Alts
,
1291 Twine AdditionalComment
) {
1292 auto &RM
= OutRMs
.emplace_back(RuleDef
.getLoc());
1293 addFeaturePredicates(RM
);
1294 RM
.setPermanentGISelFlags(GISF_IgnoreCopies
);
1295 RM
.addRequiredSimplePredicate(getIsEnabledPredicateEnumName(RuleID
));
1297 std::string Comment
;
1298 raw_string_ostream
CommentOS(Comment
);
1299 CommentOS
<< "Combiner Rule #" << RuleID
<< ": " << RuleDef
.getName();
1300 if (!Alts
.empty()) {
1302 print(CommentOS
, Alts
);
1304 if (!AdditionalComment
.isTriviallyEmpty())
1305 CommentOS
<< "; " << AdditionalComment
;
1306 RM
.addAction
<DebugCommentAction
>(Comment
);
1310 bool CombineRuleBuilder::addFeaturePredicates(RuleMatcher
&M
) {
1311 if (!RuleDef
.getValue("Predicates"))
1314 ListInit
*Preds
= RuleDef
.getValueAsListInit("Predicates");
1315 for (Init
*PI
: Preds
->getValues()) {
1316 DefInit
*Pred
= dyn_cast
<DefInit
>(PI
);
1320 Record
*Def
= Pred
->getDef();
1321 if (!Def
->isSubClassOf("Predicate")) {
1322 ::PrintError(Def
, "Unknown 'Predicate' Type");
1326 if (Def
->getValueAsString("CondString").empty())
1329 if (SubtargetFeatures
.count(Def
) == 0) {
1330 SubtargetFeatures
.emplace(
1331 Def
, SubtargetFeatureInfo(Def
, SubtargetFeatures
.size()));
1334 M
.addRequiredFeature(Def
);
1340 bool CombineRuleBuilder::findRoots() {
1341 const auto Finish
= [&]() {
1344 if (hasOnlyCXXApplyPatterns() || hasEraseRoot())
1347 auto *IPRoot
= dyn_cast
<InstructionPattern
>(MatchRoot
);
1351 if (IPRoot
->getNumInstDefs() == 0) {
1352 // No defs to work with -> find the root using the pattern name.
1353 auto It
= ApplyPats
.find(RootName
);
1354 if (It
== ApplyPats
.end()) {
1355 PrintError("Cannot find root '" + RootName
+ "' in apply patterns!");
1359 auto *ApplyRoot
= dyn_cast
<InstructionPattern
>(It
->second
.get());
1361 PrintError("apply pattern root '" + RootName
+
1362 "' must be an instruction pattern");
1366 ApplyRoots
.insert(ApplyRoot
);
1370 // Collect all redefinitions of the MatchRoot's defs and put them in
1372 const auto DefsNeeded
= IPRoot
->getApplyDefsNeeded();
1373 for (auto &Op
: DefsNeeded
) {
1374 assert(Op
.isDef() && Op
.isNamedOperand());
1375 StringRef Name
= Op
.getOperandName();
1377 auto *ApplyRedef
= ApplyOpTable
.getDef(Name
);
1379 PrintError("'" + Name
+ "' must be redefined in the 'apply' pattern");
1383 ApplyRoots
.insert((InstructionPattern
*)ApplyRedef
);
1386 if (auto It
= ApplyPats
.find(RootName
); It
!= ApplyPats
.end()) {
1387 if (find(ApplyRoots
, It
->second
.get()) == ApplyRoots
.end()) {
1388 PrintError("apply pattern '" + RootName
+
1389 "' is supposed to be a root but it does not redefine any of "
1390 "the defs of the match root");
1398 // Look by pattern name, e.g.
1399 // (G_FNEG $x, $y):$root
1400 if (auto MatchPatIt
= MatchPats
.find(RootName
);
1401 MatchPatIt
!= MatchPats
.end()) {
1402 MatchRoot
= MatchPatIt
->second
.get();
1407 // (G_FNEG $root, $y)
1408 auto LookupRes
= MatchOpTable
.lookup(RootName
);
1409 if (!LookupRes
.Found
) {
1410 PrintError("Cannot find root '" + RootName
+ "' in match patterns!");
1414 MatchRoot
= LookupRes
.Def
;
1416 PrintError("Cannot use live-in operand '" + RootName
+
1417 "' as match pattern root!");
1424 bool CombineRuleBuilder::buildRuleOperandsTable() {
1425 const auto DiagnoseRedefMatch
= [&](StringRef OpName
) {
1426 PrintError("Operand '" + OpName
+
1427 "' is defined multiple times in the 'match' patterns");
1430 const auto DiagnoseRedefApply
= [&](StringRef OpName
) {
1431 PrintError("Operand '" + OpName
+
1432 "' is defined multiple times in the 'apply' patterns");
1435 for (auto &Pat
: values(MatchPats
)) {
1436 auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get());
1437 if (IP
&& !MatchOpTable
.addPattern(IP
, DiagnoseRedefMatch
))
1441 for (auto &Pat
: values(ApplyPats
)) {
1442 auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get());
1443 if (IP
&& !ApplyOpTable
.addPattern(IP
, DiagnoseRedefApply
))
1450 bool CombineRuleBuilder::parseDefs(const DagInit
&Def
) {
1451 if (Def
.getOperatorAsDef(RuleDef
.getLoc())->getName() != "defs") {
1452 PrintError("Expected defs operator");
1456 SmallVector
<StringRef
> Roots
;
1457 for (unsigned I
= 0, E
= Def
.getNumArgs(); I
< E
; ++I
) {
1458 if (isSpecificDef(*Def
.getArg(I
), "root")) {
1459 Roots
.emplace_back(Def
.getArgNameStr(I
));
1463 // Subclasses of GIDefMatchData should declare that this rule needs to pass
1464 // data from the match stage to the apply stage, and ensure that the
1465 // generated matcher has a suitable variable for it to do so.
1466 if (Record
*MatchDataRec
=
1467 getDefOfSubClass(*Def
.getArg(I
), "GIDefMatchData")) {
1468 MatchDatas
.emplace_back(Def
.getArgNameStr(I
),
1469 MatchDataRec
->getValueAsString("Type"));
1473 // Otherwise emit an appropriate error message.
1474 if (getDefOfSubClass(*Def
.getArg(I
), "GIDefKind"))
1475 PrintError("This GIDefKind not implemented in tablegen");
1476 else if (getDefOfSubClass(*Def
.getArg(I
), "GIDefKindWithArgs"))
1477 PrintError("This GIDefKindWithArgs not implemented in tablegen");
1479 PrintError("Expected a subclass of GIDefKind or a sub-dag whose "
1480 "operator is of type GIDefKindWithArgs");
1484 if (Roots
.size() != 1) {
1485 PrintError("Combine rules must have exactly one root");
1489 RootName
= Roots
.front();
1491 // Assign variables to all MatchDatas.
1492 AssignMatchDataVariables(MatchDatas
);
1496 bool CombineRuleBuilder::parsePatternList(
1497 const DagInit
&List
,
1498 function_ref
<bool(std::unique_ptr
<Pattern
>)> ParseAction
,
1499 StringRef Operator
, ArrayRef
<SMLoc
> DiagLoc
,
1500 StringRef AnonPatNamePrefix
) const {
1501 if (List
.getOperatorAsDef(RuleDef
.getLoc())->getName() != Operator
) {
1502 ::PrintError(DiagLoc
, "Expected " + Operator
+ " operator");
1506 if (List
.getNumArgs() == 0) {
1507 ::PrintError(DiagLoc
, Operator
+ " pattern list is empty");
1511 // The match section consists of a list of matchers and predicates. Parse each
1512 // one and add the equivalent GIMatchDag nodes, predicates, and edges.
1513 for (unsigned I
= 0; I
< List
.getNumArgs(); ++I
) {
1514 Init
*Arg
= List
.getArg(I
);
1515 std::string Name
= List
.getArgName(I
)
1516 ? List
.getArgName(I
)->getValue().str()
1517 : ("__" + AnonPatNamePrefix
+ "_" + Twine(I
)).str();
1519 if (auto Pat
= parseInstructionPattern(*Arg
, Name
)) {
1520 if (!ParseAction(std::move(Pat
)))
1525 if (auto Pat
= parseWipMatchOpcodeMatcher(*Arg
, Name
)) {
1526 if (!ParseAction(std::move(Pat
)))
1531 // Parse arbitrary C++ code
1532 if (const auto *StringI
= dyn_cast
<StringInit
>(Arg
)) {
1533 auto CXXPat
= std::make_unique
<CXXPattern
>(*StringI
, insertStrRef(Name
));
1534 if (!ParseAction(std::move(CXXPat
)))
1539 ::PrintError(DiagLoc
,
1540 "Failed to parse pattern: '" + Arg
->getAsString() + "'");
1547 std::unique_ptr
<Pattern
>
1548 CombineRuleBuilder::parseInstructionPattern(const Init
&Arg
,
1549 StringRef Name
) const {
1550 const DagInit
*DagPat
= dyn_cast
<DagInit
>(&Arg
);
1554 std::unique_ptr
<InstructionPattern
> Pat
;
1555 if (const DagInit
*IP
= getDagWithOperatorOfSubClass(Arg
, "Instruction")) {
1556 auto &Instr
= CGT
.getInstruction(IP
->getOperatorAsDef(RuleDef
.getLoc()));
1558 std::make_unique
<CodeGenInstructionPattern
>(Instr
, insertStrRef(Name
));
1559 } else if (const DagInit
*PFP
=
1560 getDagWithOperatorOfSubClass(Arg
, PatFrag::ClassName
)) {
1561 const Record
*Def
= PFP
->getOperatorAsDef(RuleDef
.getLoc());
1562 const PatFrag
*PF
= parsePatFrag(Def
);
1564 return nullptr; // Already diagnosed by parsePatFrag
1565 Pat
= std::make_unique
<PatFragPattern
>(*PF
, insertStrRef(Name
));
1566 } else if (const DagInit
*BP
=
1567 getDagWithOperatorOfSubClass(Arg
, BuiltinPattern::ClassName
)) {
1568 Pat
= std::make_unique
<BuiltinPattern
>(
1569 *BP
->getOperatorAsDef(RuleDef
.getLoc()), insertStrRef(Name
));
1574 for (unsigned K
= 0; K
< DagPat
->getNumArgs(); ++K
) {
1575 Init
*Arg
= DagPat
->getArg(K
);
1576 if (auto *DagArg
= getDagWithSpecificOperator(*Arg
, "MIFlags")) {
1577 if (!parseInstructionPatternMIFlags(*Pat
, DagArg
))
1582 if (!parseInstructionPatternOperand(*Pat
, Arg
, DagPat
->getArgName(K
)))
1586 if (!Pat
->checkSemantics(RuleDef
.getLoc()))
1589 return std::move(Pat
);
1592 std::unique_ptr
<Pattern
>
1593 CombineRuleBuilder::parseWipMatchOpcodeMatcher(const Init
&Arg
,
1594 StringRef Name
) const {
1595 const DagInit
*Matcher
= getDagWithSpecificOperator(Arg
, "wip_match_opcode");
1599 if (Matcher
->getNumArgs() == 0) {
1600 PrintError("Empty wip_match_opcode");
1604 // Each argument is an opcode that can match.
1605 auto Result
= std::make_unique
<AnyOpcodePattern
>(insertStrRef(Name
));
1606 for (const auto &Arg
: Matcher
->getArgs()) {
1607 Record
*OpcodeDef
= getDefOfSubClass(*Arg
, "Instruction");
1609 Result
->addOpcode(&CGT
.getInstruction(OpcodeDef
));
1613 PrintError("Arguments to wip_match_opcode must be instructions");
1617 return std::move(Result
);
1620 bool CombineRuleBuilder::parseInstructionPatternOperand(
1621 InstructionPattern
&IP
, const Init
*OpInit
,
1622 const StringInit
*OpName
) const {
1623 const auto ParseErr
= [&]() {
1624 PrintError("cannot parse operand '" + OpInit
->getAsUnquotedString() + "' ");
1626 PrintNote("operand name is '" + OpName
->getAsUnquotedString() + "'");
1630 // untyped immediate, e.g. 0
1631 if (const auto *IntImm
= dyn_cast
<IntInit
>(OpInit
)) {
1632 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
1633 IP
.addOperand(IntImm
->getValue(), insertStrRef(Name
), PatternType());
1637 // typed immediate, e.g. (i32 0)
1638 if (const auto *DagOp
= dyn_cast
<DagInit
>(OpInit
)) {
1639 if (DagOp
->getNumArgs() != 1)
1642 const Record
*TyDef
= DagOp
->getOperatorAsDef(RuleDef
.getLoc());
1643 auto ImmTy
= PatternType::get(RuleDef
.getLoc(), TyDef
,
1644 "cannot parse immediate '" +
1645 DagOp
->getAsUnquotedString() + "'");
1649 if (!IP
.hasAllDefs()) {
1650 PrintError("out operand of '" + IP
.getInstName() +
1651 "' cannot be an immediate");
1655 const auto *Val
= dyn_cast
<IntInit
>(DagOp
->getArg(0));
1659 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
1660 IP
.addOperand(Val
->getValue(), insertStrRef(Name
), *ImmTy
);
1664 // Typed operand e.g. $x/$z in (G_FNEG $x, $z)
1665 if (auto *DefI
= dyn_cast
<DefInit
>(OpInit
)) {
1667 PrintError("expected an operand name after '" + OpInit
->getAsString() +
1671 const Record
*Def
= DefI
->getDef();
1673 PatternType::get(RuleDef
.getLoc(), Def
, "cannot parse operand type");
1676 IP
.addOperand(insertStrRef(OpName
->getAsUnquotedString()), *Ty
);
1680 // Untyped operand e.g. $x/$z in (G_FNEG $x, $z)
1681 if (isa
<UnsetInit
>(OpInit
)) {
1682 assert(OpName
&& "Unset w/ no OpName?");
1683 IP
.addOperand(insertStrRef(OpName
->getAsUnquotedString()), PatternType());
1690 bool CombineRuleBuilder::parseInstructionPatternMIFlags(
1691 InstructionPattern
&IP
, const DagInit
*Op
) const {
1692 auto *CGIP
= dyn_cast
<CodeGenInstructionPattern
>(&IP
);
1694 PrintError("matching/writing MIFlags is only allowed on CodeGenInstruction "
1699 const auto CheckFlagEnum
= [&](const Record
*R
) {
1700 if (!R
->isSubClassOf(MIFlagsEnumClassName
)) {
1701 PrintError("'" + R
->getName() + "' is not a subclass of '" +
1702 MIFlagsEnumClassName
+ "'");
1709 if (CGIP
->getMIFlagsInfo()) {
1710 PrintError("MIFlags can only be present once on an instruction");
1714 auto &FI
= CGIP
->getOrCreateMIFlagsInfo();
1715 for (unsigned K
= 0; K
< Op
->getNumArgs(); ++K
) {
1716 const Init
*Arg
= Op
->getArg(K
);
1718 // Match/set a flag: (MIFlags FmNoNans)
1719 if (const auto *Def
= dyn_cast
<DefInit
>(Arg
)) {
1720 const Record
*R
= Def
->getDef();
1721 if (!CheckFlagEnum(R
))
1728 // Do not match a flag/unset a flag: (MIFlags (not FmNoNans))
1729 if (const DagInit
*NotDag
= getDagWithSpecificOperator(*Arg
, "not")) {
1730 for (const Init
*NotArg
: NotDag
->getArgs()) {
1731 const DefInit
*DefArg
= dyn_cast
<DefInit
>(NotArg
);
1733 PrintError("cannot parse '" + NotArg
->getAsUnquotedString() +
1734 "': expected a '" + MIFlagsEnumClassName
+ "'");
1738 const Record
*R
= DefArg
->getDef();
1739 if (!CheckFlagEnum(R
))
1749 // Copy flags from a matched instruction: (MIFlags $mi)
1750 if (isa
<UnsetInit
>(Arg
)) {
1751 FI
.addCopyFlag(insertStrRef(Op
->getArgName(K
)->getAsUnquotedString()));
1759 std::unique_ptr
<PatFrag
>
1760 CombineRuleBuilder::parsePatFragImpl(const Record
*Def
) const {
1761 auto StackTrace
= PrettyStackTraceParse(*Def
);
1762 if (!Def
->isSubClassOf(PatFrag::ClassName
))
1765 const DagInit
*Ins
= Def
->getValueAsDag("InOperands");
1766 if (Ins
->getOperatorAsDef(Def
->getLoc())->getName() != "ins") {
1767 ::PrintError(Def
, "expected 'ins' operator for " + PatFrag::ClassName
+
1768 " in operands list");
1772 const DagInit
*Outs
= Def
->getValueAsDag("OutOperands");
1773 if (Outs
->getOperatorAsDef(Def
->getLoc())->getName() != "outs") {
1774 ::PrintError(Def
, "expected 'outs' operator for " + PatFrag::ClassName
+
1775 " out operands list");
1779 auto Result
= std::make_unique
<PatFrag
>(*Def
);
1780 if (!parsePatFragParamList(Def
->getLoc(), *Outs
,
1781 [&](StringRef Name
, PatFrag::ParamKind Kind
) {
1782 Result
->addOutParam(insertStrRef(Name
), Kind
);
1787 if (!parsePatFragParamList(Def
->getLoc(), *Ins
,
1788 [&](StringRef Name
, PatFrag::ParamKind Kind
) {
1789 Result
->addInParam(insertStrRef(Name
), Kind
);
1794 const ListInit
*Alts
= Def
->getValueAsListInit("Alternatives");
1795 unsigned AltIdx
= 0;
1796 for (const Init
*Alt
: *Alts
) {
1797 const auto *PatDag
= dyn_cast
<DagInit
>(Alt
);
1799 ::PrintError(Def
, "expected dag init for PatFrag pattern alternative");
1803 PatFrag::Alternative
&A
= Result
->addAlternative();
1804 const auto AddPat
= [&](std::unique_ptr
<Pattern
> Pat
) {
1805 A
.Pats
.push_back(std::move(Pat
));
1809 if (!parsePatternList(
1810 *PatDag
, AddPat
, "pattern", Def
->getLoc(),
1812 (Def
->getName() + "_alt" + Twine(AltIdx
++) + "_pattern").str()))
1816 if (!Result
->buildOperandsTables() || !Result
->checkSemantics())
1822 bool CombineRuleBuilder::parsePatFragParamList(
1823 ArrayRef
<SMLoc
> DiagLoc
, const DagInit
&OpsList
,
1824 function_ref
<bool(StringRef
, PatFrag::ParamKind
)> ParseAction
) const {
1825 for (unsigned K
= 0; K
< OpsList
.getNumArgs(); ++K
) {
1826 const StringInit
*Name
= OpsList
.getArgName(K
);
1827 const Init
*Ty
= OpsList
.getArg(K
);
1830 ::PrintError(DiagLoc
, "all operands must be named'");
1833 const std::string NameStr
= Name
->getAsUnquotedString();
1835 PatFrag::ParamKind OpKind
;
1836 if (isSpecificDef(*Ty
, "gi_imm"))
1837 OpKind
= PatFrag::PK_Imm
;
1838 else if (isSpecificDef(*Ty
, "root"))
1839 OpKind
= PatFrag::PK_Root
;
1840 else if (isa
<UnsetInit
>(Ty
) ||
1841 isSpecificDef(*Ty
, "gi_mo")) // no type = gi_mo.
1842 OpKind
= PatFrag::PK_MachineOperand
;
1847 "' operand type was expected to be 'root', 'gi_imm' or 'gi_mo'");
1851 if (!ParseAction(NameStr
, OpKind
))
1858 const PatFrag
*CombineRuleBuilder::parsePatFrag(const Record
*Def
) const {
1859 // Cache already parsed PatFrags to avoid doing extra work.
1860 static DenseMap
<const Record
*, std::unique_ptr
<PatFrag
>> ParsedPatFrags
;
1862 auto It
= ParsedPatFrags
.find(Def
);
1863 if (It
!= ParsedPatFrags
.end()) {
1864 SeenPatFrags
.insert(It
->second
.get());
1865 return It
->second
.get();
1868 std::unique_ptr
<PatFrag
> NewPatFrag
= parsePatFragImpl(Def
);
1870 ::PrintError(Def
, "Could not parse " + PatFrag::ClassName
+ " '" +
1871 Def
->getName() + "'");
1872 // Put a nullptr in the map so we don't attempt parsing this again.
1873 ParsedPatFrags
[Def
] = nullptr;
1877 const auto *Res
= NewPatFrag
.get();
1878 ParsedPatFrags
[Def
] = std::move(NewPatFrag
);
1879 SeenPatFrags
.insert(Res
);
1883 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions
&CE
,
1884 const PatternAlternatives
&Alts
,
1885 const InstructionPattern
&IP
) {
1886 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &IP
);
1888 auto &M
= addRuleMatcher(Alts
);
1889 InstructionMatcher
&IM
= M
.addInstructionMatcher(IP
.getName());
1890 declareInstExpansion(CE
, IM
, IP
.getName());
1892 DenseSet
<const Pattern
*> SeenPats
;
1894 const auto FindOperandDef
= [&](StringRef Op
) -> InstructionPattern
* {
1895 return MatchOpTable
.getDef(Op
);
1898 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&IP
)) {
1899 if (!emitCodeGenInstructionMatchPattern(CE
, Alts
, M
, IM
, *CGP
, SeenPats
,
1902 } else if (const auto *PFP
= dyn_cast
<PatFragPattern
>(&IP
)) {
1903 if (!PFP
->getPatFrag().canBeMatchRoot()) {
1904 PrintError("cannot use '" + PFP
->getInstName() + " as match root");
1908 if (!emitPatFragMatchPattern(CE
, Alts
, M
, &IM
, *PFP
, SeenPats
))
1910 } else if (isa
<BuiltinPattern
>(&IP
)) {
1911 llvm_unreachable("No match builtins known!");
1913 llvm_unreachable("Unknown kind of InstructionPattern!");
1915 // Emit remaining patterns
1916 for (auto &Pat
: values(MatchPats
)) {
1917 if (SeenPats
.contains(Pat
.get()))
1920 switch (Pat
->getKind()) {
1921 case Pattern::K_AnyOpcode
:
1922 PrintError("wip_match_opcode can not be used with instruction patterns!");
1924 case Pattern::K_PatFrag
: {
1925 if (!emitPatFragMatchPattern(CE
, Alts
, M
, /*IM*/ nullptr,
1926 *cast
<PatFragPattern
>(Pat
.get()), SeenPats
))
1930 case Pattern::K_Builtin
:
1931 PrintError("No known match builtins");
1933 case Pattern::K_CodeGenInstruction
:
1934 cast
<InstructionPattern
>(Pat
.get())->reportUnreachable(RuleDef
.getLoc());
1936 case Pattern::K_CXX
: {
1937 addCXXPredicate(M
, CE
, *cast
<CXXPattern
>(Pat
.get()), Alts
);
1941 llvm_unreachable("unknown pattern kind!");
1945 return emitApplyPatterns(CE
, M
);
1948 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions
&CE
,
1949 const PatternAlternatives
&Alts
,
1950 const AnyOpcodePattern
&AOP
) {
1951 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &AOP
);
1953 for (const CodeGenInstruction
*CGI
: AOP
.insts()) {
1954 auto &M
= addRuleMatcher(Alts
, "wip_match_opcode '" +
1955 CGI
->TheDef
->getName() + "'");
1957 InstructionMatcher
&IM
= M
.addInstructionMatcher(AOP
.getName());
1958 declareInstExpansion(CE
, IM
, AOP
.getName());
1959 // declareInstExpansion needs to be identical, otherwise we need to create a
1960 // CodeExpansions object here instead.
1961 assert(IM
.getInsnVarID() == 0);
1963 IM
.addPredicate
<InstructionOpcodeMatcher
>(CGI
);
1965 // Emit remaining patterns.
1966 for (auto &Pat
: values(MatchPats
)) {
1967 if (Pat
.get() == &AOP
)
1970 switch (Pat
->getKind()) {
1971 case Pattern::K_AnyOpcode
:
1972 PrintError("wip_match_opcode can only be present once!");
1974 case Pattern::K_PatFrag
: {
1975 DenseSet
<const Pattern
*> SeenPats
;
1976 if (!emitPatFragMatchPattern(CE
, Alts
, M
, /*IM*/ nullptr,
1977 *cast
<PatFragPattern
>(Pat
.get()),
1982 case Pattern::K_Builtin
:
1983 PrintError("No known match builtins");
1985 case Pattern::K_CodeGenInstruction
:
1986 cast
<InstructionPattern
>(Pat
.get())->reportUnreachable(
1989 case Pattern::K_CXX
: {
1990 addCXXPredicate(M
, CE
, *cast
<CXXPattern
>(Pat
.get()), Alts
);
1994 llvm_unreachable("unknown pattern kind!");
1998 if (!emitApplyPatterns(CE
, M
))
2005 bool CombineRuleBuilder::emitPatFragMatchPattern(
2006 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&RM
,
2007 InstructionMatcher
*IM
, const PatFragPattern
&PFP
,
2008 DenseSet
<const Pattern
*> &SeenPats
) {
2009 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &PFP
);
2011 if (SeenPats
.contains(&PFP
))
2013 SeenPats
.insert(&PFP
);
2015 const auto &PF
= PFP
.getPatFrag();
2018 // When we don't have an IM, this means this PatFrag isn't reachable from
2019 // the root. This is only acceptable if it doesn't define anything (e.g. a
2020 // pure C++ PatFrag).
2021 if (PF
.num_out_params() != 0) {
2022 PFP
.reportUnreachable(RuleDef
.getLoc());
2026 // When an IM is provided, this is reachable from the root, and we're
2027 // expecting to have output operands.
2028 // TODO: If we want to allow for multiple roots we'll need a map of IMs
2029 // then, and emission becomes a bit more complicated.
2030 assert(PF
.num_roots() == 1);
2033 CodeExpansions PatFragCEs
;
2034 if (!PFP
.mapInputCodeExpansions(CE
, PatFragCEs
, RuleDef
.getLoc()))
2037 // List of {ParamName, ArgName}.
2038 // When all patterns have been emitted, find expansions in PatFragCEs named
2039 // ArgName and add their expansion to CE using ParamName as the key.
2040 SmallVector
<std::pair
<std::string
, std::string
>, 4> CEsToImport
;
2042 // Map parameter names to the actual argument.
2043 const auto OperandMapper
=
2044 [&](const InstructionOperand
&O
) -> InstructionOperand
{
2045 if (!O
.isNamedOperand())
2048 StringRef ParamName
= O
.getOperandName();
2050 // Not sure what to do with those tbh. They should probably never be here.
2051 assert(!O
.isNamedImmediate() && "TODO: handle named imms");
2052 unsigned PIdx
= PF
.getParamIdx(ParamName
);
2054 // Map parameters to the argument values.
2055 if (PIdx
== (unsigned)-1) {
2056 // This is a temp of the PatFragPattern, prefix the name to avoid
2058 return O
.withNewName(
2059 insertStrRef((PFP
.getName() + "." + ParamName
).str()));
2062 // The operand will be added to PatFragCEs's code expansions using the
2063 // parameter's name. If it's bound to some operand during emission of the
2064 // patterns, we'll want to add it to CE.
2065 auto ArgOp
= PFP
.getOperand(PIdx
);
2066 if (ArgOp
.isNamedOperand())
2067 CEsToImport
.emplace_back(ArgOp
.getOperandName().str(), ParamName
);
2069 if (ArgOp
.getType() && O
.getType() && ArgOp
.getType() != O
.getType()) {
2070 StringRef PFName
= PF
.getName();
2071 PrintWarning("impossible type constraints: operand " + Twine(PIdx
) +
2072 " of '" + PFP
.getName() + "' has type '" +
2073 ArgOp
.getType().str() + "', but '" + PFName
+
2074 "' constrains it to '" + O
.getType().str() + "'");
2075 if (ArgOp
.isNamedOperand())
2076 PrintNote("operand " + Twine(PIdx
) + " of '" + PFP
.getName() +
2077 "' is '" + ArgOp
.getOperandName() + "'");
2078 if (O
.isNamedOperand())
2079 PrintNote("argument " + Twine(PIdx
) + " of '" + PFName
+ "' is '" +
2086 // PatFragPatterns are only made of InstructionPatterns or CXXPatterns.
2087 // Emit instructions from the root.
2088 const auto &FragAlt
= PF
.getAlternative(Alts
.lookup(&PFP
));
2089 const auto &FragAltOT
= FragAlt
.OpTable
;
2090 const auto LookupOperandDef
=
2091 [&](StringRef Op
) -> const InstructionPattern
* {
2092 return FragAltOT
.getDef(Op
);
2095 DenseSet
<const Pattern
*> PatFragSeenPats
;
2096 for (const auto &[Idx
, InOp
] : enumerate(PF
.out_params())) {
2097 if (InOp
.Kind
!= PatFrag::PK_Root
)
2100 StringRef ParamName
= InOp
.Name
;
2101 const auto *Def
= FragAltOT
.getDef(ParamName
);
2102 assert(Def
&& "PatFrag::checkSemantics should have emitted an error if "
2103 "an out operand isn't defined!");
2104 assert(isa
<CodeGenInstructionPattern
>(Def
) &&
2105 "Nested PatFrags not supported yet");
2107 if (!emitCodeGenInstructionMatchPattern(
2108 PatFragCEs
, Alts
, RM
, *IM
, *cast
<CodeGenInstructionPattern
>(Def
),
2109 PatFragSeenPats
, LookupOperandDef
, OperandMapper
))
2114 for (const auto &Pat
: FragAlt
.Pats
) {
2115 if (PatFragSeenPats
.contains(Pat
.get()))
2118 if (const auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
.get())) {
2119 addCXXPredicate(RM
, PatFragCEs
, *CXXPat
, Alts
);
2123 if (const auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
2124 IP
->reportUnreachable(PF
.getLoc());
2128 llvm_unreachable("Unexpected pattern kind in PatFrag");
2131 for (const auto &[ParamName
, ArgName
] : CEsToImport
) {
2132 // Note: we're find if ParamName already exists. It just means it's been
2133 // bound before, so we prefer to keep the first binding.
2134 CE
.declare(ParamName
, PatFragCEs
.lookup(ArgName
));
2140 bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions
&CE
, RuleMatcher
&M
) {
2141 if (hasOnlyCXXApplyPatterns()) {
2142 for (auto &Pat
: values(ApplyPats
))
2143 addCXXAction(M
, CE
, *cast
<CXXPattern
>(Pat
.get()));
2147 DenseSet
<const Pattern
*> SeenPats
;
2148 StringMap
<unsigned> OperandToTempRegID
;
2150 for (auto *ApplyRoot
: ApplyRoots
) {
2151 assert(isa
<InstructionPattern
>(ApplyRoot
) &&
2152 "Root can only be a InstructionPattern!");
2153 if (!emitInstructionApplyPattern(CE
, M
,
2154 cast
<InstructionPattern
>(*ApplyRoot
),
2155 SeenPats
, OperandToTempRegID
))
2159 for (auto &Pat
: values(ApplyPats
)) {
2160 if (SeenPats
.contains(Pat
.get()))
2163 switch (Pat
->getKind()) {
2164 case Pattern::K_AnyOpcode
:
2165 llvm_unreachable("Unexpected pattern in apply!");
2166 case Pattern::K_PatFrag
:
2167 // TODO: We could support pure C++ PatFrags as a temporary thing.
2168 llvm_unreachable("Unexpected pattern in apply!");
2169 case Pattern::K_Builtin
:
2170 if (!emitInstructionApplyPattern(CE
, M
, cast
<BuiltinPattern
>(*Pat
),
2171 SeenPats
, OperandToTempRegID
))
2174 case Pattern::K_CodeGenInstruction
:
2175 cast
<CodeGenInstructionPattern
>(*Pat
).reportUnreachable(RuleDef
.getLoc());
2177 case Pattern::K_CXX
: {
2178 addCXXAction(M
, CE
, *cast
<CXXPattern
>(Pat
.get()));
2182 llvm_unreachable("unknown pattern kind!");
2189 bool CombineRuleBuilder::emitInstructionApplyPattern(
2190 CodeExpansions
&CE
, RuleMatcher
&M
, const InstructionPattern
&P
,
2191 DenseSet
<const Pattern
*> &SeenPats
,
2192 StringMap
<unsigned> &OperandToTempRegID
) {
2193 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &P
);
2195 if (SeenPats
.contains(&P
))
2198 SeenPats
.insert(&P
);
2200 // First, render the uses.
2201 for (auto &Op
: P
.named_operands()) {
2205 StringRef OpName
= Op
.getOperandName();
2206 if (const auto *DefPat
= ApplyOpTable
.getDef(OpName
)) {
2207 if (!emitInstructionApplyPattern(CE
, M
, *DefPat
, SeenPats
,
2208 OperandToTempRegID
))
2211 // If we have no def, check this exists in the MatchRoot.
2212 if (!Op
.isNamedImmediate() && !MatchOpTable
.lookup(OpName
).Found
) {
2213 PrintError("invalid output operand '" + OpName
+
2214 "': operand is not a live-in of the match pattern, and it "
2215 "has no definition");
2221 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(&P
))
2222 return emitBuiltinApplyPattern(CE
, M
, *BP
, OperandToTempRegID
);
2224 if (isa
<PatFragPattern
>(&P
))
2225 llvm_unreachable("PatFragPatterns is not supported in 'apply'!");
2227 auto &CGIP
= cast
<CodeGenInstructionPattern
>(P
);
2229 // Now render this inst.
2231 M
.addAction
<BuildMIAction
>(M
.allocateOutputInsnID(), &CGIP
.getInst());
2233 for (auto &Op
: P
.operands()) {
2234 if (Op
.isNamedImmediate()) {
2235 PrintError("invalid output operand '" + Op
.getOperandName() +
2236 "': output immediates cannot be named");
2237 PrintNote("while emitting pattern '" + P
.getName() + "' (" +
2238 P
.getInstName() + ")");
2242 if (Op
.hasImmValue()) {
2243 if (!emitCodeGenInstructionApplyImmOperand(M
, DstMI
, CGIP
, Op
))
2248 StringRef OpName
= Op
.getOperandName();
2252 if (auto It
= OperandToTempRegID
.find(OpName
);
2253 It
!= OperandToTempRegID
.end()) {
2254 assert(!MatchOpTable
.lookup(OpName
).Found
&&
2255 "Temp reg is also from match pattern?");
2256 DstMI
.addRenderer
<TempRegRenderer
>(It
->second
);
2258 // This should be a match live in or a redef of a matched instr.
2259 // If it's a use of a temporary register, then we messed up somewhere -
2260 // the previous condition should have passed.
2261 assert(MatchOpTable
.lookup(OpName
).Found
&&
2262 !ApplyOpTable
.getDef(OpName
) && "Temp reg not emitted yet!");
2263 DstMI
.addRenderer
<CopyRenderer
>(OpName
);
2268 // Determine what we're dealing with. Are we replace a matched instruction?
2269 // Creating a new one?
2270 auto OpLookupRes
= MatchOpTable
.lookup(OpName
);
2271 if (OpLookupRes
.Found
) {
2272 if (OpLookupRes
.isLiveIn()) {
2273 // live-in of the match pattern.
2274 PrintError("Cannot define live-in operand '" + OpName
+
2275 "' in the 'apply' pattern");
2278 assert(OpLookupRes
.Def
);
2280 // TODO: Handle this. We need to mutate the instr, or delete the old
2282 // Likewise, we also need to ensure we redef everything, if the
2283 // instr has more than one def, we need to redef all or nothing.
2284 if (OpLookupRes
.Def
!= MatchRoot
) {
2285 PrintError("redefining an instruction other than the root is not "
2286 "supported (operand '" +
2291 DstMI
.addRenderer
<CopyRenderer
>(OpName
);
2295 // Define a new register unique to the apply patterns (AKA a "temp"
2298 if (auto It
= OperandToTempRegID
.find(OpName
);
2299 It
!= OperandToTempRegID
.end()) {
2300 TempRegID
= It
->second
;
2302 // This is a brand new register.
2303 TempRegID
= M
.allocateTempRegID();
2304 OperandToTempRegID
[OpName
] = TempRegID
;
2305 const auto Ty
= Op
.getType();
2307 PrintError("def of a new register '" + OpName
+
2308 "' in the apply patterns must have a type");
2312 declareTempRegExpansion(CE
, TempRegID
, OpName
);
2313 // Always insert the action at the beginning, otherwise we may end up
2314 // using the temp reg before it's available.
2315 M
.insertAction
<MakeTempRegisterAction
>(
2316 M
.actions_begin(), getLLTCodeGenOrTempType(Ty
, M
), TempRegID
);
2319 DstMI
.addRenderer
<TempRegRenderer
>(TempRegID
);
2323 if (const auto *FI
= CGIP
.getMIFlagsInfo()) {
2324 for (StringRef InstName
: FI
->copy_flags())
2325 DstMI
.addCopiedMIFlags(M
.getInstructionMatcher(InstName
));
2326 for (StringRef F
: FI
->set_flags())
2327 DstMI
.addSetMIFlags(F
);
2328 for (StringRef F
: FI
->unset_flags())
2329 DstMI
.addUnsetMIFlags(F
);
2332 // Don't allow mutating opcodes for GISel combiners. We want a more precise
2333 // handling of MIFlags so we require them to be explicitly preserved.
2335 // TODO: We don't mutate very often, if at all in combiners, but it'd be nice
2336 // to re-enable this. We'd then need to always clear MIFlags when mutating
2337 // opcodes, and never mutate an inst that we copy flags from.
2338 // DstMI.chooseInsnToMutate(M);
2339 declareInstExpansion(CE
, DstMI
, P
.getName());
2344 bool CombineRuleBuilder::emitCodeGenInstructionApplyImmOperand(
2345 RuleMatcher
&M
, BuildMIAction
&DstMI
, const CodeGenInstructionPattern
&P
,
2346 const InstructionOperand
&O
) {
2347 // If we have a type, we implicitly emit a G_CONSTANT, except for G_CONSTANT
2348 // itself where we emit a CImm.
2350 // No type means we emit a simple imm.
2351 // G_CONSTANT is a special case and needs a CImm though so this is likely a
2353 const bool isGConstant
= P
.is("G_CONSTANT");
2354 const auto Ty
= O
.getType();
2357 PrintError("'G_CONSTANT' immediate must be typed!");
2358 PrintNote("while emitting pattern '" + P
.getName() + "' (" +
2359 P
.getInstName() + ")");
2363 DstMI
.addRenderer
<ImmRenderer
>(O
.getImmValue());
2367 auto ImmTy
= getLLTCodeGenOrTempType(Ty
, M
);
2370 DstMI
.addRenderer
<ImmRenderer
>(O
.getImmValue(), ImmTy
);
2374 unsigned TempRegID
= M
.allocateTempRegID();
2375 // Ensure MakeTempReg & the BuildConstantAction occur at the beginning.
2376 auto InsertIt
= M
.insertAction
<MakeTempRegisterAction
>(M
.actions_begin(),
2378 M
.insertAction
<BuildConstantAction
>(++InsertIt
, TempRegID
, O
.getImmValue());
2379 DstMI
.addRenderer
<TempRegRenderer
>(TempRegID
);
2383 bool CombineRuleBuilder::emitBuiltinApplyPattern(
2384 CodeExpansions
&CE
, RuleMatcher
&M
, const BuiltinPattern
&P
,
2385 StringMap
<unsigned> &OperandToTempRegID
) {
2386 const auto Error
= [&](Twine Reason
) {
2387 PrintError("cannot emit '" + P
.getInstName() + "' builtin: " + Reason
);
2391 switch (P
.getBuiltinKind()) {
2392 case BI_EraseRoot
: {
2393 // Root is always inst 0.
2394 M
.addAction
<EraseInstAction
>(/*InsnID*/ 0);
2397 case BI_ReplaceReg
: {
2398 StringRef Old
= P
.getOperand(0).getOperandName();
2399 StringRef New
= P
.getOperand(1).getOperandName();
2401 if (!ApplyOpTable
.lookup(New
).Found
&& !MatchOpTable
.lookup(New
).Found
)
2402 return Error("unknown operand '" + Old
+ "'");
2404 auto &OldOM
= M
.getOperandMatcher(Old
);
2405 if (auto It
= OperandToTempRegID
.find(New
);
2406 It
!= OperandToTempRegID
.end()) {
2407 // Replace with temp reg.
2408 M
.addAction
<ReplaceRegAction
>(OldOM
.getInsnVarID(), OldOM
.getOpIdx(),
2411 // Replace with matched reg.
2412 auto &NewOM
= M
.getOperandMatcher(New
);
2413 M
.addAction
<ReplaceRegAction
>(OldOM
.getInsnVarID(), OldOM
.getOpIdx(),
2414 NewOM
.getInsnVarID(), NewOM
.getOpIdx());
2416 // checkSemantics should have ensured that we can only rewrite the root.
2417 // Ensure we're deleting it.
2418 assert(MatchOpTable
.getDef(Old
) == MatchRoot
);
2419 // TODO: We could avoid adding the action again if it's already in. The
2420 // MatchTable is smart enough to only emit one opcode even if
2421 // EraseInstAction is present multiple times. I think searching for a copy
2422 // is more expensive than just blindly adding it though.
2423 M
.addAction
<EraseInstAction
>(/*InsnID*/ 0);
2429 llvm_unreachable("Unknown BuiltinKind!");
2432 bool isLiteralImm(const InstructionPattern
&P
, unsigned OpIdx
) {
2433 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&P
)) {
2434 StringRef InstName
= CGP
->getInst().TheDef
->getName();
2435 return (InstName
== "G_CONSTANT" || InstName
== "G_FCONSTANT") &&
2439 llvm_unreachable("TODO");
2442 bool CombineRuleBuilder::emitCodeGenInstructionMatchPattern(
2443 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&M
,
2444 InstructionMatcher
&IM
, const CodeGenInstructionPattern
&P
,
2445 DenseSet
<const Pattern
*> &SeenPats
, OperandDefLookupFn LookupOperandDef
,
2446 OperandMapperFnRef OperandMapper
) {
2447 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &P
);
2449 if (SeenPats
.contains(&P
))
2452 SeenPats
.insert(&P
);
2454 IM
.addPredicate
<InstructionOpcodeMatcher
>(&P
.getInst());
2455 declareInstExpansion(CE
, IM
, P
.getName());
2457 // Check flags if needed.
2458 if (const auto *FI
= P
.getMIFlagsInfo()) {
2459 assert(FI
->copy_flags().empty());
2461 if (const auto &SetF
= FI
->set_flags(); !SetF
.empty())
2462 IM
.addPredicate
<MIFlagsInstructionPredicateMatcher
>(SetF
.getArrayRef());
2463 if (const auto &UnsetF
= FI
->unset_flags(); !UnsetF
.empty())
2464 IM
.addPredicate
<MIFlagsInstructionPredicateMatcher
>(UnsetF
.getArrayRef(),
2468 for (const auto &[Idx
, OriginalO
] : enumerate(P
.operands())) {
2469 // Remap the operand. This is used when emitting InstructionPatterns inside
2470 // PatFrags, so it can remap them to the arguments passed to the pattern.
2472 // We use the remapped operand to emit immediates, and for the symbolic
2473 // operand names (in IM.addOperand). CodeExpansions and OperandTable lookups
2474 // still use the original name.
2476 // The "def" flag on the remapped operand is always ignored.
2477 auto RemappedO
= OperandMapper(OriginalO
);
2478 assert(RemappedO
.isNamedOperand() == OriginalO
.isNamedOperand() &&
2479 "Cannot remap an unnamed operand to a named one!");
2482 RemappedO
.isNamedOperand() ? RemappedO
.getOperandName().str() : "";
2483 OperandMatcher
&OM
=
2484 IM
.addOperand(Idx
, OpName
, AllocatedTemporariesBaseID
++);
2485 if (!OpName
.empty())
2486 declareOperandExpansion(CE
, OM
, OriginalO
.getOperandName());
2488 // Handle immediates.
2489 if (RemappedO
.hasImmValue()) {
2490 if (isLiteralImm(P
, Idx
))
2491 OM
.addPredicate
<LiteralIntOperandMatcher
>(RemappedO
.getImmValue());
2493 OM
.addPredicate
<ConstantIntOperandMatcher
>(RemappedO
.getImmValue());
2496 // Handle typed operands, but only bother to check if it hasn't been done
2499 // getOperandMatcher will always return the first OM to have been created
2500 // for that Operand. "OM" here is always a new OperandMatcher.
2502 // Always emit a check for unnamed operands.
2503 if (OpName
.empty() ||
2504 !M
.getOperandMatcher(OpName
).contains
<LLTOperandMatcher
>()) {
2505 if (const auto Ty
= RemappedO
.getType()) {
2506 // TODO: We could support GITypeOf here on the condition that the
2507 // OperandMatcher exists already. Though it's clunky to make this work
2508 // and isn't all that useful so it's just rejected in typecheckPatterns
2510 assert(Ty
.isLLT() && "Only LLTs are supported in match patterns!");
2511 OM
.addPredicate
<LLTOperandMatcher
>(getLLTCodeGen(Ty
));
2515 // Stop here if the operand is a def, or if it had no name.
2516 if (OriginalO
.isDef() || !OriginalO
.isNamedOperand())
2519 const auto *DefPat
= LookupOperandDef(OriginalO
.getOperandName());
2523 if (OriginalO
.hasImmValue()) {
2524 assert(!OpName
.empty());
2525 // This is a named immediate that also has a def, that's not okay.
2527 // (G_SEXT $y, (i32 0))
2529 PrintError("'" + OpName
+
2530 "' is a named immediate, it cannot be defined by another "
2532 PrintNote("'" + OpName
+ "' is defined by '" + DefPat
->getName() + "'");
2536 // From here we know that the operand defines an instruction, and we need to
2539 OM
.addPredicate
<InstructionOperandMatcher
>(M
, DefPat
->getName());
2541 // TODO: copy-pasted from GlobalISelEmitter.cpp. Is it still relevant
2543 PrintError("Nested instruction '" + DefPat
->getName() +
2544 "' cannot be the same as another operand '" +
2545 OriginalO
.getOperandName() + "'");
2549 auto &IM
= (*InstOpM
)->getInsnMatcher();
2550 if (const auto *CGIDef
= dyn_cast
<CodeGenInstructionPattern
>(DefPat
)) {
2551 if (!emitCodeGenInstructionMatchPattern(CE
, Alts
, M
, IM
, *CGIDef
,
2552 SeenPats
, LookupOperandDef
,
2558 if (const auto *PFPDef
= dyn_cast
<PatFragPattern
>(DefPat
)) {
2559 if (!emitPatFragMatchPattern(CE
, Alts
, M
, &IM
, *PFPDef
, SeenPats
))
2564 llvm_unreachable("unknown type of InstructionPattern");
2570 //===- GICombinerEmitter --------------------------------------------------===//
2572 /// Main implementation class. This emits the tablegenerated output.
2574 /// It collects rules, uses `CombineRuleBuilder` to parse them and accumulate
2575 /// RuleMatchers, then takes all the necessary state/data from the various
2576 /// static storage pools and wires them together to emit the match table &
2577 /// associated function/data structures.
2578 class GICombinerEmitter final
: public GlobalISelMatchTableExecutorEmitter
{
2579 RecordKeeper
&Records
;
2581 const CodeGenTarget
&Target
;
2583 unsigned NextRuleID
= 0;
2585 // List all combine rules (ID, name) imported.
2586 // Note that the combiner rule ID is different from the RuleMatcher ID. The
2587 // latter is internal to the MatchTable, the former is the canonical ID of the
2588 // combine rule used to disable/enable it.
2589 std::vector
<std::pair
<unsigned, std::string
>> AllCombineRules
;
2591 // Keep track of all rules we've seen so far to ensure we don't process
2592 // the same rule twice.
2593 StringSet
<> RulesSeen
;
2595 MatchTable
buildMatchTable(MutableArrayRef
<RuleMatcher
> Rules
);
2597 void emitRuleConfigImpl(raw_ostream
&OS
);
2599 void emitAdditionalImpl(raw_ostream
&OS
) override
;
2601 void emitMIPredicateFns(raw_ostream
&OS
) override
;
2602 void emitI64ImmPredicateFns(raw_ostream
&OS
) override
;
2603 void emitAPFloatImmPredicateFns(raw_ostream
&OS
) override
;
2604 void emitAPIntImmPredicateFns(raw_ostream
&OS
) override
;
2605 void emitTestSimplePredicate(raw_ostream
&OS
) override
;
2606 void emitRunCustomAction(raw_ostream
&OS
) override
;
2608 void emitAdditionalTemporariesDecl(raw_ostream
&OS
,
2609 StringRef Indent
) override
;
2611 const CodeGenTarget
&getTarget() const override
{ return Target
; }
2612 StringRef
getClassName() const override
{
2613 return Combiner
->getValueAsString("Classname");
2616 StringRef
getCombineAllMethodName() const {
2617 return Combiner
->getValueAsString("CombineAllMethodName");
2620 std::string
getRuleConfigClassName() const {
2621 return getClassName().str() + "RuleConfig";
2624 void gatherRules(std::vector
<RuleMatcher
> &Rules
,
2625 const std::vector
<Record
*> &&RulesAndGroups
);
2628 explicit GICombinerEmitter(RecordKeeper
&RK
, const CodeGenTarget
&Target
,
2629 StringRef Name
, Record
*Combiner
);
2630 ~GICombinerEmitter() {}
2632 void run(raw_ostream
&OS
);
2635 void GICombinerEmitter::emitRuleConfigImpl(raw_ostream
&OS
) {
2636 OS
<< "struct " << getRuleConfigClassName() << " {\n"
2637 << " SparseBitVector<> DisabledRules;\n\n"
2638 << " bool isRuleEnabled(unsigned RuleID) const;\n"
2639 << " bool parseCommandLineOption();\n"
2640 << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
2641 << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
2644 std::vector
<std::pair
<std::string
, std::string
>> Cases
;
2645 Cases
.reserve(AllCombineRules
.size());
2647 for (const auto &[ID
, Name
] : AllCombineRules
)
2648 Cases
.emplace_back(Name
, "return " + to_string(ID
) + ";\n");
2650 OS
<< "static std::optional<uint64_t> getRuleIdxForIdentifier(StringRef "
2651 "RuleIdentifier) {\n"
2653 << " // getAtInteger(...) returns false on success\n"
2654 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
2657 << "#ifndef NDEBUG\n";
2658 StringMatcher
Matcher("RuleIdentifier", Cases
, OS
);
2660 OS
<< "#endif // ifndef NDEBUG\n\n"
2661 << " return std::nullopt;\n"
2664 OS
<< "static std::optional<std::pair<uint64_t, uint64_t>> "
2665 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
2666 << " std::pair<StringRef, StringRef> RangePair = "
2667 "RuleIdentifier.split('-');\n"
2668 << " if (!RangePair.second.empty()) {\n"
2669 << " const auto First = "
2670 "getRuleIdxForIdentifier(RangePair.first);\n"
2671 << " const auto Last = "
2672 "getRuleIdxForIdentifier(RangePair.second);\n"
2673 << " if (!First || !Last)\n"
2674 << " return std::nullopt;\n"
2675 << " if (First >= Last)\n"
2676 << " report_fatal_error(\"Beginning of range should be before "
2677 "end of range\");\n"
2678 << " return {{*First, *Last + 1}};\n"
2680 << " if (RangePair.first == \"*\") {\n"
2681 << " return {{0, " << AllCombineRules
.size() << "}};\n"
2683 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
2685 << " return std::nullopt;\n"
2686 << " return {{*I, *I + 1}};\n"
2689 for (bool Enabled
: {true, false}) {
2690 OS
<< "bool " << getRuleConfigClassName() << "::setRule"
2691 << (Enabled
? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
2692 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
2693 << " if (!MaybeRange)\n"
2694 << " return false;\n"
2695 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
2696 << " DisabledRules." << (Enabled
? "reset" : "set") << "(I);\n"
2697 << " return true;\n"
2701 OS
<< "static std::vector<std::string> " << Name
<< "Option;\n"
2702 << "static cl::list<std::string> " << Name
<< "DisableOption(\n"
2703 << " \"" << Name
.lower() << "-disable-rule\",\n"
2704 << " cl::desc(\"Disable one or more combiner rules temporarily in "
2705 << "the " << Name
<< " pass\"),\n"
2706 << " cl::CommaSeparated,\n"
2708 << " cl::cat(GICombinerOptionCategory),\n"
2709 << " cl::callback([](const std::string &Str) {\n"
2710 << " " << Name
<< "Option.push_back(Str);\n"
2712 << "static cl::list<std::string> " << Name
<< "OnlyEnableOption(\n"
2713 << " \"" << Name
.lower() << "-only-enable-rule\",\n"
2714 << " cl::desc(\"Disable all rules in the " << Name
2715 << " pass then re-enable the specified ones\"),\n"
2717 << " cl::cat(GICombinerOptionCategory),\n"
2718 << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
2719 << " StringRef Str = CommaSeparatedArg;\n"
2720 << " " << Name
<< "Option.push_back(\"*\");\n"
2722 << " auto X = Str.split(\",\");\n"
2723 << " " << Name
<< "Option.push_back((\"!\" + X.first).str());\n"
2724 << " Str = X.second;\n"
2725 << " } while (!Str.empty());\n"
2728 << "bool " << getRuleConfigClassName()
2729 << "::isRuleEnabled(unsigned RuleID) const {\n"
2730 << " return !DisabledRules.test(RuleID);\n"
2732 << "bool " << getRuleConfigClassName() << "::parseCommandLineOption() {\n"
2733 << " for (StringRef Identifier : " << Name
<< "Option) {\n"
2734 << " bool Enabled = Identifier.consume_front(\"!\");\n"
2735 << " if (Enabled && !setRuleEnabled(Identifier))\n"
2736 << " return false;\n"
2737 << " if (!Enabled && !setRuleDisabled(Identifier))\n"
2738 << " return false;\n"
2740 << " return true;\n"
2744 void GICombinerEmitter::emitAdditionalImpl(raw_ostream
&OS
) {
2745 OS
<< "bool " << getClassName() << "::" << getCombineAllMethodName()
2746 << "(MachineInstr &I) const {\n"
2747 << " const TargetSubtargetInfo &ST = MF.getSubtarget();\n"
2748 << " const PredicateBitset AvailableFeatures = "
2749 "getAvailableFeatures();\n"
2750 << " B.setInstrAndDebugLoc(I);\n"
2751 << " State.MIs.clear();\n"
2752 << " State.MIs.push_back(&I);\n"
2753 << " " << MatchDataInfo::StructName
<< " = "
2754 << MatchDataInfo::StructTypeName
<< "();\n\n"
2755 << " if (executeMatchTable(*this, State, ExecInfo, B"
2756 << ", getMatchTable(), *ST.getInstrInfo(), MRI, "
2757 "*MRI.getTargetRegisterInfo(), *ST.getRegBankInfo(), AvailableFeatures"
2758 << ", /*CoverageInfo*/ nullptr)) {\n"
2759 << " return true;\n"
2761 << " return false;\n"
2765 void GICombinerEmitter::emitMIPredicateFns(raw_ostream
&OS
) {
2766 auto MatchCode
= CXXPredicateCode::getAllMatchCode();
2767 emitMIPredicateFnsImpl
<const CXXPredicateCode
*>(
2768 OS
, "", ArrayRef
<const CXXPredicateCode
*>(MatchCode
),
2769 [](const CXXPredicateCode
*C
) -> StringRef
{ return C
->BaseEnumName
; },
2770 [](const CXXPredicateCode
*C
) -> StringRef
{ return C
->Code
; });
2773 void GICombinerEmitter::emitI64ImmPredicateFns(raw_ostream
&OS
) {
2774 // Unused, but still needs to be called.
2775 emitImmPredicateFnsImpl
<unsigned>(
2776 OS
, "I64", "int64_t", {}, [](unsigned) { return ""; },
2777 [](unsigned) { return ""; });
2780 void GICombinerEmitter::emitAPFloatImmPredicateFns(raw_ostream
&OS
) {
2781 // Unused, but still needs to be called.
2782 emitImmPredicateFnsImpl
<unsigned>(
2783 OS
, "APFloat", "const APFloat &", {}, [](unsigned) { return ""; },
2784 [](unsigned) { return ""; });
2787 void GICombinerEmitter::emitAPIntImmPredicateFns(raw_ostream
&OS
) {
2788 // Unused, but still needs to be called.
2789 emitImmPredicateFnsImpl
<unsigned>(
2790 OS
, "APInt", "const APInt &", {}, [](unsigned) { return ""; },
2791 [](unsigned) { return ""; });
2794 void GICombinerEmitter::emitTestSimplePredicate(raw_ostream
&OS
) {
2795 if (!AllCombineRules
.empty()) {
2797 std::string EnumeratorSeparator
= " = GICXXPred_Invalid + 1,\n";
2798 // To avoid emitting a switch, we expect that all those rules are in order.
2799 // That way we can just get the RuleID from the enum by subtracting
2800 // (GICXXPred_Invalid + 1).
2801 unsigned ExpectedID
= 0;
2803 for (const auto &ID
: keys(AllCombineRules
)) {
2804 assert(ExpectedID
++ == ID
&& "combine rules are not ordered!");
2805 OS
<< " " << getIsEnabledPredicateEnumName(ID
) << EnumeratorSeparator
;
2806 EnumeratorSeparator
= ",\n";
2811 OS
<< "bool " << getClassName()
2812 << "::testSimplePredicate(unsigned Predicate) const {\n"
2813 << " return RuleConfig.isRuleEnabled(Predicate - "
2814 "GICXXPred_Invalid - "
2819 void GICombinerEmitter::emitRunCustomAction(raw_ostream
&OS
) {
2820 const auto ApplyCode
= CXXPredicateCode::getAllApplyCode();
2822 if (!ApplyCode
.empty()) {
2824 std::string EnumeratorSeparator
= " = GICXXCustomAction_Invalid + 1,\n";
2825 for (const auto &Apply
: ApplyCode
) {
2826 OS
<< " " << Apply
->getEnumNameWithPrefix(CXXApplyPrefix
)
2827 << EnumeratorSeparator
;
2828 EnumeratorSeparator
= ",\n";
2833 OS
<< "void " << getClassName()
2834 << "::runCustomAction(unsigned ApplyID, const MatcherState &State, "
2835 "NewMIVector &OutMIs) const "
2837 if (!ApplyCode
.empty()) {
2838 OS
<< " switch(ApplyID) {\n";
2839 for (const auto &Apply
: ApplyCode
) {
2840 OS
<< " case " << Apply
->getEnumNameWithPrefix(CXXApplyPrefix
) << ":{\n"
2841 << " " << join(split(Apply
->Code
, '\n'), "\n ") << '\n'
2847 OS
<< " llvm_unreachable(\"Unknown Apply Action\");\n"
2851 void GICombinerEmitter::emitAdditionalTemporariesDecl(raw_ostream
&OS
,
2853 OS
<< Indent
<< "struct " << MatchDataInfo::StructTypeName
<< " {\n";
2854 for (const auto &[Type
, VarNames
] : AllMatchDataVars
) {
2855 assert(!VarNames
.empty() && "Cannot have no vars for this type!");
2856 OS
<< Indent
<< " " << Type
<< " " << join(VarNames
, ", ") << ";\n";
2858 OS
<< Indent
<< "};\n"
2859 << Indent
<< "mutable " << MatchDataInfo::StructTypeName
<< " "
2860 << MatchDataInfo::StructName
<< ";\n\n";
2863 GICombinerEmitter::GICombinerEmitter(RecordKeeper
&RK
,
2864 const CodeGenTarget
&Target
,
2865 StringRef Name
, Record
*Combiner
)
2866 : Records(RK
), Name(Name
), Target(Target
), Combiner(Combiner
) {}
2869 GICombinerEmitter::buildMatchTable(MutableArrayRef
<RuleMatcher
> Rules
) {
2870 std::vector
<Matcher
*> InputRules
;
2871 for (Matcher
&Rule
: Rules
)
2872 InputRules
.push_back(&Rule
);
2874 unsigned CurrentOrdering
= 0;
2875 StringMap
<unsigned> OpcodeOrder
;
2876 for (RuleMatcher
&Rule
: Rules
) {
2877 const StringRef Opcode
= Rule
.getOpcode();
2878 assert(!Opcode
.empty() && "Didn't expect an undefined opcode");
2879 if (OpcodeOrder
.count(Opcode
) == 0)
2880 OpcodeOrder
[Opcode
] = CurrentOrdering
++;
2883 llvm::stable_sort(InputRules
, [&OpcodeOrder
](const Matcher
*A
,
2885 auto *L
= static_cast<const RuleMatcher
*>(A
);
2886 auto *R
= static_cast<const RuleMatcher
*>(B
);
2887 return std::make_tuple(OpcodeOrder
[L
->getOpcode()], L
->getNumOperands()) <
2888 std::make_tuple(OpcodeOrder
[R
->getOpcode()], R
->getNumOperands());
2891 for (Matcher
*Rule
: InputRules
)
2894 std::vector
<std::unique_ptr
<Matcher
>> MatcherStorage
;
2895 std::vector
<Matcher
*> OptRules
=
2896 optimizeRules
<GroupMatcher
>(InputRules
, MatcherStorage
);
2898 for (Matcher
*Rule
: OptRules
)
2901 OptRules
= optimizeRules
<SwitchMatcher
>(OptRules
, MatcherStorage
);
2903 return MatchTable::buildTable(OptRules
, /*WithCoverage*/ false,
2904 /*IsCombiner*/ true);
2907 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
2908 void GICombinerEmitter::gatherRules(
2909 std::vector
<RuleMatcher
> &ActiveRules
,
2910 const std::vector
<Record
*> &&RulesAndGroups
) {
2911 for (Record
*Rec
: RulesAndGroups
) {
2912 if (!Rec
->isValueUnset("Rules")) {
2913 gatherRules(ActiveRules
, Rec
->getValueAsListOfDefs("Rules"));
2917 StringRef RuleName
= Rec
->getName();
2918 if (!RulesSeen
.insert(RuleName
).second
) {
2919 PrintWarning(Rec
->getLoc(),
2920 "skipping rule '" + Rec
->getName() +
2921 "' because it has already been processed");
2925 AllCombineRules
.emplace_back(NextRuleID
, Rec
->getName().str());
2926 CombineRuleBuilder
CRB(Target
, SubtargetFeatures
, *Rec
, NextRuleID
++,
2929 if (!CRB
.parseAll()) {
2930 assert(ErrorsPrinted
&& "Parsing failed without errors!");
2934 if (StopAfterParse
) {
2939 if (!CRB
.emitRuleMatchers()) {
2940 assert(ErrorsPrinted
&& "Emission failed without errors!");
2946 void GICombinerEmitter::run(raw_ostream
&OS
) {
2947 InstructionOpcodeMatcher::initOpcodeValuesMap(Target
);
2948 LLTOperandMatcher::initTypeIDValuesMap();
2950 Records
.startTimer("Gather rules");
2951 std::vector
<RuleMatcher
> Rules
;
2952 gatherRules(Rules
, Combiner
->getValueAsListOfDefs("Rules"));
2954 PrintFatalError(Combiner
->getLoc(), "Failed to parse one or more rules");
2959 Records
.startTimer("Creating Match Table");
2960 unsigned MaxTemporaries
= 0;
2961 for (const auto &Rule
: Rules
)
2962 MaxTemporaries
= std::max(MaxTemporaries
, Rule
.countRendererFns());
2964 llvm::stable_sort(Rules
, [&](const RuleMatcher
&A
, const RuleMatcher
&B
) {
2965 if (A
.isHigherPriorityThan(B
)) {
2966 assert(!B
.isHigherPriorityThan(A
) && "Cannot be more important "
2967 "and less important at "
2974 const MatchTable Table
= buildMatchTable(Rules
);
2976 Records
.startTimer("Emit combiner");
2978 emitSourceFileHeader(getClassName().str() + " Combiner Match Table", OS
);
2981 std::vector
<StringRef
> CustomRendererFns
;
2983 std::vector
<Record
*> ComplexPredicates
;
2985 SmallVector
<LLTCodeGen
, 16> TypeObjects
;
2986 append_range(TypeObjects
, KnownTypes
);
2987 llvm::sort(TypeObjects
);
2989 // Hack: Avoid empty declarator.
2990 if (TypeObjects
.empty())
2991 TypeObjects
.push_back(LLT::scalar(1));
2993 // GET_GICOMBINER_DEPS, which pulls in extra dependencies.
2994 OS
<< "#ifdef GET_GICOMBINER_DEPS\n"
2995 << "#include \"llvm/ADT/SparseBitVector.h\"\n"
2996 << "namespace llvm {\n"
2997 << "extern cl::OptionCategory GICombinerOptionCategory;\n"
2998 << "} // end namespace llvm\n"
2999 << "#endif // ifdef GET_GICOMBINER_DEPS\n\n";
3001 // GET_GICOMBINER_TYPES, which needs to be included before the declaration of
3003 OS
<< "#ifdef GET_GICOMBINER_TYPES\n";
3004 emitRuleConfigImpl(OS
);
3005 OS
<< "#endif // ifdef GET_GICOMBINER_TYPES\n\n";
3006 emitPredicateBitset(OS
, "GET_GICOMBINER_TYPES");
3008 // GET_GICOMBINER_CLASS_MEMBERS, which need to be included inside the class.
3009 emitPredicatesDecl(OS
, "GET_GICOMBINER_CLASS_MEMBERS");
3010 emitTemporariesDecl(OS
, "GET_GICOMBINER_CLASS_MEMBERS");
3012 // GET_GICOMBINER_IMPL, which needs to be included outside the class.
3013 emitExecutorImpl(OS
, Table
, TypeObjects
, Rules
, ComplexPredicates
,
3014 CustomRendererFns
, "GET_GICOMBINER_IMPL");
3016 // GET_GICOMBINER_CONSTRUCTOR_INITS, which are in the constructor's
3017 // initializer list.
3018 emitPredicatesInit(OS
, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3019 emitTemporariesInit(OS
, MaxTemporaries
, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3022 } // end anonymous namespace
3024 //===----------------------------------------------------------------------===//
3026 static void EmitGICombiner(RecordKeeper
&RK
, raw_ostream
&OS
) {
3027 EnablePrettyStackTrace();
3028 CodeGenTarget
Target(RK
);
3030 if (SelectedCombiners
.empty())
3031 PrintFatalError("No combiners selected with -combiners");
3032 for (const auto &Combiner
: SelectedCombiners
) {
3033 Record
*CombinerDef
= RK
.getDef(Combiner
);
3035 PrintFatalError("Could not find " + Combiner
);
3036 GICombinerEmitter(RK
, Target
, Combiner
, CombinerDef
).run(OS
);
3040 static TableGen::Emitter::Opt
X("gen-global-isel-combiner", EmitGICombiner
,
3041 "Generate GlobalISel Combiner");