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/CodeExpander.h"
32 #include "GlobalISel/CodeExpansions.h"
33 #include "GlobalISel/CombinerUtils.h"
34 #include "GlobalISelMatchTable.h"
35 #include "GlobalISelMatchTableExecutorEmitter.h"
36 #include "SubtargetFeatureInfo.h"
37 #include "llvm/ADT/APInt.h"
38 #include "llvm/ADT/Hashing.h"
39 #include "llvm/ADT/MapVector.h"
40 #include "llvm/ADT/Statistic.h"
41 #include "llvm/ADT/StringSet.h"
42 #include "llvm/Support/CommandLine.h"
43 #include "llvm/Support/Debug.h"
44 #include "llvm/Support/PrettyStackTrace.h"
45 #include "llvm/Support/ScopedPrinter.h"
46 #include "llvm/TableGen/Error.h"
47 #include "llvm/TableGen/Record.h"
48 #include "llvm/TableGen/StringMatcher.h"
49 #include "llvm/TableGen/TableGenBackend.h"
53 using namespace llvm::gi
;
55 #define DEBUG_TYPE "gicombiner-emitter"
59 GICombinerEmitterCat("Options for -gen-global-isel-combiner");
60 cl::opt
<bool> StopAfterParse(
61 "gicombiner-stop-after-parse",
62 cl::desc("Stop processing after parsing rules and dump state"),
63 cl::cat(GICombinerEmitterCat
));
65 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
66 cl::cat(GICombinerEmitterCat
), cl::CommaSeparated
);
67 cl::opt
<bool> DebugCXXPreds(
68 "gicombiner-debug-cxxpreds",
69 cl::desc("Add Contextual/Debug comments to all C++ predicates"),
70 cl::cat(GICombinerEmitterCat
));
72 constexpr StringLiteral CXXApplyPrefix
= "GICXXCustomAction_CombineApply";
73 constexpr StringLiteral CXXPredPrefix
= "GICXXPred_MI_Predicate_";
74 constexpr StringLiteral PatFragClassName
= "GICombinePatFrag";
75 constexpr StringLiteral BuiltinInstClassName
= "GIBuiltinInst";
76 constexpr StringLiteral SpecialTyClassName
= "GISpecialType";
77 constexpr StringLiteral TypeOfClassName
= "GITypeOf";
79 std::string
getIsEnabledPredicateEnumName(unsigned CombinerRuleID
) {
80 return "GICXXPred_Simple_IsRule" + to_string(CombinerRuleID
) + "Enabled";
83 /// Copies a StringRef into a static pool to make sure it has a static lifetime.
84 StringRef
insertStrRef(StringRef S
) {
88 static StringSet
<> Pool
;
89 auto [It
, Inserted
] = Pool
.insert(S
);
93 void declareInstExpansion(CodeExpansions
&CE
, const InstructionMatcher
&IM
,
95 CE
.declare(Name
, "State.MIs[" + to_string(IM
.getInsnVarID()) + "]");
98 void declareInstExpansion(CodeExpansions
&CE
, const BuildMIAction
&A
,
100 // Note: we use redeclare here because this may overwrite a matcher inst
102 CE
.redeclare(Name
, "OutMIs[" + to_string(A
.getInsnID()) + "]");
105 void declareOperandExpansion(CodeExpansions
&CE
, const OperandMatcher
&OM
,
107 CE
.declare(Name
, "State.MIs[" + to_string(OM
.getInsnVarID()) +
108 "]->getOperand(" + to_string(OM
.getOpIdx()) + ")");
111 void declareTempRegExpansion(CodeExpansions
&CE
, unsigned TempRegID
,
113 CE
.declare(Name
, "State.TempRegisters[" + to_string(TempRegID
) + "]");
116 std::string
makeAnonPatName(StringRef Prefix
, unsigned Idx
) {
117 return ("__" + Prefix
+ "_" + Twine(Idx
)).str();
120 template <typename Container
> auto keys(Container
&&C
) {
121 return map_range(C
, [](auto &Entry
) -> auto & { return Entry
.first
; });
124 template <typename Container
> auto values(Container
&&C
) {
125 return map_range(C
, [](auto &Entry
) -> auto & { return Entry
.second
; });
128 //===- MatchData Handling -------------------------------------------------===//
130 /// Represents MatchData defined by the match stage and required by the apply
133 /// This allows the plumbing of arbitrary data from C++ predicates between the
136 /// When this class is initially created, it only has a pattern symbol and a
137 /// type. When all of the MatchDatas declarations of a given pattern have been
138 /// parsed, `AssignVariables` must be called to assign storage variable names to
139 /// each MatchDataInfo.
140 class MatchDataInfo
{
141 StringRef PatternSymbol
;
146 static constexpr StringLiteral StructTypeName
= "MatchInfosTy";
147 static constexpr StringLiteral StructName
= "MatchInfos";
149 MatchDataInfo(StringRef PatternSymbol
, StringRef Type
)
150 : PatternSymbol(PatternSymbol
), Type(Type
.trim()) {}
152 StringRef
getPatternSymbol() const { return PatternSymbol
; };
153 StringRef
getType() const { return Type
; };
155 bool hasVariableName() const { return !VarName
.empty(); }
156 void setVariableName(StringRef Name
) { VarName
= Name
; }
157 StringRef
getVariableName() const;
159 std::string
getQualifiedVariableName() const {
160 return StructName
.str() + "." + getVariableName().str();
163 void print(raw_ostream
&OS
) const;
164 void dump() const { print(dbgs()); }
167 StringRef
MatchDataInfo::getVariableName() const {
168 assert(hasVariableName());
172 void MatchDataInfo::print(raw_ostream
&OS
) const {
173 OS
<< "(MatchDataInfo pattern_symbol:" << PatternSymbol
<< " type:'" << Type
174 << "' var_name:" << (VarName
.empty() ? "<unassigned>" : VarName
) << ")";
177 /// Pool of type -> variables used to emit MatchData variables declarations.
179 /// e.g. if the map contains "int64_t" -> ["MD0", "MD1"], then two variable
180 /// declarations must be emitted: `int64_t MD0` and `int64_t MD1`.
182 /// This has a static lifetime and will outlive all the `MatchDataInfo` objects
183 /// by design. It needs to persist after all `CombineRuleBuilder` objects died
184 /// so we can emit the variable declarations.
185 StringMap
<std::vector
<std::string
>> AllMatchDataVars
;
187 // Assign variable names to all MatchDatas used by a pattern. This must be
188 // called after all MatchData decls have been parsed inside a rule.
190 // Requires an array of MatchDataInfo so we can handle cases where a pattern
191 // uses multiple instances of the same MatchData type.
192 void AssignMatchDataVariables(MutableArrayRef
<MatchDataInfo
> Infos
) {
193 static unsigned NextVarID
= 0;
195 StringMap
<unsigned> SeenTypes
;
196 for (auto &Info
: Infos
) {
197 unsigned &NumSeen
= SeenTypes
[Info
.getType()];
198 auto &ExistingVars
= AllMatchDataVars
[Info
.getType()];
200 if (NumSeen
== ExistingVars
.size())
201 ExistingVars
.push_back("MDInfo" + to_string(NextVarID
++));
203 Info
.setVariableName(ExistingVars
[NumSeen
++]);
207 //===- C++ Predicates Handling --------------------------------------------===//
209 /// Entry into the static pool of all CXX Predicate code. This contains
210 /// fully expanded C++ code.
212 /// The static pool is hidden inside the object and can be accessed through
213 /// getAllMatchCode/getAllApplyCode
215 /// Note that CXXPattern trims C++ code, so the Code is already expected to be
216 /// free of leading/trailing whitespace.
217 class CXXPredicateCode
{
218 using CXXPredicateCodePool
=
219 DenseMap
<hash_code
, std::unique_ptr
<CXXPredicateCode
>>;
220 static CXXPredicateCodePool AllCXXMatchCode
;
221 static CXXPredicateCodePool AllCXXApplyCode
;
223 /// Sorts a `CXXPredicateCodePool` by their IDs and returns it.
224 static std::vector
<const CXXPredicateCode
*>
225 getSorted(const CXXPredicateCodePool
&Pool
) {
226 std::vector
<const CXXPredicateCode
*> Out
;
227 std::transform(Pool
.begin(), Pool
.end(), std::back_inserter(Out
),
228 [&](auto &Elt
) { return Elt
.second
.get(); });
229 sort(Out
, [](const auto *A
, const auto *B
) { return A
->ID
< B
->ID
; });
233 /// Gets an instance of `CXXPredicateCode` for \p Code, or returns an already
235 static const CXXPredicateCode
&get(CXXPredicateCodePool
&Pool
,
237 // Check if we already have an identical piece of code, if not, create an
238 // entry in the pool.
239 const auto CodeHash
= hash_value(Code
);
240 if (auto It
= Pool
.find(CodeHash
); It
!= Pool
.end())
243 const auto ID
= Pool
.size();
244 auto OwnedData
= std::unique_ptr
<CXXPredicateCode
>(
245 new CXXPredicateCode(std::move(Code
), ID
));
246 const auto &DataRef
= *OwnedData
;
247 Pool
[CodeHash
] = std::move(OwnedData
);
251 CXXPredicateCode(std::string Code
, unsigned ID
)
252 : Code(Code
), ID(ID
), BaseEnumName("GICombiner" + to_string(ID
)) {
253 // Don't assert if ErrorsPrinted is set. This may mean CodeExpander failed,
254 // and it may add spaces in such cases.
255 assert((ErrorsPrinted
|| StringRef(Code
).trim() == Code
) &&
256 "Code was expected to be trimmed!");
260 static const CXXPredicateCode
&getMatchCode(std::string Code
) {
261 return get(AllCXXMatchCode
, std::move(Code
));
264 static const CXXPredicateCode
&getApplyCode(std::string Code
) {
265 return get(AllCXXApplyCode
, std::move(Code
));
268 static std::vector
<const CXXPredicateCode
*> getAllMatchCode() {
269 return getSorted(AllCXXMatchCode
);
272 static std::vector
<const CXXPredicateCode
*> getAllApplyCode() {
273 return getSorted(AllCXXApplyCode
);
276 const std::string Code
;
278 const std::string BaseEnumName
;
280 bool needsUnreachable() const {
281 return !StringRef(Code
).starts_with("return");
284 std::string
getEnumNameWithPrefix(StringRef Prefix
) const {
285 return Prefix
.str() + BaseEnumName
;
289 CXXPredicateCode::CXXPredicateCodePool
CXXPredicateCode::AllCXXMatchCode
;
290 CXXPredicateCode::CXXPredicateCodePool
CXXPredicateCode::AllCXXApplyCode
;
292 //===- PatternType --------------------------------------------------------===//
294 /// Represent the type of a Pattern Operand.
296 /// Types have two form:
297 /// - LLTs, which are straightforward.
298 /// - Special types, e.g. GITypeOf
301 PatternType() = default;
302 PatternType(const Record
*R
) : R(R
) {}
304 bool isValidType() const { return !R
|| isLLT() || isSpecial(); }
306 bool isLLT() const { return R
&& R
->isSubClassOf("ValueType"); }
307 bool isSpecial() const { return R
&& R
->isSubClassOf(SpecialTyClassName
); }
308 bool isTypeOf() const { return R
&& R
->isSubClassOf(TypeOfClassName
); }
310 StringRef
getTypeOfOpName() const;
311 LLTCodeGen
getLLTCodeGen() const;
313 bool checkSemantics(ArrayRef
<SMLoc
> DiagLoc
) const;
315 LLTCodeGenOrTempType
getLLTCodeGenOrTempType(RuleMatcher
&RM
) const;
317 explicit operator bool() const { return R
!= nullptr; }
319 bool operator==(const PatternType
&Other
) const;
320 bool operator!=(const PatternType
&Other
) const { return !operator==(Other
); }
322 std::string
str() const;
325 StringRef
getRawOpName() const { return R
->getValueAsString("OpName"); }
327 const Record
*R
= nullptr;
330 StringRef
PatternType::getTypeOfOpName() const {
332 StringRef Name
= getRawOpName();
333 Name
.consume_front("$");
337 LLTCodeGen
PatternType::getLLTCodeGen() const {
339 return *MVTToLLT(getValueType(R
));
343 PatternType::getLLTCodeGenOrTempType(RuleMatcher
&RM
) const {
344 assert(isValidType());
347 return getLLTCodeGen();
350 auto &OM
= RM
.getOperandMatcher(getTypeOfOpName());
351 return OM
.getTempTypeIdx(RM
);
354 bool PatternType::checkSemantics(ArrayRef
<SMLoc
> DiagLoc
) const {
358 auto RawOpName
= getRawOpName();
359 if (RawOpName
.starts_with("$"))
362 PrintError(DiagLoc
, "invalid operand name format '" + RawOpName
+ "' in " +
364 ": expected '$' followed by an operand name");
368 bool PatternType::operator==(const PatternType
&Other
) const {
370 if (R
&& R
->getName() != Other
.R
->getName()) {
371 dbgs() << "Same ptr but: " << R
->getName() << " and "
372 << Other
.R
->getName() << "?\n";
378 if (isTypeOf() && Other
.isTypeOf())
379 return getTypeOfOpName() == Other
.getTypeOfOpName();
384 std::string
PatternType::str() const {
392 return R
->getName().str();
397 return (TypeOfClassName
+ "<$" + getTypeOfOpName() + ">").str();
399 llvm_unreachable("Unknown type!");
402 //===- Pattern Base Class -------------------------------------------------===//
404 /// Base class for all patterns that can be written in an `apply`, `match` or
405 /// `pattern` DAG operator.
409 /// (apply (G_ZEXT $x, $y), (G_ZEXT $y, $z), "return isFoo(${z})")
411 /// Creates 3 Pattern objects:
412 /// - Two CodeGenInstruction Patterns
420 K_CodeGenInstruction
,
425 virtual ~Pattern() = default;
427 unsigned getKind() const { return Kind
; }
428 const char *getKindName() const;
430 bool hasName() const { return !Name
.empty(); }
431 StringRef
getName() const { return Name
; }
433 virtual void print(raw_ostream
&OS
, bool PrintName
= true) const = 0;
434 void dump() const { return print(dbgs()); }
437 Pattern(unsigned Kind
, StringRef Name
)
438 : Kind(Kind
), Name(insertStrRef(Name
)) {
439 assert(!Name
.empty() && "unnamed pattern!");
442 void printImpl(raw_ostream
&OS
, bool PrintName
,
443 function_ref
<void()> ContentPrinter
) const;
450 const char *Pattern::getKindName() const {
453 return "AnyOpcodePattern";
456 case K_CodeGenInstruction
:
457 return "CodeGenInstructionPattern";
459 return "PatFragPattern";
461 return "BuiltinPattern";
464 llvm_unreachable("unknown pattern kind!");
467 void Pattern::printImpl(raw_ostream
&OS
, bool PrintName
,
468 function_ref
<void()> ContentPrinter
) const {
469 OS
<< "(" << getKindName() << " ";
471 OS
<< "name:" << getName() << " ";
476 //===- AnyOpcodePattern ---------------------------------------------------===//
478 /// `wip_match_opcode` patterns.
479 /// This matches one or more opcodes, and does not check any operands
482 /// TODO: Long-term, this needs to be removed. It's a hack around MIR
483 /// pattern matching limitations.
484 class AnyOpcodePattern
: public Pattern
{
486 AnyOpcodePattern(StringRef Name
) : Pattern(K_AnyOpcode
, Name
) {}
488 static bool classof(const Pattern
*P
) { return P
->getKind() == K_AnyOpcode
; }
490 void addOpcode(const CodeGenInstruction
*I
) { Insts
.push_back(I
); }
491 const auto &insts() const { return Insts
; }
493 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
496 SmallVector
<const CodeGenInstruction
*, 4> Insts
;
499 void AnyOpcodePattern::print(raw_ostream
&OS
, bool PrintName
) const {
500 printImpl(OS
, PrintName
, [&OS
, this]() {
502 << join(map_range(Insts
,
503 [](const auto *I
) { return I
->TheDef
->getName(); }),
509 //===- CXXPattern ---------------------------------------------------------===//
511 /// Represents raw C++ code which may need some expansions.
513 /// e.g. [{ return isFooBux(${src}.getReg()); }]
515 /// For the expanded code, \see CXXPredicateCode. CXXPredicateCode objects are
516 /// created through `expandCode`.
518 /// \see CodeExpander and \see CodeExpansions for more information on code
521 /// This object has two purposes:
522 /// - Represent C++ code as a pattern entry.
523 /// - Be a factory for expanded C++ code.
524 /// - It's immutable and only holds the raw code so we can expand the same
525 /// CXX pattern multiple times if we need to.
527 /// Note that the code is always trimmed in the constructor, so leading and
528 /// trailing whitespaces are removed. This removes bloat in the output, avoids
529 /// formatting issues, but also allows us to check things like
530 /// `.startswith("return")` trivially without worrying about spaces.
531 class CXXPattern
: public Pattern
{
533 CXXPattern(const StringInit
&Code
, StringRef Name
)
534 : CXXPattern(Code
.getAsUnquotedString(), Name
) {}
536 CXXPattern(StringRef Code
, StringRef Name
)
537 : Pattern(K_CXX
, Name
), RawCode(Code
.trim().str()) {}
539 static bool classof(const Pattern
*P
) { return P
->getKind() == K_CXX
; }
541 void setIsApply(bool Value
= true) { IsApply
= Value
; }
542 StringRef
getRawCode() const { return RawCode
; }
544 /// Expands raw code, replacing things such as `${foo}` with their
545 /// substitution in \p CE.
547 /// \param CE Map of Code Expansions
548 /// \param Locs SMLocs for the Code Expander, in case it needs to emit
550 /// \param AddComment If DebugCXXPreds is enabled, this is called to emit a
551 /// comment before the expanded code.
553 /// \return A CXXPredicateCode object that contains the expanded code. Note
554 /// that this may or may not insert a new object. All CXXPredicateCode objects
555 /// are held in a set to avoid emitting duplicate C++ code.
556 const CXXPredicateCode
&
557 expandCode(const CodeExpansions
&CE
, ArrayRef
<SMLoc
> Locs
,
558 function_ref
<void(raw_ostream
&)> AddComment
= {}) const;
560 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
563 bool IsApply
= false;
567 const CXXPredicateCode
&
568 CXXPattern::expandCode(const CodeExpansions
&CE
, ArrayRef
<SMLoc
> Locs
,
569 function_ref
<void(raw_ostream
&)> AddComment
) const {
571 raw_string_ostream
OS(Result
);
573 if (DebugCXXPreds
&& AddComment
)
576 CodeExpander
Expander(RawCode
, CE
, Locs
, /*ShowExpansions*/ false);
579 return CXXPredicateCode::getApplyCode(std::move(Result
));
580 return CXXPredicateCode::getMatchCode(std::move(Result
));
583 void CXXPattern::print(raw_ostream
&OS
, bool PrintName
) const {
584 printImpl(OS
, PrintName
, [&OS
, this] {
585 OS
<< (IsApply
? "apply" : "match") << " code:\"";
586 printEscapedString(getRawCode(), OS
);
591 //===- InstructionPattern ---------------------------------------------===//
593 /// An operand for an InstructionPattern.
595 /// Operands are composed of three elements:
596 /// - (Optional) Value
597 /// - (Optional) Name
598 /// - (Optional) Type
601 /// (i32 0):$x -> V=int(0), Name='x', Type=i32
602 /// 0:$x -> V=int(0), Name='x'
604 /// i32:$x -> Name='x', Type = i32
605 class InstructionOperand
{
607 using IntImmTy
= int64_t;
609 InstructionOperand(IntImmTy Imm
, StringRef Name
, PatternType Type
)
610 : Value(Imm
), Name(insertStrRef(Name
)), Type(Type
) {
611 assert(Type
.isValidType());
614 InstructionOperand(StringRef Name
, PatternType Type
)
615 : Name(insertStrRef(Name
)), Type(Type
) {
616 assert(Type
.isValidType());
619 bool isNamedImmediate() const { return hasImmValue() && isNamedOperand(); }
621 bool hasImmValue() const { return Value
.has_value(); }
622 IntImmTy
getImmValue() const { return *Value
; }
624 bool isNamedOperand() const { return !Name
.empty(); }
625 StringRef
getOperandName() const {
626 assert(isNamedOperand() && "Operand is unnamed");
630 InstructionOperand
withNewName(StringRef NewName
) const {
631 InstructionOperand Result
= *this;
632 Result
.Name
= insertStrRef(NewName
);
636 void setIsDef(bool Value
= true) { Def
= Value
; }
637 bool isDef() const { return Def
; }
639 void setType(PatternType NewType
) {
640 assert((!Type
|| (Type
== NewType
)) && "Overwriting type!");
641 assert(NewType
.isValidType());
644 PatternType
getType() const { return Type
; }
646 std::string
describe() const {
648 return "MachineOperand $" + getOperandName().str() + "";
649 std::string Str
= "imm " + to_string(getImmValue());
650 if (isNamedImmediate())
651 Str
+= ":$" + getOperandName().str() + "";
655 void print(raw_ostream
&OS
) const {
659 bool NeedsColon
= true;
662 OS
<< "(" << Type
.str() << " " << getImmValue() << ")";
665 } else if (hasImmValue())
670 if (isNamedOperand())
671 OS
<< (NeedsColon
? ":" : "") << "$" << getOperandName();
674 void dump() const { return print(dbgs()); }
677 std::optional
<int64_t> Value
;
683 /// Base class for CodeGenInstructionPattern & PatFragPattern, which handles all
684 /// the boilerplate for patterns that have a list of operands for some (pseudo)
686 class InstructionPattern
: public Pattern
{
688 virtual ~InstructionPattern() = default;
690 static bool classof(const Pattern
*P
) {
691 return P
->getKind() == K_CodeGenInstruction
|| P
->getKind() == K_PatFrag
||
692 P
->getKind() == K_Builtin
;
695 template <typename
... Ty
> void addOperand(Ty
&&...Init
) {
696 Operands
.emplace_back(std::forward
<Ty
>(Init
)...);
699 auto &operands() { return Operands
; }
700 const auto &operands() const { return Operands
; }
701 unsigned operands_size() const { return Operands
.size(); }
702 InstructionOperand
&getOperand(unsigned K
) { return Operands
[K
]; }
703 const InstructionOperand
&getOperand(unsigned K
) const { return Operands
[K
]; }
705 /// When this InstructionPattern is used as the match root, returns the
706 /// operands that must be redefined in the 'apply' pattern for the rule to be
709 /// For most patterns, this just returns the defs.
710 /// For PatFrag this only returns the root of the PF.
712 /// Returns an empty array on error.
713 virtual ArrayRef
<InstructionOperand
> getApplyDefsNeeded() const {
714 return {operands().begin(), getNumInstDefs()};
717 auto named_operands() {
718 return make_filter_range(Operands
,
719 [&](auto &O
) { return O
.isNamedOperand(); });
722 auto named_operands() const {
723 return make_filter_range(Operands
,
724 [&](auto &O
) { return O
.isNamedOperand(); });
727 virtual bool isVariadic() const { return false; }
728 virtual unsigned getNumInstOperands() const = 0;
729 virtual unsigned getNumInstDefs() const = 0;
731 bool hasAllDefs() const { return operands_size() >= getNumInstDefs(); }
733 virtual StringRef
getInstName() const = 0;
735 /// Diagnoses all uses of special types in this Pattern and returns true if at
736 /// least one diagnostic was emitted.
737 bool diagnoseAllSpecialTypes(ArrayRef
<SMLoc
> Loc
, Twine Msg
) const;
739 void reportUnreachable(ArrayRef
<SMLoc
> Locs
) const;
740 virtual bool checkSemantics(ArrayRef
<SMLoc
> Loc
);
742 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
745 InstructionPattern(unsigned K
, StringRef Name
) : Pattern(K
, Name
) {}
747 SmallVector
<InstructionOperand
, 4> Operands
;
750 bool InstructionPattern::diagnoseAllSpecialTypes(ArrayRef
<SMLoc
> Loc
,
752 bool HasDiag
= false;
753 for (const auto &[Idx
, Op
] : enumerate(operands())) {
754 if (Op
.getType().isSpecial()) {
755 PrintError(Loc
, Msg
);
756 PrintNote(Loc
, "operand " + Twine(Idx
) + " of '" + getName() +
757 "' has type '" + Op
.getType().str() + "'");
764 void InstructionPattern::reportUnreachable(ArrayRef
<SMLoc
> Locs
) const {
765 PrintError(Locs
, "pattern '" + getName() + "' ('" + getInstName() +
766 "') is unreachable from the pattern root!");
769 bool InstructionPattern::checkSemantics(ArrayRef
<SMLoc
> Loc
) {
770 unsigned NumExpectedOperands
= getNumInstOperands();
773 if (Operands
.size() < NumExpectedOperands
) {
774 PrintError(Loc
, +"'" + getInstName() + "' expected at least " +
775 Twine(NumExpectedOperands
) + " operands, got " +
776 Twine(Operands
.size()));
779 } else if (NumExpectedOperands
!= Operands
.size()) {
780 PrintError(Loc
, +"'" + getInstName() + "' expected " +
781 Twine(NumExpectedOperands
) + " operands, got " +
782 Twine(Operands
.size()));
787 unsigned NumDefs
= getNumInstDefs();
788 for (auto &Op
: Operands
)
789 Op
.setIsDef(OpIdx
++ < NumDefs
);
794 void InstructionPattern::print(raw_ostream
&OS
, bool PrintName
) const {
795 printImpl(OS
, PrintName
, [&OS
, this] {
796 OS
<< getInstName() << " operands:[";
798 for (const auto &Op
: Operands
) {
807 //===- OperandTable -------------------------------------------------------===//
809 /// Maps InstructionPattern operands to their definitions. This allows us to tie
810 /// different patterns of a (apply), (match) or (patterns) set of patterns
812 template <typename DefTy
= InstructionPattern
> class OperandTable
{
814 static_assert(std::is_base_of_v
<InstructionPattern
, DefTy
>,
815 "DefTy should be a derived class from InstructionPattern");
817 bool addPattern(DefTy
*P
, function_ref
<void(StringRef
)> DiagnoseRedef
) {
818 for (const auto &Op
: P
->named_operands()) {
819 StringRef OpName
= Op
.getOperandName();
821 // We always create an entry in the OperandTable, even for uses.
822 // Uses of operands that don't have a def (= live-ins) will remain with a
823 // nullptr as the Def.
825 // This allows us tell whether an operand exists in a pattern or not. If
826 // there is no entry for it, it doesn't exist, if there is an entry, it's
827 // used/def'd at least once.
828 auto &Def
= Table
[OpName
];
834 DiagnoseRedef(OpName
);
844 struct LookupResult
{
845 LookupResult() = default;
846 LookupResult(DefTy
*Def
) : Found(true), Def(Def
) {}
849 DefTy
*Def
= nullptr;
851 bool isLiveIn() const { return Found
&& !Def
; }
854 LookupResult
lookup(StringRef OpName
) const {
855 if (auto It
= Table
.find(OpName
); It
!= Table
.end())
856 return LookupResult(It
->second
);
857 return LookupResult();
860 DefTy
*getDef(StringRef OpName
) const { return lookup(OpName
).Def
; }
862 void print(raw_ostream
&OS
, StringRef Name
= "",
863 StringRef Indent
= "") const {
864 OS
<< Indent
<< "(OperandTable ";
872 SmallVector
<StringRef
, 0> Keys(Table
.keys());
876 for (const auto &Key
: Keys
) {
877 const auto *Def
= Table
.at(Key
);
878 OS
<< Indent
<< " " << Key
<< " -> "
879 << (Def
? Def
->getName() : "<live-in>") << "\n";
881 OS
<< Indent
<< ")\n";
884 auto begin() const { return Table
.begin(); }
885 auto end() const { return Table
.end(); }
887 void dump() const { print(dbgs()); }
890 StringMap
<DefTy
*> Table
;
893 //===- CodeGenInstructionPattern ------------------------------------------===//
895 /// Matches an instruction, e.g. `G_ADD $x, $y, $z`.
896 class CodeGenInstructionPattern
: public InstructionPattern
{
898 CodeGenInstructionPattern(const CodeGenInstruction
&I
, StringRef Name
)
899 : InstructionPattern(K_CodeGenInstruction
, Name
), I(I
) {}
901 static bool classof(const Pattern
*P
) {
902 return P
->getKind() == K_CodeGenInstruction
;
905 bool is(StringRef OpcodeName
) const {
906 return I
.TheDef
->getName() == OpcodeName
;
909 bool hasVariadicDefs() const;
910 bool isVariadic() const override
{ return I
.Operands
.isVariadic
; }
911 unsigned getNumInstDefs() const override
;
912 unsigned getNumInstOperands() const override
;
914 const CodeGenInstruction
&getInst() const { return I
; }
915 StringRef
getInstName() const override
{ return I
.TheDef
->getName(); }
918 const CodeGenInstruction
&I
;
921 bool CodeGenInstructionPattern::hasVariadicDefs() const {
922 // Note: we cannot use variadicOpsAreDefs, it's not set for
923 // GenericInstructions.
927 if (I
.variadicOpsAreDefs
)
930 DagInit
*OutOps
= I
.TheDef
->getValueAsDag("OutOperandList");
931 if (OutOps
->arg_empty())
934 auto *LastArgTy
= dyn_cast
<DefInit
>(OutOps
->getArg(OutOps
->arg_size() - 1));
935 return LastArgTy
&& LastArgTy
->getDef()->getName() == "variable_ops";
938 unsigned CodeGenInstructionPattern::getNumInstDefs() const {
939 if (!isVariadic() || !hasVariadicDefs())
940 return I
.Operands
.NumDefs
;
941 unsigned NumOuts
= I
.Operands
.size() - I
.Operands
.NumDefs
;
942 assert(Operands
.size() > NumOuts
);
943 return std::max
<unsigned>(I
.Operands
.NumDefs
, Operands
.size() - NumOuts
);
946 unsigned CodeGenInstructionPattern::getNumInstOperands() const {
947 unsigned NumCGIOps
= I
.Operands
.size();
948 return isVariadic() ? std::max
<unsigned>(NumCGIOps
, Operands
.size())
952 //===- OperandTypeChecker -------------------------------------------------===//
954 /// This is a trivial type checker for all operands in a set of
955 /// InstructionPatterns.
957 /// It infers the type of each operand, check it's consistent with the known
958 /// type of the operand, and then sets all of the types in all operands in
959 /// setAllOperandTypes.
961 /// It also handles verifying correctness of special types.
962 class OperandTypeChecker
{
964 OperandTypeChecker(ArrayRef
<SMLoc
> DiagLoc
) : DiagLoc(DiagLoc
) {}
966 bool check(InstructionPattern
*P
,
967 std::function
<bool(const PatternType
&)> VerifyTypeOfOperand
);
969 void setAllOperandTypes();
974 InstructionPattern
*TypeSrc
= nullptr;
977 ArrayRef
<SMLoc
> DiagLoc
;
978 StringMap
<OpTypeInfo
> Types
;
980 SmallVector
<InstructionPattern
*, 16> Pats
;
983 bool OperandTypeChecker::check(
984 InstructionPattern
*P
,
985 std::function
<bool(const PatternType
&)> VerifyTypeOfOperand
) {
988 for (auto &Op
: P
->operands()) {
989 const auto Ty
= Op
.getType();
993 if (!Ty
.checkSemantics(DiagLoc
))
996 if (Ty
.isTypeOf() && !VerifyTypeOfOperand(Ty
))
999 if (!Op
.isNamedOperand())
1002 auto &Info
= Types
[Op
.getOperandName()];
1009 if (Info
.Type
!= Ty
) {
1010 PrintError(DiagLoc
, "conflicting types for operand '" +
1011 Op
.getOperandName() + "': first seen with '" +
1012 Info
.Type
.str() + "' in '" +
1013 Info
.TypeSrc
->getName() + ", now seen with '" +
1014 Ty
.str() + "' in '" + P
->getName() + "'");
1022 void OperandTypeChecker::setAllOperandTypes() {
1023 for (auto *Pat
: Pats
) {
1024 for (auto &Op
: Pat
->named_operands()) {
1025 if (auto &Info
= Types
[Op
.getOperandName()]; Info
.Type
)
1026 Op
.setType(Info
.Type
);
1031 //===- PatFrag ------------------------------------------------------------===//
1033 /// Represents a parsed GICombinePatFrag. This can be thought of as the
1034 /// equivalent of a CodeGenInstruction, but for PatFragPatterns.
1036 /// PatFrags are made of 3 things:
1037 /// - Out parameters (defs)
1039 /// - A set of pattern lists (alternatives).
1041 /// If the PatFrag uses instruction patterns, the root must be one of the defs.
1043 /// Note that this DOES NOT represent the use of the PatFrag, only its
1044 /// definition. The use of the PatFrag in a Pattern is represented by
1047 /// PatFrags use the term "parameter" instead of operand because they're
1048 /// essentially macros, and using that name avoids confusion. Other than that,
1049 /// they're structured similarly to a MachineInstruction - all parameters
1050 /// (operands) are in the same list, with defs at the start. This helps mapping
1051 /// parameters to values, because, param N of a PatFrag is always operand N of a
1066 using ParamVec
= SmallVector
<Param
, 4>;
1067 using ParamIt
= ParamVec::const_iterator
;
1069 /// Represents an alternative of the PatFrag. When parsing a GICombinePatFrag,
1070 /// this is created from its "Alternatives" list. Each alternative is a list
1071 /// of patterns written wrapped in a `(pattern ...)` dag init.
1073 /// Each argument to the `pattern` DAG operator is parsed into a Pattern
1075 struct Alternative
{
1076 OperandTable
<> OpTable
;
1077 SmallVector
<std::unique_ptr
<Pattern
>, 4> Pats
;
1080 explicit PatFrag(const Record
&Def
) : Def(Def
) {
1081 assert(Def
.isSubClassOf(PatFragClassName
));
1084 static StringRef
getParamKindStr(ParamKind OK
);
1086 StringRef
getName() const { return Def
.getName(); }
1088 const Record
&getDef() const { return Def
; }
1089 ArrayRef
<SMLoc
> getLoc() const { return Def
.getLoc(); }
1091 Alternative
&addAlternative() { return Alts
.emplace_back(); }
1092 const Alternative
&getAlternative(unsigned K
) const { return Alts
[K
]; }
1093 unsigned num_alternatives() const { return Alts
.size(); }
1095 void addInParam(StringRef Name
, ParamKind Kind
);
1096 iterator_range
<ParamIt
> in_params() const;
1097 unsigned num_in_params() const { return Params
.size() - NumOutParams
; }
1099 void addOutParam(StringRef Name
, ParamKind Kind
);
1100 iterator_range
<ParamIt
> out_params() const;
1101 unsigned num_out_params() const { return NumOutParams
; }
1103 unsigned num_roots() const;
1104 unsigned num_params() const { return num_in_params() + num_out_params(); }
1106 /// Finds the operand \p Name and returns its index or -1 if not found.
1107 /// Remember that all params are part of the same list, with out params at the
1108 /// start. This means that the index returned can be used to access operands
1109 /// of InstructionPatterns.
1110 unsigned getParamIdx(StringRef Name
) const;
1111 const Param
&getParam(unsigned K
) const { return Params
[K
]; }
1113 bool canBeMatchRoot() const { return num_roots() == 1; }
1115 void print(raw_ostream
&OS
, StringRef Indent
= "") const;
1116 void dump() const { print(dbgs()); }
1118 /// Checks if the in-param \p ParamName can be unbound or not.
1119 /// \p ArgName is the name of the argument passed to the PatFrag.
1121 /// An argument can be unbound only if, for all alternatives:
1122 /// - There is no CXX pattern, OR:
1123 /// - There is an InstructionPattern that binds the parameter.
1125 /// e.g. in (MyPatFrag $foo), if $foo has never been seen before (= it's
1126 /// unbound), this checks if MyPatFrag supports it or not.
1127 bool handleUnboundInParam(StringRef ParamName
, StringRef ArgName
,
1128 ArrayRef
<SMLoc
> DiagLoc
) const;
1130 bool checkSemantics();
1131 bool buildOperandsTables();
1134 static void printParamsList(raw_ostream
&OS
, iterator_range
<ParamIt
> Params
);
1136 void PrintError(Twine Msg
) const { ::PrintError(&Def
, Msg
); }
1139 unsigned NumOutParams
= 0;
1141 SmallVector
<Alternative
, 2> Alts
;
1144 StringRef
PatFrag::getParamKindStr(ParamKind OK
) {
1148 case PK_MachineOperand
:
1149 return "machine_operand";
1154 llvm_unreachable("Unknown operand kind!");
1157 void PatFrag::addInParam(StringRef Name
, ParamKind Kind
) {
1158 Params
.emplace_back(Param
{insertStrRef(Name
), Kind
});
1161 iterator_range
<PatFrag::ParamIt
> PatFrag::in_params() const {
1162 return {Params
.begin() + NumOutParams
, Params
.end()};
1165 void PatFrag::addOutParam(StringRef Name
, ParamKind Kind
) {
1166 assert(NumOutParams
== Params
.size() &&
1167 "Adding out-param after an in-param!");
1168 Params
.emplace_back(Param
{insertStrRef(Name
), Kind
});
1172 iterator_range
<PatFrag::ParamIt
> PatFrag::out_params() const {
1173 return {Params
.begin(), Params
.begin() + NumOutParams
};
1176 unsigned PatFrag::num_roots() const {
1177 return count_if(out_params(),
1178 [&](const auto &P
) { return P
.Kind
== PK_Root
; });
1181 unsigned PatFrag::getParamIdx(StringRef Name
) const {
1182 for (const auto &[Idx
, Op
] : enumerate(Params
)) {
1183 if (Op
.Name
== Name
)
1190 bool PatFrag::checkSemantics() {
1191 for (const auto &Alt
: Alts
) {
1192 for (const auto &Pat
: Alt
.Pats
) {
1193 switch (Pat
->getKind()) {
1194 case Pattern::K_AnyOpcode
:
1195 PrintError("wip_match_opcode cannot be used in " + PatFragClassName
);
1197 case Pattern::K_Builtin
:
1198 PrintError("Builtin instructions cannot be used in " +
1201 case Pattern::K_CXX
:
1203 case Pattern::K_CodeGenInstruction
:
1204 if (cast
<CodeGenInstructionPattern
>(Pat
.get())->diagnoseAllSpecialTypes(
1205 Def
.getLoc(), SpecialTyClassName
+ " is not supported in " +
1209 case Pattern::K_PatFrag
:
1210 // TODO: It's just that the emitter doesn't handle it but technically
1211 // there is no reason why we can't. We just have to be careful with
1212 // operand mappings, it could get complex.
1213 PrintError("nested " + PatFragClassName
+ " are not supported");
1219 StringSet
<> SeenOps
;
1220 for (const auto &Op
: in_params()) {
1221 if (SeenOps
.count(Op
.Name
)) {
1222 PrintError("duplicate parameter '" + Op
.Name
+ "'");
1226 // Check this operand is NOT defined in any alternative's patterns.
1227 for (const auto &Alt
: Alts
) {
1228 if (Alt
.OpTable
.lookup(Op
.Name
).Def
) {
1229 PrintError("input parameter '" + Op
.Name
+ "' cannot be redefined!");
1234 if (Op
.Kind
== PK_Root
) {
1235 PrintError("input parameterr '" + Op
.Name
+ "' cannot be a root!");
1239 SeenOps
.insert(Op
.Name
);
1242 for (const auto &Op
: out_params()) {
1243 if (Op
.Kind
!= PK_Root
&& Op
.Kind
!= PK_MachineOperand
) {
1244 PrintError("output parameter '" + Op
.Name
+
1245 "' must be 'root' or 'gi_mo'");
1249 if (SeenOps
.count(Op
.Name
)) {
1250 PrintError("duplicate parameter '" + Op
.Name
+ "'");
1254 // Check this operand is defined in all alternative's patterns.
1255 for (const auto &Alt
: Alts
) {
1256 const auto *OpDef
= Alt
.OpTable
.getDef(Op
.Name
);
1258 PrintError("output parameter '" + Op
.Name
+
1259 "' must be defined by all alternative patterns in '" +
1260 Def
.getName() + "'");
1264 if (Op
.Kind
== PK_Root
&& OpDef
->getNumInstDefs() != 1) {
1265 // The instruction that defines the root must have a single def.
1266 // Otherwise we'd need to support multiple roots and it gets messy.
1268 // e.g. this is not supported:
1269 // (pattern (G_UNMERGE_VALUES $x, $root, $vec))
1270 PrintError("all instructions that define root '" + Op
.Name
+ "' in '" +
1271 Def
.getName() + "' can only have a single output operand");
1276 SeenOps
.insert(Op
.Name
);
1279 if (num_out_params() != 0 && num_roots() == 0) {
1280 PrintError(PatFragClassName
+ " must have one root in its 'out' operands");
1284 if (num_roots() > 1) {
1285 PrintError(PatFragClassName
+ " can only have one root");
1289 // TODO: find unused params
1291 const auto CheckTypeOf
= [&](const PatternType
&) -> bool {
1292 llvm_unreachable("GITypeOf should have been rejected earlier!");
1295 // Now, typecheck all alternatives.
1296 for (auto &Alt
: Alts
) {
1297 OperandTypeChecker
OTC(Def
.getLoc());
1298 for (auto &Pat
: Alt
.Pats
) {
1299 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
1300 if (!OTC
.check(IP
, CheckTypeOf
))
1304 OTC
.setAllOperandTypes();
1310 bool PatFrag::handleUnboundInParam(StringRef ParamName
, StringRef ArgName
,
1311 ArrayRef
<SMLoc
> DiagLoc
) const {
1312 // The parameter must be a live-in of all alternatives for this to work.
1313 // Otherwise, we risk having unbound parameters being used (= crashes).
1317 // in (ins $y), (patterns (G_FNEG $dst, $y), "return matchFnegOp(${y})")
1318 // even if $y is unbound, we'll lazily bind it when emitting the G_FNEG.
1320 // in (ins $y), (patterns "return matchFnegOp(${y})")
1321 // if $y is unbound when this fragment is emitted, C++ code expansion will
1323 for (const auto &Alt
: Alts
) {
1324 auto &OT
= Alt
.OpTable
;
1325 if (!OT
.lookup(ParamName
).Found
) {
1326 ::PrintError(DiagLoc
, "operand '" + ArgName
+ "' (for parameter '" +
1327 ParamName
+ "' of '" + getName() +
1328 "') cannot be unbound");
1331 "one or more alternatives of '" + getName() + "' do not bind '" +
1333 "' to an instruction operand; either use a bound operand or "
1335 Def
.getName() + "' binds '" + ParamName
+
1336 "' in all alternatives");
1344 bool PatFrag::buildOperandsTables() {
1345 // enumerate(...) doesn't seem to allow lvalues so we need to count the old
1349 const auto DiagnoseRedef
= [this, &Idx
](StringRef OpName
) {
1350 PrintError("Operand '" + OpName
+
1351 "' is defined multiple times in patterns of alternative #" +
1355 for (auto &Alt
: Alts
) {
1356 for (auto &Pat
: Alt
.Pats
) {
1357 auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get());
1361 if (!Alt
.OpTable
.addPattern(IP
, DiagnoseRedef
))
1371 void PatFrag::print(raw_ostream
&OS
, StringRef Indent
) const {
1372 OS
<< Indent
<< "(PatFrag name:" << getName() << "\n";
1373 if (!in_params().empty()) {
1374 OS
<< Indent
<< " (ins ";
1375 printParamsList(OS
, in_params());
1379 if (!out_params().empty()) {
1380 OS
<< Indent
<< " (outs ";
1381 printParamsList(OS
, out_params());
1385 // TODO: Dump OperandTable as well.
1386 OS
<< Indent
<< " (alternatives [\n";
1387 for (const auto &Alt
: Alts
) {
1388 OS
<< Indent
<< " [\n";
1389 for (const auto &Pat
: Alt
.Pats
) {
1390 OS
<< Indent
<< " ";
1391 Pat
->print(OS
, /*PrintName=*/true);
1394 OS
<< Indent
<< " ],\n";
1396 OS
<< Indent
<< " ])\n";
1398 OS
<< Indent
<< ')';
1401 void PatFrag::printParamsList(raw_ostream
&OS
, iterator_range
<ParamIt
> Params
) {
1403 << join(map_range(Params
,
1405 return (O
.Name
+ ":" + getParamKindStr(O
.Kind
)).str();
1411 //===- PatFragPattern -----------------------------------------------------===//
1413 class PatFragPattern
: public InstructionPattern
{
1415 PatFragPattern(const PatFrag
&PF
, StringRef Name
)
1416 : InstructionPattern(K_PatFrag
, Name
), PF(PF
) {}
1418 static bool classof(const Pattern
*P
) { return P
->getKind() == K_PatFrag
; }
1420 const PatFrag
&getPatFrag() const { return PF
; }
1421 StringRef
getInstName() const override
{ return PF
.getName(); }
1423 unsigned getNumInstDefs() const override
{ return PF
.num_out_params(); }
1424 unsigned getNumInstOperands() const override
{ return PF
.num_params(); }
1426 ArrayRef
<InstructionOperand
> getApplyDefsNeeded() const override
;
1428 bool checkSemantics(ArrayRef
<SMLoc
> DiagLoc
) override
;
1430 /// Before emitting the patterns inside the PatFrag, add all necessary code
1431 /// expansions to \p PatFragCEs imported from \p ParentCEs.
1433 /// For a MachineOperand PatFrag parameter, this will fetch the expansion for
1434 /// that operand from \p ParentCEs and add it to \p PatFragCEs. Errors can be
1435 /// emitted if the MachineOperand reference is unbound.
1437 /// For an Immediate PatFrag parameter this simply adds the integer value to
1438 /// \p PatFragCEs as an expansion.
1440 /// \param ParentCEs Contains all of the code expansions declared by the other
1441 /// patterns emitted so far in the pattern list containing
1442 /// this PatFragPattern.
1443 /// \param PatFragCEs Output Code Expansions (usually empty)
1444 /// \param DiagLoc Diagnostic loc in case an error occurs.
1445 /// \return `true` on success, `false` on failure.
1446 bool mapInputCodeExpansions(const CodeExpansions
&ParentCEs
,
1447 CodeExpansions
&PatFragCEs
,
1448 ArrayRef
<SMLoc
> DiagLoc
) const;
1454 ArrayRef
<InstructionOperand
> PatFragPattern::getApplyDefsNeeded() const {
1455 assert(PF
.num_roots() == 1);
1456 // Only roots need to be redef.
1457 for (auto [Idx
, Param
] : enumerate(PF
.out_params())) {
1458 if (Param
.Kind
== PatFrag::PK_Root
)
1459 return getOperand(Idx
);
1461 llvm_unreachable("root not found!");
1464 bool PatFragPattern::checkSemantics(ArrayRef
<SMLoc
> DiagLoc
) {
1465 if (!InstructionPattern::checkSemantics(DiagLoc
))
1468 for (const auto &[Idx
, Op
] : enumerate(Operands
)) {
1469 switch (PF
.getParam(Idx
).Kind
) {
1470 case PatFrag::PK_Imm
:
1471 if (!Op
.hasImmValue()) {
1472 PrintError(DiagLoc
, "expected operand " + to_string(Idx
) + " of '" +
1473 getInstName() + "' to be an immediate; got " +
1477 if (Op
.isNamedImmediate()) {
1478 PrintError(DiagLoc
, "operand " + to_string(Idx
) + " of '" +
1480 "' cannot be a named immediate");
1484 case PatFrag::PK_Root
:
1485 case PatFrag::PK_MachineOperand
:
1486 if (!Op
.isNamedOperand() || Op
.isNamedImmediate()) {
1487 PrintError(DiagLoc
, "expected operand " + to_string(Idx
) + " of '" +
1489 "' to be a MachineOperand; got " +
1500 bool PatFragPattern::mapInputCodeExpansions(const CodeExpansions
&ParentCEs
,
1501 CodeExpansions
&PatFragCEs
,
1502 ArrayRef
<SMLoc
> DiagLoc
) const {
1503 for (const auto &[Idx
, Op
] : enumerate(operands())) {
1504 StringRef ParamName
= PF
.getParam(Idx
).Name
;
1506 // Operands to a PFP can only be named, or be an immediate, but not a named
1508 assert(!Op
.isNamedImmediate());
1510 if (Op
.isNamedOperand()) {
1511 StringRef ArgName
= Op
.getOperandName();
1512 // Map it only if it's been defined.
1513 auto It
= ParentCEs
.find(ArgName
);
1514 if (It
== ParentCEs
.end()) {
1515 if (!PF
.handleUnboundInParam(ParamName
, ArgName
, DiagLoc
))
1518 PatFragCEs
.declare(ParamName
, It
->second
);
1522 if (Op
.hasImmValue()) {
1523 PatFragCEs
.declare(ParamName
, to_string(Op
.getImmValue()));
1527 llvm_unreachable("Unknown Operand Type!");
1533 //===- BuiltinPattern -----------------------------------------------------===//
1540 class BuiltinPattern
: public InstructionPattern
{
1541 struct BuiltinInfo
{
1542 StringLiteral DefName
;
1548 static constexpr std::array
<BuiltinInfo
, 2> KnownBuiltins
= {{
1549 {"GIReplaceReg", BI_ReplaceReg
, 2, 1},
1550 {"GIEraseRoot", BI_EraseRoot
, 0, 0},
1554 BuiltinPattern(const Record
&Def
, StringRef Name
)
1555 : InstructionPattern(K_Builtin
, Name
), I(getBuiltinInfo(Def
)) {}
1557 static bool classof(const Pattern
*P
) { return P
->getKind() == K_Builtin
; }
1559 unsigned getNumInstOperands() const override
{ return I
.NumOps
; }
1560 unsigned getNumInstDefs() const override
{ return I
.NumDefs
; }
1561 StringRef
getInstName() const override
{ return I
.DefName
; }
1562 BuiltinKind
getBuiltinKind() const { return I
.Kind
; }
1564 bool checkSemantics(ArrayRef
<SMLoc
> Loc
) override
;
1567 static BuiltinInfo
getBuiltinInfo(const Record
&Def
);
1572 BuiltinPattern::BuiltinInfo
BuiltinPattern::getBuiltinInfo(const Record
&Def
) {
1573 assert(Def
.isSubClassOf(BuiltinInstClassName
));
1575 StringRef Name
= Def
.getName();
1576 for (const auto &KBI
: KnownBuiltins
) {
1577 if (KBI
.DefName
== Name
)
1581 PrintFatalError(Def
.getLoc(), "Unimplemented " + BuiltinInstClassName
+
1582 " def '" + Name
+ "'");
1585 bool BuiltinPattern::checkSemantics(ArrayRef
<SMLoc
> Loc
) {
1586 if (!InstructionPattern::checkSemantics(Loc
))
1589 // For now all builtins just take names, no immediates.
1590 for (const auto &[Idx
, Op
] : enumerate(operands())) {
1591 if (!Op
.isNamedOperand() || Op
.isNamedImmediate()) {
1592 PrintError(Loc
, "expected operand " + to_string(Idx
) + " of '" +
1593 getInstName() + "' to be a name");
1601 //===- PrettyStackTrace Helpers ------------------------------------------===//
1603 class PrettyStackTraceParse
: public PrettyStackTraceEntry
{
1607 PrettyStackTraceParse(const Record
&Def
) : Def(Def
) {}
1609 void print(raw_ostream
&OS
) const override
{
1610 if (Def
.isSubClassOf("GICombineRule"))
1611 OS
<< "Parsing GICombineRule '" << Def
.getName() << "'";
1612 else if (Def
.isSubClassOf(PatFragClassName
))
1613 OS
<< "Parsing " << PatFragClassName
<< " '" << Def
.getName() << "'";
1615 OS
<< "Parsing '" << Def
.getName() << "'";
1620 class PrettyStackTraceEmit
: public PrettyStackTraceEntry
{
1622 const Pattern
*Pat
= nullptr;
1625 PrettyStackTraceEmit(const Record
&Def
, const Pattern
*Pat
= nullptr)
1626 : Def(Def
), Pat(Pat
) {}
1628 void print(raw_ostream
&OS
) const override
{
1629 if (Def
.isSubClassOf("GICombineRule"))
1630 OS
<< "Emitting GICombineRule '" << Def
.getName() << "'";
1631 else if (Def
.isSubClassOf(PatFragClassName
))
1632 OS
<< "Emitting " << PatFragClassName
<< " '" << Def
.getName() << "'";
1634 OS
<< "Emitting '" << Def
.getName() << "'";
1637 OS
<< " [" << Pat
->getKindName() << " '" << Pat
->getName() << "']";
1642 //===- CombineRuleBuilder -------------------------------------------------===//
1644 /// Parses combine rule and builds a small intermediate representation to tie
1645 /// patterns together and emit RuleMatchers to match them. This may emit more
1646 /// than one RuleMatcher, e.g. for `wip_match_opcode`.
1648 /// Memory management for `Pattern` objects is done through `std::unique_ptr`.
1649 /// In most cases, there are two stages to a pattern's lifetime:
1650 /// - Creation in a `parse` function
1651 /// - The unique_ptr is stored in a variable, and may be destroyed if the
1652 /// pattern is found to be semantically invalid.
1653 /// - Ownership transfer into a `PatternMap`
1654 /// - Once a pattern is moved into either the map of Match or Apply
1655 /// patterns, it is known to be valid and it never moves back.
1656 class CombineRuleBuilder
{
1658 using PatternMap
= MapVector
<StringRef
, std::unique_ptr
<Pattern
>>;
1659 using PatternAlternatives
= DenseMap
<const Pattern
*, unsigned>;
1661 CombineRuleBuilder(const CodeGenTarget
&CGT
,
1662 SubtargetFeatureInfoMap
&SubtargetFeatures
,
1663 Record
&RuleDef
, unsigned ID
,
1664 std::vector
<RuleMatcher
> &OutRMs
)
1665 : CGT(CGT
), SubtargetFeatures(SubtargetFeatures
), RuleDef(RuleDef
),
1666 RuleID(ID
), OutRMs(OutRMs
) {}
1668 /// Parses all fields in the RuleDef record.
1671 /// Emits all RuleMatchers into the vector of RuleMatchers passed in the
1673 bool emitRuleMatchers();
1675 void print(raw_ostream
&OS
) const;
1676 void dump() const { print(dbgs()); }
1678 /// Debug-only verification of invariants.
1680 void verify() const;
1684 const CodeGenInstruction
&getGConstant() const {
1685 return CGT
.getInstruction(RuleDef
.getRecords().getDef("G_CONSTANT"));
1688 void PrintError(Twine Msg
) const { ::PrintError(&RuleDef
, Msg
); }
1689 void PrintWarning(Twine Msg
) const { ::PrintWarning(RuleDef
.getLoc(), Msg
); }
1690 void PrintNote(Twine Msg
) const { ::PrintNote(RuleDef
.getLoc(), Msg
); }
1692 void print(raw_ostream
&OS
, const PatternAlternatives
&Alts
) const;
1694 bool addApplyPattern(std::unique_ptr
<Pattern
> Pat
);
1695 bool addMatchPattern(std::unique_ptr
<Pattern
> Pat
);
1697 /// Adds the expansions from \see MatchDatas to \p CE.
1698 void declareAllMatchDatasExpansions(CodeExpansions
&CE
) const;
1700 /// Adds a matcher \p P to \p IM, expanding its code using \p CE.
1701 /// Note that the predicate is added on the last InstructionMatcher.
1703 /// \p Alts is only used if DebugCXXPreds is enabled.
1704 void addCXXPredicate(RuleMatcher
&M
, const CodeExpansions
&CE
,
1705 const CXXPattern
&P
, const PatternAlternatives
&Alts
);
1707 /// Adds an apply \p P to \p IM, expanding its code using \p CE.
1708 void addCXXAction(RuleMatcher
&M
, const CodeExpansions
&CE
,
1709 const CXXPattern
&P
);
1711 bool hasOnlyCXXApplyPatterns() const;
1712 bool hasEraseRoot() const;
1714 // Infer machine operand types and check their consistency.
1715 bool typecheckPatterns();
1717 /// For all PatFragPatterns, add a new entry in PatternAlternatives for each
1718 /// PatternList it contains. This is multiplicative, so if we have 2
1719 /// PatFrags with 3 alternatives each, we get 2*3 permutations added to
1720 /// PermutationsToEmit. The "MaxPermutations" field controls how many
1721 /// permutations are allowed before an error is emitted and this function
1722 /// returns false. This is a simple safeguard to prevent combination of
1723 /// PatFrags from generating enormous amounts of rules.
1724 bool buildPermutationsToEmit();
1726 /// Checks additional semantics of the Patterns.
1727 bool checkSemantics();
1729 /// Creates a new RuleMatcher with some boilerplate
1730 /// settings/actions/predicates, and and adds it to \p OutRMs.
1731 /// \see addFeaturePredicates too.
1733 /// \param Alts Current set of alternatives, for debug comment.
1734 /// \param AdditionalComment Comment string to be added to the
1735 /// `DebugCommentAction`.
1736 RuleMatcher
&addRuleMatcher(const PatternAlternatives
&Alts
,
1737 Twine AdditionalComment
= "");
1738 bool addFeaturePredicates(RuleMatcher
&M
);
1741 bool buildRuleOperandsTable();
1743 bool parseDefs(const DagInit
&Def
);
1745 parsePatternList(const DagInit
&List
,
1746 function_ref
<bool(std::unique_ptr
<Pattern
>)> ParseAction
,
1747 StringRef Operator
, ArrayRef
<SMLoc
> DiagLoc
,
1748 StringRef AnonPatNamePrefix
) const;
1750 std::unique_ptr
<Pattern
> parseInstructionPattern(const Init
&Arg
,
1751 StringRef PatName
) const;
1752 std::unique_ptr
<Pattern
> parseWipMatchOpcodeMatcher(const Init
&Arg
,
1753 StringRef PatName
) const;
1754 bool parseInstructionPatternOperand(InstructionPattern
&IP
,
1756 const StringInit
*OpName
) const;
1757 std::unique_ptr
<PatFrag
> parsePatFragImpl(const Record
*Def
) const;
1758 bool parsePatFragParamList(
1759 ArrayRef
<SMLoc
> DiagLoc
, const DagInit
&OpsList
,
1760 function_ref
<bool(StringRef
, PatFrag::ParamKind
)> ParseAction
) const;
1761 const PatFrag
*parsePatFrag(const Record
*Def
) const;
1763 bool emitMatchPattern(CodeExpansions
&CE
, const PatternAlternatives
&Alts
,
1764 const InstructionPattern
&IP
);
1765 bool emitMatchPattern(CodeExpansions
&CE
, const PatternAlternatives
&Alts
,
1766 const AnyOpcodePattern
&AOP
);
1768 bool emitPatFragMatchPattern(CodeExpansions
&CE
,
1769 const PatternAlternatives
&Alts
, RuleMatcher
&RM
,
1770 InstructionMatcher
*IM
,
1771 const PatFragPattern
&PFP
,
1772 DenseSet
<const Pattern
*> &SeenPats
);
1774 bool emitApplyPatterns(CodeExpansions
&CE
, RuleMatcher
&M
);
1776 // Recursively visits InstructionPatterns from P to build up the
1777 // RuleMatcher actions.
1778 bool emitInstructionApplyPattern(CodeExpansions
&CE
, RuleMatcher
&M
,
1779 const InstructionPattern
&P
,
1780 DenseSet
<const Pattern
*> &SeenPats
,
1781 StringMap
<unsigned> &OperandToTempRegID
);
1783 bool emitCodeGenInstructionApplyImmOperand(RuleMatcher
&M
,
1784 BuildMIAction
&DstMI
,
1785 const CodeGenInstructionPattern
&P
,
1786 const InstructionOperand
&O
);
1788 bool emitBuiltinApplyPattern(CodeExpansions
&CE
, RuleMatcher
&M
,
1789 const BuiltinPattern
&P
,
1790 StringMap
<unsigned> &OperandToTempRegID
);
1792 // Recursively visits CodeGenInstructionPattern from P to build up the
1793 // RuleMatcher/InstructionMatcher. May create new InstructionMatchers as
1795 using OperandMapperFnRef
=
1796 function_ref
<InstructionOperand(const InstructionOperand
&)>;
1797 using OperandDefLookupFn
=
1798 function_ref
<const InstructionPattern
*(StringRef
)>;
1799 bool emitCodeGenInstructionMatchPattern(
1800 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&M
,
1801 InstructionMatcher
&IM
, const CodeGenInstructionPattern
&P
,
1802 DenseSet
<const Pattern
*> &SeenPats
, OperandDefLookupFn LookupOperandDef
,
1803 OperandMapperFnRef OperandMapper
= [](const auto &O
) { return O
; });
1805 const CodeGenTarget
&CGT
;
1806 SubtargetFeatureInfoMap
&SubtargetFeatures
;
1808 const unsigned RuleID
;
1809 std::vector
<RuleMatcher
> &OutRMs
;
1811 // For InstructionMatcher::addOperand
1812 unsigned AllocatedTemporariesBaseID
= 0;
1814 /// The root of the pattern.
1817 /// These maps have ownership of the actual Pattern objects.
1818 /// They both map a Pattern's name to the Pattern instance.
1819 PatternMap MatchPats
;
1820 PatternMap ApplyPats
;
1822 /// Operand tables to tie match/apply patterns together.
1823 OperandTable
<> MatchOpTable
;
1824 OperandTable
<> ApplyOpTable
;
1826 /// Set by findRoots.
1827 Pattern
*MatchRoot
= nullptr;
1828 SmallDenseSet
<InstructionPattern
*, 2> ApplyRoots
;
1830 SmallVector
<MatchDataInfo
, 2> MatchDatas
;
1831 SmallVector
<PatternAlternatives
, 1> PermutationsToEmit
;
1833 // print()/debug-only members.
1834 mutable SmallPtrSet
<const PatFrag
*, 2> SeenPatFrags
;
1837 bool CombineRuleBuilder::parseAll() {
1838 auto StackTrace
= PrettyStackTraceParse(RuleDef
);
1840 if (!parseDefs(*RuleDef
.getValueAsDag("Defs")))
1843 if (!parsePatternList(
1844 *RuleDef
.getValueAsDag("Match"),
1845 [this](auto Pat
) { return addMatchPattern(std::move(Pat
)); }, "match",
1846 RuleDef
.getLoc(), (RuleDef
.getName() + "_match").str()))
1849 if (!parsePatternList(
1850 *RuleDef
.getValueAsDag("Apply"),
1851 [this](auto Pat
) { return addApplyPattern(std::move(Pat
)); }, "apply",
1852 RuleDef
.getLoc(), (RuleDef
.getName() + "_apply").str()))
1855 if (!buildRuleOperandsTable() || !typecheckPatterns() || !findRoots() ||
1856 !checkSemantics() || !buildPermutationsToEmit())
1858 LLVM_DEBUG(verify());
1862 bool CombineRuleBuilder::emitRuleMatchers() {
1863 auto StackTrace
= PrettyStackTraceEmit(RuleDef
);
1867 declareAllMatchDatasExpansions(CE
);
1869 assert(!PermutationsToEmit
.empty());
1870 for (const auto &Alts
: PermutationsToEmit
) {
1871 switch (MatchRoot
->getKind()) {
1872 case Pattern::K_AnyOpcode
: {
1873 if (!emitMatchPattern(CE
, Alts
, *cast
<AnyOpcodePattern
>(MatchRoot
)))
1877 case Pattern::K_PatFrag
:
1878 case Pattern::K_Builtin
:
1879 case Pattern::K_CodeGenInstruction
:
1880 if (!emitMatchPattern(CE
, Alts
, *cast
<InstructionPattern
>(MatchRoot
)))
1883 case Pattern::K_CXX
:
1884 PrintError("C++ code cannot be the root of a rule!");
1887 llvm_unreachable("unknown pattern kind!");
1894 void CombineRuleBuilder::print(raw_ostream
&OS
) const {
1895 OS
<< "(CombineRule name:" << RuleDef
.getName() << " id:" << RuleID
1896 << " root:" << RootName
<< "\n";
1898 if (!MatchDatas
.empty()) {
1899 OS
<< " (MatchDatas\n";
1900 for (const auto &MD
: MatchDatas
) {
1908 if (!SeenPatFrags
.empty()) {
1909 OS
<< " (PatFrags\n";
1910 for (const auto *PF
: SeenPatFrags
) {
1911 PF
->print(OS
, /*Indent=*/" ");
1917 const auto DumpPats
= [&](StringRef Name
, const PatternMap
&Pats
) {
1918 OS
<< " (" << Name
<< " ";
1925 for (const auto &[Name
, Pat
] : Pats
) {
1927 if (Pat
.get() == MatchRoot
)
1928 OS
<< "<match_root>";
1929 if (isa
<InstructionPattern
>(Pat
.get()) &&
1930 ApplyRoots
.contains(cast
<InstructionPattern
>(Pat
.get())))
1931 OS
<< "<apply_root>";
1933 Pat
->print(OS
, /*PrintName=*/false);
1939 DumpPats("MatchPats", MatchPats
);
1940 DumpPats("ApplyPats", ApplyPats
);
1942 MatchOpTable
.print(OS
, "MatchPats", /*Indent*/ " ");
1943 ApplyOpTable
.print(OS
, "ApplyPats", /*Indent*/ " ");
1945 if (PermutationsToEmit
.size() > 1) {
1946 OS
<< " (PermutationsToEmit\n";
1947 for (const auto &Perm
: PermutationsToEmit
) {
1959 void CombineRuleBuilder::verify() const {
1960 const auto VerifyPats
= [&](const PatternMap
&Pats
) {
1961 for (const auto &[Name
, Pat
] : Pats
) {
1963 PrintFatalError("null pattern in pattern map!");
1965 if (Name
!= Pat
->getName()) {
1967 PrintFatalError("Pattern name mismatch! Map name: " + Name
+
1968 ", Pat name: " + Pat
->getName());
1971 // Sanity check: the map should point to the same data as the Pattern.
1972 // Both strings are allocated in the pool using insertStrRef.
1973 if (Name
.data() != Pat
->getName().data()) {
1974 dbgs() << "Map StringRef: '" << Name
<< "' @ "
1975 << (const void *)Name
.data() << "\n";
1976 dbgs() << "Pat String: '" << Pat
->getName() << "' @ "
1977 << (const void *)Pat
->getName().data() << "\n";
1978 PrintFatalError("StringRef stored in the PatternMap is not referencing "
1979 "the same string as its Pattern!");
1984 VerifyPats(MatchPats
);
1985 VerifyPats(ApplyPats
);
1987 // Check there are no wip_match_opcode patterns in the "apply" patterns.
1988 if (any_of(ApplyPats
,
1989 [&](auto &E
) { return isa
<AnyOpcodePattern
>(E
.second
.get()); })) {
1992 "illegal wip_match_opcode pattern in the 'apply' patterns!");
1995 // Check there are no nullptrs in ApplyRoots.
1996 if (ApplyRoots
.contains(nullptr)) {
1998 "CombineRuleBuilder's ApplyRoots set contains a null pointer!");
2003 void CombineRuleBuilder::print(raw_ostream
&OS
,
2004 const PatternAlternatives
&Alts
) const {
2005 SmallVector
<std::string
, 1> Strings(
2006 map_range(Alts
, [](const auto &PatAndPerm
) {
2007 return PatAndPerm
.first
->getName().str() + "[" +
2008 to_string(PatAndPerm
.second
) + "]";
2010 // Sort so output is deterministic for tests. Otherwise it's sorted by pointer
2013 OS
<< "[" << join(Strings
, ", ") << "]";
2016 bool CombineRuleBuilder::addApplyPattern(std::unique_ptr
<Pattern
> Pat
) {
2017 StringRef Name
= Pat
->getName();
2018 if (ApplyPats
.contains(Name
)) {
2019 PrintError("'" + Name
+ "' apply pattern defined more than once!");
2023 if (isa
<AnyOpcodePattern
>(Pat
.get())) {
2024 PrintError("'" + Name
+
2025 "': wip_match_opcode is not supported in apply patterns");
2029 if (isa
<PatFragPattern
>(Pat
.get())) {
2030 PrintError("'" + Name
+ "': using " + PatFragClassName
+
2031 " is not supported in apply patterns");
2035 if (auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
.get()))
2036 CXXPat
->setIsApply();
2038 ApplyPats
[Name
] = std::move(Pat
);
2042 bool CombineRuleBuilder::addMatchPattern(std::unique_ptr
<Pattern
> Pat
) {
2043 StringRef Name
= Pat
->getName();
2044 if (MatchPats
.contains(Name
)) {
2045 PrintError("'" + Name
+ "' match pattern defined more than once!");
2049 // For now, none of the builtins can appear in 'match'.
2050 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(Pat
.get())) {
2051 PrintError("'" + BP
->getInstName() +
2052 "' cannot be used in a 'match' pattern");
2056 MatchPats
[Name
] = std::move(Pat
);
2060 void CombineRuleBuilder::declareAllMatchDatasExpansions(
2061 CodeExpansions
&CE
) const {
2062 for (const auto &MD
: MatchDatas
)
2063 CE
.declare(MD
.getPatternSymbol(), MD
.getQualifiedVariableName());
2066 void CombineRuleBuilder::addCXXPredicate(RuleMatcher
&M
,
2067 const CodeExpansions
&CE
,
2068 const CXXPattern
&P
,
2069 const PatternAlternatives
&Alts
) {
2070 // FIXME: Hack so C++ code is executed last. May not work for more complex
2072 auto &IM
= *std::prev(M
.insnmatchers().end());
2073 const auto &ExpandedCode
=
2074 P
.expandCode(CE
, RuleDef
.getLoc(), [&](raw_ostream
&OS
) {
2075 OS
<< "// Pattern Alternatives: ";
2079 IM
->addPredicate
<GenericInstructionPredicateMatcher
>(
2080 ExpandedCode
.getEnumNameWithPrefix(CXXPredPrefix
));
2083 void CombineRuleBuilder::addCXXAction(RuleMatcher
&M
, const CodeExpansions
&CE
,
2084 const CXXPattern
&P
) {
2085 const auto &ExpandedCode
= P
.expandCode(CE
, RuleDef
.getLoc());
2086 M
.addAction
<CustomCXXAction
>(
2087 ExpandedCode
.getEnumNameWithPrefix(CXXApplyPrefix
));
2090 bool CombineRuleBuilder::hasOnlyCXXApplyPatterns() const {
2091 return all_of(ApplyPats
, [&](auto &Entry
) {
2092 return isa
<CXXPattern
>(Entry
.second
.get());
2096 bool CombineRuleBuilder::hasEraseRoot() const {
2097 return any_of(ApplyPats
, [&](auto &Entry
) {
2098 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(Entry
.second
.get()))
2099 return BP
->getBuiltinKind() == BI_EraseRoot
;
2104 bool CombineRuleBuilder::typecheckPatterns() {
2105 OperandTypeChecker
OTC(RuleDef
.getLoc());
2107 const auto CheckMatchTypeOf
= [&](const PatternType
&) -> bool {
2108 // We'll reject those after we're done inferring
2112 for (auto &Pat
: values(MatchPats
)) {
2113 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
2114 if (!OTC
.check(IP
, CheckMatchTypeOf
))
2119 const auto CheckApplyTypeOf
= [&](const PatternType
&Ty
) {
2120 // GITypeOf<"$x"> can only be used if "$x" is a matched operand.
2121 const auto OpName
= Ty
.getTypeOfOpName();
2122 if (MatchOpTable
.lookup(OpName
).Found
)
2125 PrintError("'" + OpName
+ "' ('" + Ty
.str() +
2126 "') does not refer to a matched operand!");
2130 for (auto &Pat
: values(ApplyPats
)) {
2131 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
2132 if (!OTC
.check(IP
, CheckApplyTypeOf
))
2137 OTC
.setAllOperandTypes();
2139 // Always check this after in case inference adds some special types to the
2141 for (auto &Pat
: values(MatchPats
)) {
2142 if (auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
2143 if (IP
->diagnoseAllSpecialTypes(
2145 SpecialTyClassName
+ " is not supported in 'match' patterns")) {
2153 bool CombineRuleBuilder::buildPermutationsToEmit() {
2154 PermutationsToEmit
.clear();
2156 // Start with one empty set of alternatives.
2157 PermutationsToEmit
.emplace_back();
2158 for (const auto &Pat
: values(MatchPats
)) {
2159 unsigned NumAlts
= 0;
2160 // Note: technically, AnyOpcodePattern also needs permutations, but:
2161 // - We only allow a single one of them in the root.
2162 // - They cannot be mixed with any other pattern other than C++ code.
2163 // So we don't really need to take them into account here. We could, but
2164 // that pattern is a hack anyway and the less it's involved, the better.
2165 if (const auto *PFP
= dyn_cast
<PatFragPattern
>(Pat
.get()))
2166 NumAlts
= PFP
->getPatFrag().num_alternatives();
2170 // For each pattern that needs permutations, multiply the current set of
2172 auto CurPerms
= PermutationsToEmit
;
2173 PermutationsToEmit
.clear();
2175 for (const auto &Perm
: CurPerms
) {
2176 assert(!Perm
.count(Pat
.get()) && "Pattern already emitted?");
2177 for (unsigned K
= 0; K
< NumAlts
; ++K
) {
2178 PatternAlternatives NewPerm
= Perm
;
2179 NewPerm
[Pat
.get()] = K
;
2180 PermutationsToEmit
.emplace_back(std::move(NewPerm
));
2185 if (int64_t MaxPerms
= RuleDef
.getValueAsInt("MaxPermutations");
2187 if ((int64_t)PermutationsToEmit
.size() > MaxPerms
) {
2188 PrintError("cannot emit rule '" + RuleDef
.getName() + "'; " +
2189 Twine(PermutationsToEmit
.size()) +
2190 " permutations would be emitted, but the max is " +
2196 // Ensure we always have a single empty entry, it simplifies the emission
2197 // logic so it doesn't need to handle the case where there are no perms.
2198 if (PermutationsToEmit
.empty()) {
2199 PermutationsToEmit
.emplace_back();
2206 bool CombineRuleBuilder::checkSemantics() {
2207 assert(MatchRoot
&& "Cannot call this before findRoots()");
2209 bool UsesWipMatchOpcode
= false;
2210 for (const auto &Match
: MatchPats
) {
2211 const auto *Pat
= Match
.second
.get();
2213 if (const auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
)) {
2214 if (!CXXPat
->getRawCode().contains("return "))
2215 PrintWarning("'match' C++ code does not seem to return!");
2219 const auto *AOP
= dyn_cast
<AnyOpcodePattern
>(Pat
);
2223 if (UsesWipMatchOpcode
) {
2224 PrintError("wip_opcode_match can only be present once");
2228 UsesWipMatchOpcode
= true;
2231 for (const auto &Apply
: ApplyPats
) {
2232 assert(Apply
.second
.get());
2233 const auto *IP
= dyn_cast
<InstructionPattern
>(Apply
.second
.get());
2237 if (UsesWipMatchOpcode
) {
2238 PrintError("cannot use wip_match_opcode in combination with apply "
2239 "instruction patterns!");
2243 const auto *BIP
= dyn_cast
<BuiltinPattern
>(IP
);
2246 StringRef Name
= BIP
->getInstName();
2248 // (GIEraseInst) has to be the only apply pattern, or it can not be used at
2249 // all. The root cannot have any defs either.
2250 switch (BIP
->getBuiltinKind()) {
2251 case BI_EraseRoot
: {
2252 if (ApplyPats
.size() > 1) {
2253 PrintError(Name
+ " must be the only 'apply' pattern");
2257 const auto *IRoot
= dyn_cast
<CodeGenInstructionPattern
>(MatchRoot
);
2260 " can only be used if the root is a CodeGenInstruction");
2264 if (IRoot
->getNumInstDefs() != 0) {
2265 PrintError(Name
+ " can only be used if on roots that do "
2266 "not have any output operand");
2267 PrintNote("'" + IRoot
->getInstName() + "' has " +
2268 Twine(IRoot
->getNumInstDefs()) + " output operands");
2273 case BI_ReplaceReg
: {
2274 // (GIReplaceReg can only be used on the root instruction)
2275 // TODO: When we allow rewriting non-root instructions, also allow this.
2276 StringRef OldRegName
= BIP
->getOperand(0).getOperandName();
2277 auto *Def
= MatchOpTable
.getDef(OldRegName
);
2279 PrintError(Name
+ " cannot find a matched pattern that defines '" +
2283 if (MatchOpTable
.getDef(OldRegName
) != MatchRoot
) {
2284 PrintError(Name
+ " cannot replace '" + OldRegName
+
2285 "': this builtin can only replace a register defined by the "
2297 RuleMatcher
&CombineRuleBuilder::addRuleMatcher(const PatternAlternatives
&Alts
,
2298 Twine AdditionalComment
) {
2299 auto &RM
= OutRMs
.emplace_back(RuleDef
.getLoc());
2300 addFeaturePredicates(RM
);
2301 RM
.setPermanentGISelFlags(GISF_IgnoreCopies
);
2302 RM
.addRequiredSimplePredicate(getIsEnabledPredicateEnumName(RuleID
));
2304 std::string Comment
;
2305 raw_string_ostream
CommentOS(Comment
);
2306 CommentOS
<< "Combiner Rule #" << RuleID
<< ": " << RuleDef
.getName();
2307 if (!Alts
.empty()) {
2309 print(CommentOS
, Alts
);
2311 if (!AdditionalComment
.isTriviallyEmpty())
2312 CommentOS
<< "; " << AdditionalComment
;
2313 RM
.addAction
<DebugCommentAction
>(Comment
);
2317 bool CombineRuleBuilder::addFeaturePredicates(RuleMatcher
&M
) {
2318 if (!RuleDef
.getValue("Predicates"))
2321 ListInit
*Preds
= RuleDef
.getValueAsListInit("Predicates");
2322 for (Init
*PI
: Preds
->getValues()) {
2323 DefInit
*Pred
= dyn_cast
<DefInit
>(PI
);
2327 Record
*Def
= Pred
->getDef();
2328 if (!Def
->isSubClassOf("Predicate")) {
2329 ::PrintError(Def
, "Unknown 'Predicate' Type");
2333 if (Def
->getValueAsString("CondString").empty())
2336 if (SubtargetFeatures
.count(Def
) == 0) {
2337 SubtargetFeatures
.emplace(
2338 Def
, SubtargetFeatureInfo(Def
, SubtargetFeatures
.size()));
2341 M
.addRequiredFeature(Def
);
2347 bool CombineRuleBuilder::findRoots() {
2348 const auto Finish
= [&]() {
2351 if (hasOnlyCXXApplyPatterns() || hasEraseRoot())
2354 auto *IPRoot
= dyn_cast
<InstructionPattern
>(MatchRoot
);
2358 if (IPRoot
->getNumInstDefs() == 0) {
2359 // No defs to work with -> find the root using the pattern name.
2360 auto It
= ApplyPats
.find(RootName
);
2361 if (It
== ApplyPats
.end()) {
2362 PrintError("Cannot find root '" + RootName
+ "' in apply patterns!");
2366 auto *ApplyRoot
= dyn_cast
<InstructionPattern
>(It
->second
.get());
2368 PrintError("apply pattern root '" + RootName
+
2369 "' must be an instruction pattern");
2373 ApplyRoots
.insert(ApplyRoot
);
2377 // Collect all redefinitions of the MatchRoot's defs and put them in
2379 const auto DefsNeeded
= IPRoot
->getApplyDefsNeeded();
2380 for (auto &Op
: DefsNeeded
) {
2381 assert(Op
.isDef() && Op
.isNamedOperand());
2382 StringRef Name
= Op
.getOperandName();
2384 auto *ApplyRedef
= ApplyOpTable
.getDef(Name
);
2386 PrintError("'" + Name
+ "' must be redefined in the 'apply' pattern");
2390 ApplyRoots
.insert((InstructionPattern
*)ApplyRedef
);
2393 if (auto It
= ApplyPats
.find(RootName
); It
!= ApplyPats
.end()) {
2394 if (find(ApplyRoots
, It
->second
.get()) == ApplyRoots
.end()) {
2395 PrintError("apply pattern '" + RootName
+
2396 "' is supposed to be a root but it does not redefine any of "
2397 "the defs of the match root");
2405 // Look by pattern name, e.g.
2406 // (G_FNEG $x, $y):$root
2407 if (auto MatchPatIt
= MatchPats
.find(RootName
);
2408 MatchPatIt
!= MatchPats
.end()) {
2409 MatchRoot
= MatchPatIt
->second
.get();
2414 // (G_FNEG $root, $y)
2415 auto LookupRes
= MatchOpTable
.lookup(RootName
);
2416 if (!LookupRes
.Found
) {
2417 PrintError("Cannot find root '" + RootName
+ "' in match patterns!");
2421 MatchRoot
= LookupRes
.Def
;
2423 PrintError("Cannot use live-in operand '" + RootName
+
2424 "' as match pattern root!");
2431 bool CombineRuleBuilder::buildRuleOperandsTable() {
2432 const auto DiagnoseRedefMatch
= [&](StringRef OpName
) {
2433 PrintError("Operand '" + OpName
+
2434 "' is defined multiple times in the 'match' patterns");
2437 const auto DiagnoseRedefApply
= [&](StringRef OpName
) {
2438 PrintError("Operand '" + OpName
+
2439 "' is defined multiple times in the 'apply' patterns");
2442 for (auto &Pat
: values(MatchPats
)) {
2443 auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get());
2444 if (IP
&& !MatchOpTable
.addPattern(IP
, DiagnoseRedefMatch
))
2448 for (auto &Pat
: values(ApplyPats
)) {
2449 auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get());
2450 if (IP
&& !ApplyOpTable
.addPattern(IP
, DiagnoseRedefApply
))
2457 bool CombineRuleBuilder::parseDefs(const DagInit
&Def
) {
2458 if (Def
.getOperatorAsDef(RuleDef
.getLoc())->getName() != "defs") {
2459 PrintError("Expected defs operator");
2463 SmallVector
<StringRef
> Roots
;
2464 for (unsigned I
= 0, E
= Def
.getNumArgs(); I
< E
; ++I
) {
2465 if (isSpecificDef(*Def
.getArg(I
), "root")) {
2466 Roots
.emplace_back(Def
.getArgNameStr(I
));
2470 // Subclasses of GIDefMatchData should declare that this rule needs to pass
2471 // data from the match stage to the apply stage, and ensure that the
2472 // generated matcher has a suitable variable for it to do so.
2473 if (Record
*MatchDataRec
=
2474 getDefOfSubClass(*Def
.getArg(I
), "GIDefMatchData")) {
2475 MatchDatas
.emplace_back(Def
.getArgNameStr(I
),
2476 MatchDataRec
->getValueAsString("Type"));
2480 // Otherwise emit an appropriate error message.
2481 if (getDefOfSubClass(*Def
.getArg(I
), "GIDefKind"))
2482 PrintError("This GIDefKind not implemented in tablegen");
2483 else if (getDefOfSubClass(*Def
.getArg(I
), "GIDefKindWithArgs"))
2484 PrintError("This GIDefKindWithArgs not implemented in tablegen");
2486 PrintError("Expected a subclass of GIDefKind or a sub-dag whose "
2487 "operator is of type GIDefKindWithArgs");
2491 if (Roots
.size() != 1) {
2492 PrintError("Combine rules must have exactly one root");
2496 RootName
= Roots
.front();
2498 // Assign variables to all MatchDatas.
2499 AssignMatchDataVariables(MatchDatas
);
2503 bool CombineRuleBuilder::parsePatternList(
2504 const DagInit
&List
,
2505 function_ref
<bool(std::unique_ptr
<Pattern
>)> ParseAction
,
2506 StringRef Operator
, ArrayRef
<SMLoc
> DiagLoc
,
2507 StringRef AnonPatNamePrefix
) const {
2508 if (List
.getOperatorAsDef(RuleDef
.getLoc())->getName() != Operator
) {
2509 ::PrintError(DiagLoc
, "Expected " + Operator
+ " operator");
2513 if (List
.getNumArgs() == 0) {
2514 ::PrintError(DiagLoc
, Operator
+ " pattern list is empty");
2518 // The match section consists of a list of matchers and predicates. Parse each
2519 // one and add the equivalent GIMatchDag nodes, predicates, and edges.
2520 for (unsigned I
= 0; I
< List
.getNumArgs(); ++I
) {
2521 Init
*Arg
= List
.getArg(I
);
2522 std::string Name
= List
.getArgName(I
)
2523 ? List
.getArgName(I
)->getValue().str()
2524 : makeAnonPatName(AnonPatNamePrefix
, I
);
2526 if (auto Pat
= parseInstructionPattern(*Arg
, Name
)) {
2527 if (!ParseAction(std::move(Pat
)))
2532 if (auto Pat
= parseWipMatchOpcodeMatcher(*Arg
, Name
)) {
2533 if (!ParseAction(std::move(Pat
)))
2538 // Parse arbitrary C++ code
2539 if (const auto *StringI
= dyn_cast
<StringInit
>(Arg
)) {
2540 auto CXXPat
= std::make_unique
<CXXPattern
>(*StringI
, Name
);
2541 if (!ParseAction(std::move(CXXPat
)))
2546 ::PrintError(DiagLoc
,
2547 "Failed to parse pattern: '" + Arg
->getAsString() + "'");
2554 std::unique_ptr
<Pattern
>
2555 CombineRuleBuilder::parseInstructionPattern(const Init
&Arg
,
2556 StringRef Name
) const {
2557 const DagInit
*DagPat
= dyn_cast
<DagInit
>(&Arg
);
2561 std::unique_ptr
<InstructionPattern
> Pat
;
2562 if (const DagInit
*IP
= getDagWithOperatorOfSubClass(Arg
, "Instruction")) {
2563 auto &Instr
= CGT
.getInstruction(IP
->getOperatorAsDef(RuleDef
.getLoc()));
2564 Pat
= std::make_unique
<CodeGenInstructionPattern
>(Instr
, Name
);
2565 } else if (const DagInit
*PFP
=
2566 getDagWithOperatorOfSubClass(Arg
, PatFragClassName
)) {
2567 const Record
*Def
= PFP
->getOperatorAsDef(RuleDef
.getLoc());
2568 const PatFrag
*PF
= parsePatFrag(Def
);
2570 return nullptr; // Already diagnosed by parsePatFrag
2571 Pat
= std::make_unique
<PatFragPattern
>(*PF
, Name
);
2572 } else if (const DagInit
*BP
=
2573 getDagWithOperatorOfSubClass(Arg
, BuiltinInstClassName
)) {
2574 Pat
= std::make_unique
<BuiltinPattern
>(
2575 *BP
->getOperatorAsDef(RuleDef
.getLoc()), Name
);
2580 for (unsigned K
= 0; K
< DagPat
->getNumArgs(); ++K
) {
2581 if (!parseInstructionPatternOperand(*Pat
, DagPat
->getArg(K
),
2582 DagPat
->getArgName(K
)))
2586 if (!Pat
->checkSemantics(RuleDef
.getLoc()))
2589 return std::move(Pat
);
2592 std::unique_ptr
<Pattern
>
2593 CombineRuleBuilder::parseWipMatchOpcodeMatcher(const Init
&Arg
,
2594 StringRef Name
) const {
2595 const DagInit
*Matcher
= getDagWithSpecificOperator(Arg
, "wip_match_opcode");
2599 if (Matcher
->getNumArgs() == 0) {
2600 PrintError("Empty wip_match_opcode");
2604 // Each argument is an opcode that can match.
2605 auto Result
= std::make_unique
<AnyOpcodePattern
>(Name
);
2606 for (const auto &Arg
: Matcher
->getArgs()) {
2607 Record
*OpcodeDef
= getDefOfSubClass(*Arg
, "Instruction");
2609 Result
->addOpcode(&CGT
.getInstruction(OpcodeDef
));
2613 PrintError("Arguments to wip_match_opcode must be instructions");
2617 return std::move(Result
);
2620 bool CombineRuleBuilder::parseInstructionPatternOperand(
2621 InstructionPattern
&IP
, const Init
*OpInit
,
2622 const StringInit
*OpName
) const {
2623 const auto ParseErr
= [&]() {
2624 PrintError("cannot parse operand '" + OpInit
->getAsUnquotedString() + "' ");
2626 PrintNote("operand name is '" + OpName
->getAsUnquotedString() + "'");
2630 // untyped immediate, e.g. 0
2631 if (const auto *IntImm
= dyn_cast
<IntInit
>(OpInit
)) {
2632 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
2633 IP
.addOperand(IntImm
->getValue(), Name
, /*Type=*/nullptr);
2637 // typed immediate, e.g. (i32 0)
2638 if (const auto *DagOp
= dyn_cast
<DagInit
>(OpInit
)) {
2639 if (DagOp
->getNumArgs() != 1)
2642 const Record
*TyDef
= DagOp
->getOperatorAsDef(RuleDef
.getLoc());
2643 PatternType
ImmTy(TyDef
);
2644 if (!ImmTy
.isValidType()) {
2645 PrintError("cannot parse immediate '" + OpInit
->getAsUnquotedString() +
2646 "', '" + TyDef
->getName() + "' is not a ValueType or " +
2647 SpecialTyClassName
);
2651 if (!IP
.hasAllDefs()) {
2652 PrintError("out operand of '" + IP
.getInstName() +
2653 "' cannot be an immediate");
2657 const auto *Val
= dyn_cast
<IntInit
>(DagOp
->getArg(0));
2661 std::string Name
= OpName
? OpName
->getAsUnquotedString() : "";
2662 IP
.addOperand(Val
->getValue(), Name
, ImmTy
);
2666 // Typed operand e.g. $x/$z in (G_FNEG $x, $z)
2667 if (auto *DefI
= dyn_cast
<DefInit
>(OpInit
)) {
2669 PrintError("expected an operand name after '" + OpInit
->getAsString() +
2673 const Record
*Def
= DefI
->getDef();
2674 PatternType
Ty(Def
);
2675 if (!Ty
.isValidType()) {
2676 PrintError("invalid operand type: '" + Def
->getName() +
2677 "' is not a ValueType");
2680 IP
.addOperand(OpName
->getAsUnquotedString(), Ty
);
2684 // Untyped operand e.g. $x/$z in (G_FNEG $x, $z)
2685 if (isa
<UnsetInit
>(OpInit
)) {
2686 assert(OpName
&& "Unset w/ no OpName?");
2687 IP
.addOperand(OpName
->getAsUnquotedString(), /*Type=*/nullptr);
2694 std::unique_ptr
<PatFrag
>
2695 CombineRuleBuilder::parsePatFragImpl(const Record
*Def
) const {
2696 auto StackTrace
= PrettyStackTraceParse(*Def
);
2697 if (!Def
->isSubClassOf(PatFragClassName
))
2700 const DagInit
*Ins
= Def
->getValueAsDag("InOperands");
2701 if (Ins
->getOperatorAsDef(Def
->getLoc())->getName() != "ins") {
2702 ::PrintError(Def
, "expected 'ins' operator for " + PatFragClassName
+
2703 " in operands list");
2707 const DagInit
*Outs
= Def
->getValueAsDag("OutOperands");
2708 if (Outs
->getOperatorAsDef(Def
->getLoc())->getName() != "outs") {
2709 ::PrintError(Def
, "expected 'outs' operator for " + PatFragClassName
+
2710 " out operands list");
2714 auto Result
= std::make_unique
<PatFrag
>(*Def
);
2715 if (!parsePatFragParamList(Def
->getLoc(), *Outs
,
2716 [&](StringRef Name
, PatFrag::ParamKind Kind
) {
2717 Result
->addOutParam(Name
, Kind
);
2722 if (!parsePatFragParamList(Def
->getLoc(), *Ins
,
2723 [&](StringRef Name
, PatFrag::ParamKind Kind
) {
2724 Result
->addInParam(Name
, Kind
);
2729 const ListInit
*Alts
= Def
->getValueAsListInit("Alternatives");
2730 unsigned AltIdx
= 0;
2731 for (const Init
*Alt
: *Alts
) {
2732 const auto *PatDag
= dyn_cast
<DagInit
>(Alt
);
2734 ::PrintError(Def
, "expected dag init for PatFrag pattern alternative");
2738 PatFrag::Alternative
&A
= Result
->addAlternative();
2739 const auto AddPat
= [&](std::unique_ptr
<Pattern
> Pat
) {
2740 A
.Pats
.push_back(std::move(Pat
));
2744 if (!parsePatternList(
2745 *PatDag
, AddPat
, "pattern", Def
->getLoc(),
2747 (Def
->getName() + "_alt" + Twine(AltIdx
++) + "_pattern").str()))
2751 if (!Result
->buildOperandsTables() || !Result
->checkSemantics())
2757 bool CombineRuleBuilder::parsePatFragParamList(
2758 ArrayRef
<SMLoc
> DiagLoc
, const DagInit
&OpsList
,
2759 function_ref
<bool(StringRef
, PatFrag::ParamKind
)> ParseAction
) const {
2760 for (unsigned K
= 0; K
< OpsList
.getNumArgs(); ++K
) {
2761 const StringInit
*Name
= OpsList
.getArgName(K
);
2762 const Init
*Ty
= OpsList
.getArg(K
);
2765 ::PrintError(DiagLoc
, "all operands must be named'");
2768 const std::string NameStr
= Name
->getAsUnquotedString();
2770 PatFrag::ParamKind OpKind
;
2771 if (isSpecificDef(*Ty
, "gi_imm"))
2772 OpKind
= PatFrag::PK_Imm
;
2773 else if (isSpecificDef(*Ty
, "root"))
2774 OpKind
= PatFrag::PK_Root
;
2775 else if (isa
<UnsetInit
>(Ty
) ||
2776 isSpecificDef(*Ty
, "gi_mo")) // no type = gi_mo.
2777 OpKind
= PatFrag::PK_MachineOperand
;
2782 "' operand type was expected to be 'root', 'gi_imm' or 'gi_mo'");
2786 if (!ParseAction(NameStr
, OpKind
))
2793 const PatFrag
*CombineRuleBuilder::parsePatFrag(const Record
*Def
) const {
2794 // Cache already parsed PatFrags to avoid doing extra work.
2795 static DenseMap
<const Record
*, std::unique_ptr
<PatFrag
>> ParsedPatFrags
;
2797 auto It
= ParsedPatFrags
.find(Def
);
2798 if (It
!= ParsedPatFrags
.end()) {
2799 SeenPatFrags
.insert(It
->second
.get());
2800 return It
->second
.get();
2803 std::unique_ptr
<PatFrag
> NewPatFrag
= parsePatFragImpl(Def
);
2805 ::PrintError(Def
, "Could not parse " + PatFragClassName
+ " '" +
2806 Def
->getName() + "'");
2807 // Put a nullptr in the map so we don't attempt parsing this again.
2808 ParsedPatFrags
[Def
] = nullptr;
2812 const auto *Res
= NewPatFrag
.get();
2813 ParsedPatFrags
[Def
] = std::move(NewPatFrag
);
2814 SeenPatFrags
.insert(Res
);
2818 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions
&CE
,
2819 const PatternAlternatives
&Alts
,
2820 const InstructionPattern
&IP
) {
2821 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &IP
);
2823 auto &M
= addRuleMatcher(Alts
);
2824 InstructionMatcher
&IM
= M
.addInstructionMatcher("root");
2825 declareInstExpansion(CE
, IM
, IP
.getName());
2827 DenseSet
<const Pattern
*> SeenPats
;
2829 const auto FindOperandDef
= [&](StringRef Op
) -> InstructionPattern
* {
2830 return MatchOpTable
.getDef(Op
);
2833 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&IP
)) {
2834 if (!emitCodeGenInstructionMatchPattern(CE
, Alts
, M
, IM
, *CGP
, SeenPats
,
2837 } else if (const auto *PFP
= dyn_cast
<PatFragPattern
>(&IP
)) {
2838 if (!PFP
->getPatFrag().canBeMatchRoot()) {
2839 PrintError("cannot use '" + PFP
->getInstName() + " as match root");
2843 if (!emitPatFragMatchPattern(CE
, Alts
, M
, &IM
, *PFP
, SeenPats
))
2845 } else if (isa
<BuiltinPattern
>(&IP
)) {
2846 llvm_unreachable("No match builtins known!");
2848 llvm_unreachable("Unknown kind of InstructionPattern!");
2850 // Emit remaining patterns
2851 for (auto &Pat
: values(MatchPats
)) {
2852 if (SeenPats
.contains(Pat
.get()))
2855 switch (Pat
->getKind()) {
2856 case Pattern::K_AnyOpcode
:
2857 PrintError("wip_match_opcode can not be used with instruction patterns!");
2859 case Pattern::K_PatFrag
: {
2860 if (!emitPatFragMatchPattern(CE
, Alts
, M
, /*IM*/ nullptr,
2861 *cast
<PatFragPattern
>(Pat
.get()), SeenPats
))
2865 case Pattern::K_Builtin
:
2866 PrintError("No known match builtins");
2868 case Pattern::K_CodeGenInstruction
:
2869 cast
<InstructionPattern
>(Pat
.get())->reportUnreachable(RuleDef
.getLoc());
2871 case Pattern::K_CXX
: {
2872 addCXXPredicate(M
, CE
, *cast
<CXXPattern
>(Pat
.get()), Alts
);
2876 llvm_unreachable("unknown pattern kind!");
2880 return emitApplyPatterns(CE
, M
);
2883 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions
&CE
,
2884 const PatternAlternatives
&Alts
,
2885 const AnyOpcodePattern
&AOP
) {
2886 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &AOP
);
2888 for (const CodeGenInstruction
*CGI
: AOP
.insts()) {
2889 auto &M
= addRuleMatcher(Alts
, "wip_match_opcode '" +
2890 CGI
->TheDef
->getName() + "'");
2892 InstructionMatcher
&IM
= M
.addInstructionMatcher(AOP
.getName());
2893 declareInstExpansion(CE
, IM
, AOP
.getName());
2894 // declareInstExpansion needs to be identical, otherwise we need to create a
2895 // CodeExpansions object here instead.
2896 assert(IM
.getInsnVarID() == 0);
2898 IM
.addPredicate
<InstructionOpcodeMatcher
>(CGI
);
2900 // Emit remaining patterns.
2901 for (auto &Pat
: values(MatchPats
)) {
2902 if (Pat
.get() == &AOP
)
2905 switch (Pat
->getKind()) {
2906 case Pattern::K_AnyOpcode
:
2907 PrintError("wip_match_opcode can only be present once!");
2909 case Pattern::K_PatFrag
: {
2910 DenseSet
<const Pattern
*> SeenPats
;
2911 if (!emitPatFragMatchPattern(CE
, Alts
, M
, /*IM*/ nullptr,
2912 *cast
<PatFragPattern
>(Pat
.get()),
2917 case Pattern::K_Builtin
:
2918 PrintError("No known match builtins");
2920 case Pattern::K_CodeGenInstruction
:
2921 cast
<InstructionPattern
>(Pat
.get())->reportUnreachable(
2924 case Pattern::K_CXX
: {
2925 addCXXPredicate(M
, CE
, *cast
<CXXPattern
>(Pat
.get()), Alts
);
2929 llvm_unreachable("unknown pattern kind!");
2933 if (!emitApplyPatterns(CE
, M
))
2940 bool CombineRuleBuilder::emitPatFragMatchPattern(
2941 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&RM
,
2942 InstructionMatcher
*IM
, const PatFragPattern
&PFP
,
2943 DenseSet
<const Pattern
*> &SeenPats
) {
2944 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &PFP
);
2946 if (SeenPats
.contains(&PFP
))
2948 SeenPats
.insert(&PFP
);
2950 const auto &PF
= PFP
.getPatFrag();
2953 // When we don't have an IM, this means this PatFrag isn't reachable from
2954 // the root. This is only acceptable if it doesn't define anything (e.g. a
2955 // pure C++ PatFrag).
2956 if (PF
.num_out_params() != 0) {
2957 PFP
.reportUnreachable(RuleDef
.getLoc());
2961 // When an IM is provided, this is reachable from the root, and we're
2962 // expecting to have output operands.
2963 // TODO: If we want to allow for multiple roots we'll need a map of IMs
2964 // then, and emission becomes a bit more complicated.
2965 assert(PF
.num_roots() == 1);
2968 CodeExpansions PatFragCEs
;
2969 if (!PFP
.mapInputCodeExpansions(CE
, PatFragCEs
, RuleDef
.getLoc()))
2972 // List of {ParamName, ArgName}.
2973 // When all patterns have been emitted, find expansions in PatFragCEs named
2974 // ArgName and add their expansion to CE using ParamName as the key.
2975 SmallVector
<std::pair
<std::string
, std::string
>, 4> CEsToImport
;
2977 // Map parameter names to the actual argument.
2978 const auto OperandMapper
=
2979 [&](const InstructionOperand
&O
) -> InstructionOperand
{
2980 if (!O
.isNamedOperand())
2983 StringRef ParamName
= O
.getOperandName();
2985 // Not sure what to do with those tbh. They should probably never be here.
2986 assert(!O
.isNamedImmediate() && "TODO: handle named imms");
2987 unsigned PIdx
= PF
.getParamIdx(ParamName
);
2989 // Map parameters to the argument values.
2990 if (PIdx
== (unsigned)-1) {
2991 // This is a temp of the PatFragPattern, prefix the name to avoid
2993 return O
.withNewName((PFP
.getName() + "." + ParamName
).str());
2996 // The operand will be added to PatFragCEs's code expansions using the
2997 // parameter's name. If it's bound to some operand during emission of the
2998 // patterns, we'll want to add it to CE.
2999 auto ArgOp
= PFP
.getOperand(PIdx
);
3000 if (ArgOp
.isNamedOperand())
3001 CEsToImport
.emplace_back(ArgOp
.getOperandName().str(), ParamName
);
3003 if (ArgOp
.getType() && O
.getType() && ArgOp
.getType() != O
.getType()) {
3004 StringRef PFName
= PF
.getName();
3005 PrintWarning("impossible type constraints: operand " + Twine(PIdx
) +
3006 " of '" + PFP
.getName() + "' has type '" +
3007 ArgOp
.getType().str() + "', but '" + PFName
+
3008 "' constrains it to '" + O
.getType().str() + "'");
3009 if (ArgOp
.isNamedOperand())
3010 PrintNote("operand " + Twine(PIdx
) + " of '" + PFP
.getName() +
3011 "' is '" + ArgOp
.getOperandName() + "'");
3012 if (O
.isNamedOperand())
3013 PrintNote("argument " + Twine(PIdx
) + " of '" + PFName
+ "' is '" +
3020 // PatFragPatterns are only made of InstructionPatterns or CXXPatterns.
3021 // Emit instructions from the root.
3022 const auto &FragAlt
= PF
.getAlternative(Alts
.lookup(&PFP
));
3023 const auto &FragAltOT
= FragAlt
.OpTable
;
3024 const auto LookupOperandDef
=
3025 [&](StringRef Op
) -> const InstructionPattern
* {
3026 return FragAltOT
.getDef(Op
);
3029 DenseSet
<const Pattern
*> PatFragSeenPats
;
3030 for (const auto &[Idx
, InOp
] : enumerate(PF
.out_params())) {
3031 if (InOp
.Kind
!= PatFrag::PK_Root
)
3034 StringRef ParamName
= InOp
.Name
;
3035 const auto *Def
= FragAltOT
.getDef(ParamName
);
3036 assert(Def
&& "PatFrag::checkSemantics should have emitted an error if "
3037 "an out operand isn't defined!");
3038 assert(isa
<CodeGenInstructionPattern
>(Def
) &&
3039 "Nested PatFrags not supported yet");
3041 if (!emitCodeGenInstructionMatchPattern(
3042 PatFragCEs
, Alts
, RM
, *IM
, *cast
<CodeGenInstructionPattern
>(Def
),
3043 PatFragSeenPats
, LookupOperandDef
, OperandMapper
))
3048 for (const auto &Pat
: FragAlt
.Pats
) {
3049 if (PatFragSeenPats
.contains(Pat
.get()))
3052 if (const auto *CXXPat
= dyn_cast
<CXXPattern
>(Pat
.get())) {
3053 addCXXPredicate(RM
, PatFragCEs
, *CXXPat
, Alts
);
3057 if (const auto *IP
= dyn_cast
<InstructionPattern
>(Pat
.get())) {
3058 IP
->reportUnreachable(PF
.getLoc());
3062 llvm_unreachable("Unexpected pattern kind in PatFrag");
3065 for (const auto &[ParamName
, ArgName
] : CEsToImport
) {
3066 // Note: we're find if ParamName already exists. It just means it's been
3067 // bound before, so we prefer to keep the first binding.
3068 CE
.declare(ParamName
, PatFragCEs
.lookup(ArgName
));
3074 bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions
&CE
, RuleMatcher
&M
) {
3075 if (hasOnlyCXXApplyPatterns()) {
3076 for (auto &Pat
: values(ApplyPats
))
3077 addCXXAction(M
, CE
, *cast
<CXXPattern
>(Pat
.get()));
3081 DenseSet
<const Pattern
*> SeenPats
;
3082 StringMap
<unsigned> OperandToTempRegID
;
3084 for (auto *ApplyRoot
: ApplyRoots
) {
3085 assert(isa
<InstructionPattern
>(ApplyRoot
) &&
3086 "Root can only be a InstructionPattern!");
3087 if (!emitInstructionApplyPattern(CE
, M
,
3088 cast
<InstructionPattern
>(*ApplyRoot
),
3089 SeenPats
, OperandToTempRegID
))
3093 for (auto &Pat
: values(ApplyPats
)) {
3094 if (SeenPats
.contains(Pat
.get()))
3097 switch (Pat
->getKind()) {
3098 case Pattern::K_AnyOpcode
:
3099 llvm_unreachable("Unexpected pattern in apply!");
3100 case Pattern::K_PatFrag
:
3101 // TODO: We could support pure C++ PatFrags as a temporary thing.
3102 llvm_unreachable("Unexpected pattern in apply!");
3103 case Pattern::K_Builtin
:
3104 if (!emitInstructionApplyPattern(CE
, M
, cast
<BuiltinPattern
>(*Pat
),
3105 SeenPats
, OperandToTempRegID
))
3108 case Pattern::K_CodeGenInstruction
:
3109 cast
<CodeGenInstructionPattern
>(*Pat
).reportUnreachable(RuleDef
.getLoc());
3111 case Pattern::K_CXX
: {
3112 addCXXAction(M
, CE
, *cast
<CXXPattern
>(Pat
.get()));
3116 llvm_unreachable("unknown pattern kind!");
3123 bool CombineRuleBuilder::emitInstructionApplyPattern(
3124 CodeExpansions
&CE
, RuleMatcher
&M
, const InstructionPattern
&P
,
3125 DenseSet
<const Pattern
*> &SeenPats
,
3126 StringMap
<unsigned> &OperandToTempRegID
) {
3127 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &P
);
3129 if (SeenPats
.contains(&P
))
3132 SeenPats
.insert(&P
);
3134 // First, render the uses.
3135 for (auto &Op
: P
.named_operands()) {
3139 StringRef OpName
= Op
.getOperandName();
3140 if (const auto *DefPat
= ApplyOpTable
.getDef(OpName
)) {
3141 if (!emitInstructionApplyPattern(CE
, M
, *DefPat
, SeenPats
,
3142 OperandToTempRegID
))
3145 // If we have no def, check this exists in the MatchRoot.
3146 if (!Op
.isNamedImmediate() && !MatchOpTable
.lookup(OpName
).Found
) {
3147 PrintError("invalid output operand '" + OpName
+
3148 "': operand is not a live-in of the match pattern, and it "
3149 "has no definition");
3155 if (const auto *BP
= dyn_cast
<BuiltinPattern
>(&P
))
3156 return emitBuiltinApplyPattern(CE
, M
, *BP
, OperandToTempRegID
);
3158 if (isa
<PatFragPattern
>(&P
))
3159 llvm_unreachable("PatFragPatterns is not supported in 'apply'!");
3161 auto &CGIP
= cast
<CodeGenInstructionPattern
>(P
);
3163 // Now render this inst.
3165 M
.addAction
<BuildMIAction
>(M
.allocateOutputInsnID(), &CGIP
.getInst());
3167 for (auto &Op
: P
.operands()) {
3168 if (Op
.isNamedImmediate()) {
3169 PrintError("invalid output operand '" + Op
.getOperandName() +
3170 "': output immediates cannot be named");
3171 PrintNote("while emitting pattern '" + P
.getName() + "' (" +
3172 P
.getInstName() + ")");
3176 if (Op
.hasImmValue()) {
3177 if (!emitCodeGenInstructionApplyImmOperand(M
, DstMI
, CGIP
, Op
))
3182 StringRef OpName
= Op
.getOperandName();
3186 if (auto It
= OperandToTempRegID
.find(OpName
);
3187 It
!= OperandToTempRegID
.end()) {
3188 assert(!MatchOpTable
.lookup(OpName
).Found
&&
3189 "Temp reg is also from match pattern?");
3190 DstMI
.addRenderer
<TempRegRenderer
>(It
->second
);
3192 // This should be a match live in or a redef of a matched instr.
3193 // If it's a use of a temporary register, then we messed up somewhere -
3194 // the previous condition should have passed.
3195 assert(MatchOpTable
.lookup(OpName
).Found
&&
3196 !ApplyOpTable
.getDef(OpName
) && "Temp reg not emitted yet!");
3197 DstMI
.addRenderer
<CopyRenderer
>(OpName
);
3202 // Determine what we're dealing with. Are we replace a matched instruction?
3203 // Creating a new one?
3204 auto OpLookupRes
= MatchOpTable
.lookup(OpName
);
3205 if (OpLookupRes
.Found
) {
3206 if (OpLookupRes
.isLiveIn()) {
3207 // live-in of the match pattern.
3208 PrintError("Cannot define live-in operand '" + OpName
+
3209 "' in the 'apply' pattern");
3212 assert(OpLookupRes
.Def
);
3214 // TODO: Handle this. We need to mutate the instr, or delete the old
3216 // Likewise, we also need to ensure we redef everything, if the
3217 // instr has more than one def, we need to redef all or nothing.
3218 if (OpLookupRes
.Def
!= MatchRoot
) {
3219 PrintError("redefining an instruction other than the root is not "
3220 "supported (operand '" +
3225 DstMI
.addRenderer
<CopyRenderer
>(OpName
);
3229 // Define a new register unique to the apply patterns (AKA a "temp"
3232 if (auto It
= OperandToTempRegID
.find(OpName
);
3233 It
!= OperandToTempRegID
.end()) {
3234 TempRegID
= It
->second
;
3236 // This is a brand new register.
3237 TempRegID
= M
.allocateTempRegID();
3238 OperandToTempRegID
[OpName
] = TempRegID
;
3239 const auto Ty
= Op
.getType();
3241 PrintError("def of a new register '" + OpName
+
3242 "' in the apply patterns must have a type");
3246 declareTempRegExpansion(CE
, TempRegID
, OpName
);
3247 // Always insert the action at the beginning, otherwise we may end up
3248 // using the temp reg before it's available.
3249 M
.insertAction
<MakeTempRegisterAction
>(
3250 M
.actions_begin(), Ty
.getLLTCodeGenOrTempType(M
), TempRegID
);
3253 DstMI
.addRenderer
<TempRegRenderer
>(TempRegID
);
3257 DstMI
.chooseInsnToMutate(M
);
3258 declareInstExpansion(CE
, DstMI
, P
.getName());
3263 bool CombineRuleBuilder::emitCodeGenInstructionApplyImmOperand(
3264 RuleMatcher
&M
, BuildMIAction
&DstMI
, const CodeGenInstructionPattern
&P
,
3265 const InstructionOperand
&O
) {
3266 // If we have a type, we implicitly emit a G_CONSTANT, except for G_CONSTANT
3267 // itself where we emit a CImm.
3269 // No type means we emit a simple imm.
3270 // G_CONSTANT is a special case and needs a CImm though so this is likely a
3272 const bool isGConstant
= P
.is("G_CONSTANT");
3273 const auto Ty
= O
.getType();
3276 PrintError("'G_CONSTANT' immediate must be typed!");
3277 PrintNote("while emitting pattern '" + P
.getName() + "' (" +
3278 P
.getInstName() + ")");
3282 DstMI
.addRenderer
<ImmRenderer
>(O
.getImmValue());
3286 auto ImmTy
= Ty
.getLLTCodeGenOrTempType(M
);
3289 DstMI
.addRenderer
<ImmRenderer
>(O
.getImmValue(), ImmTy
);
3293 unsigned TempRegID
= M
.allocateTempRegID();
3294 // Ensure MakeTempReg & the BuildConstantAction occur at the beginning.
3295 auto InsertIt
= M
.insertAction
<MakeTempRegisterAction
>(M
.actions_begin(),
3297 M
.insertAction
<BuildConstantAction
>(++InsertIt
, TempRegID
, O
.getImmValue());
3298 DstMI
.addRenderer
<TempRegRenderer
>(TempRegID
);
3302 bool CombineRuleBuilder::emitBuiltinApplyPattern(
3303 CodeExpansions
&CE
, RuleMatcher
&M
, const BuiltinPattern
&P
,
3304 StringMap
<unsigned> &OperandToTempRegID
) {
3305 const auto Error
= [&](Twine Reason
) {
3306 PrintError("cannot emit '" + P
.getInstName() + "' builtin: " + Reason
);
3310 switch (P
.getBuiltinKind()) {
3311 case BI_EraseRoot
: {
3312 // Root is always inst 0.
3313 M
.addAction
<EraseInstAction
>(/*InsnID*/ 0);
3316 case BI_ReplaceReg
: {
3317 StringRef Old
= P
.getOperand(0).getOperandName();
3318 StringRef New
= P
.getOperand(1).getOperandName();
3320 if (!ApplyOpTable
.lookup(New
).Found
&& !MatchOpTable
.lookup(New
).Found
)
3321 return Error("unknown operand '" + Old
+ "'");
3323 auto &OldOM
= M
.getOperandMatcher(Old
);
3324 if (auto It
= OperandToTempRegID
.find(New
);
3325 It
!= OperandToTempRegID
.end()) {
3326 // Replace with temp reg.
3327 M
.addAction
<ReplaceRegAction
>(OldOM
.getInsnVarID(), OldOM
.getOpIdx(),
3330 // Replace with matched reg.
3331 auto &NewOM
= M
.getOperandMatcher(New
);
3332 M
.addAction
<ReplaceRegAction
>(OldOM
.getInsnVarID(), OldOM
.getOpIdx(),
3333 NewOM
.getInsnVarID(), NewOM
.getOpIdx());
3335 // checkSemantics should have ensured that we can only rewrite the root.
3336 // Ensure we're deleting it.
3337 assert(MatchOpTable
.getDef(Old
) == MatchRoot
);
3338 // TODO: We could avoid adding the action again if it's already in. The
3339 // MatchTable is smart enough to only emit one opcode even if
3340 // EraseInstAction is present multiple times. I think searching for a copy
3341 // is more expensive than just blindly adding it though.
3342 M
.addAction
<EraseInstAction
>(/*InsnID*/ 0);
3348 llvm_unreachable("Unknown BuiltinKind!");
3351 bool isLiteralImm(const InstructionPattern
&P
, unsigned OpIdx
) {
3352 if (const auto *CGP
= dyn_cast
<CodeGenInstructionPattern
>(&P
)) {
3353 StringRef InstName
= CGP
->getInst().TheDef
->getName();
3354 return (InstName
== "G_CONSTANT" || InstName
== "G_FCONSTANT") &&
3358 llvm_unreachable("TODO");
3361 bool CombineRuleBuilder::emitCodeGenInstructionMatchPattern(
3362 CodeExpansions
&CE
, const PatternAlternatives
&Alts
, RuleMatcher
&M
,
3363 InstructionMatcher
&IM
, const CodeGenInstructionPattern
&P
,
3364 DenseSet
<const Pattern
*> &SeenPats
, OperandDefLookupFn LookupOperandDef
,
3365 OperandMapperFnRef OperandMapper
) {
3366 auto StackTrace
= PrettyStackTraceEmit(RuleDef
, &P
);
3368 if (SeenPats
.contains(&P
))
3371 SeenPats
.insert(&P
);
3373 IM
.addPredicate
<InstructionOpcodeMatcher
>(&P
.getInst());
3374 declareInstExpansion(CE
, IM
, P
.getName());
3376 for (const auto &[Idx
, OriginalO
] : enumerate(P
.operands())) {
3377 // Remap the operand. This is used when emitting InstructionPatterns inside
3378 // PatFrags, so it can remap them to the arguments passed to the pattern.
3380 // We use the remapped operand to emit immediates, and for the symbolic
3381 // operand names (in IM.addOperand). CodeExpansions and OperandTable lookups
3382 // still use the original name.
3384 // The "def" flag on the remapped operand is always ignored.
3385 auto RemappedO
= OperandMapper(OriginalO
);
3386 assert(RemappedO
.isNamedOperand() == OriginalO
.isNamedOperand() &&
3387 "Cannot remap an unnamed operand to a named one!");
3390 RemappedO
.isNamedOperand() ? RemappedO
.getOperandName().str() : "";
3391 OperandMatcher
&OM
=
3392 IM
.addOperand(Idx
, OpName
, AllocatedTemporariesBaseID
++);
3393 if (!OpName
.empty())
3394 declareOperandExpansion(CE
, OM
, OriginalO
.getOperandName());
3396 // Handle immediates.
3397 if (RemappedO
.hasImmValue()) {
3398 if (isLiteralImm(P
, Idx
))
3399 OM
.addPredicate
<LiteralIntOperandMatcher
>(RemappedO
.getImmValue());
3401 OM
.addPredicate
<ConstantIntOperandMatcher
>(RemappedO
.getImmValue());
3404 // Handle typed operands, but only bother to check if it hasn't been done
3407 // getOperandMatcher will always return the first OM to have been created
3408 // for that Operand. "OM" here is always a new OperandMatcher.
3410 // Always emit a check for unnamed operands.
3411 if (OpName
.empty() ||
3412 !M
.getOperandMatcher(OpName
).contains
<LLTOperandMatcher
>()) {
3413 if (const auto Ty
= RemappedO
.getType()) {
3414 // TODO: We could support GITypeOf here on the condition that the
3415 // OperandMatcher exists already. Though it's clunky to make this work
3416 // and isn't all that useful so it's just rejected in typecheckPatterns
3418 assert(Ty
.isLLT() && "Only LLTs are supported in match patterns!");
3419 OM
.addPredicate
<LLTOperandMatcher
>(Ty
.getLLTCodeGen());
3423 // Stop here if the operand is a def, or if it had no name.
3424 if (OriginalO
.isDef() || !OriginalO
.isNamedOperand())
3427 const auto *DefPat
= LookupOperandDef(OriginalO
.getOperandName());
3431 if (OriginalO
.hasImmValue()) {
3432 assert(!OpName
.empty());
3433 // This is a named immediate that also has a def, that's not okay.
3435 // (G_SEXT $y, (i32 0))
3437 PrintError("'" + OpName
+
3438 "' is a named immediate, it cannot be defined by another "
3440 PrintNote("'" + OpName
+ "' is defined by '" + DefPat
->getName() + "'");
3444 // From here we know that the operand defines an instruction, and we need to
3447 OM
.addPredicate
<InstructionOperandMatcher
>(M
, DefPat
->getName());
3449 // TODO: copy-pasted from GlobalISelEmitter.cpp. Is it still relevant
3451 PrintError("Nested instruction '" + DefPat
->getName() +
3452 "' cannot be the same as another operand '" +
3453 OriginalO
.getOperandName() + "'");
3457 auto &IM
= (*InstOpM
)->getInsnMatcher();
3458 if (const auto *CGIDef
= dyn_cast
<CodeGenInstructionPattern
>(DefPat
)) {
3459 if (!emitCodeGenInstructionMatchPattern(CE
, Alts
, M
, IM
, *CGIDef
,
3460 SeenPats
, LookupOperandDef
,
3466 if (const auto *PFPDef
= dyn_cast
<PatFragPattern
>(DefPat
)) {
3467 if (!emitPatFragMatchPattern(CE
, Alts
, M
, &IM
, *PFPDef
, SeenPats
))
3472 llvm_unreachable("unknown type of InstructionPattern");
3478 //===- GICombinerEmitter --------------------------------------------------===//
3480 /// Main implementation class. This emits the tablegenerated output.
3482 /// It collects rules, uses `CombineRuleBuilder` to parse them and accumulate
3483 /// RuleMatchers, then takes all the necessary state/data from the various
3484 /// static storage pools and wires them together to emit the match table &
3485 /// associated function/data structures.
3486 class GICombinerEmitter final
: public GlobalISelMatchTableExecutorEmitter
{
3487 RecordKeeper
&Records
;
3489 const CodeGenTarget
&Target
;
3491 unsigned NextRuleID
= 0;
3493 // List all combine rules (ID, name) imported.
3494 // Note that the combiner rule ID is different from the RuleMatcher ID. The
3495 // latter is internal to the MatchTable, the former is the canonical ID of the
3496 // combine rule used to disable/enable it.
3497 std::vector
<std::pair
<unsigned, std::string
>> AllCombineRules
;
3499 // Keep track of all rules we've seen so far to ensure we don't process
3500 // the same rule twice.
3501 StringSet
<> RulesSeen
;
3503 MatchTable
buildMatchTable(MutableArrayRef
<RuleMatcher
> Rules
);
3505 void emitRuleConfigImpl(raw_ostream
&OS
);
3507 void emitAdditionalImpl(raw_ostream
&OS
) override
;
3509 void emitMIPredicateFns(raw_ostream
&OS
) override
;
3510 void emitI64ImmPredicateFns(raw_ostream
&OS
) override
;
3511 void emitAPFloatImmPredicateFns(raw_ostream
&OS
) override
;
3512 void emitAPIntImmPredicateFns(raw_ostream
&OS
) override
;
3513 void emitTestSimplePredicate(raw_ostream
&OS
) override
;
3514 void emitRunCustomAction(raw_ostream
&OS
) override
;
3516 void emitAdditionalTemporariesDecl(raw_ostream
&OS
,
3517 StringRef Indent
) override
;
3519 const CodeGenTarget
&getTarget() const override
{ return Target
; }
3520 StringRef
getClassName() const override
{
3521 return Combiner
->getValueAsString("Classname");
3524 StringRef
getCombineAllMethodName() const {
3525 return Combiner
->getValueAsString("CombineAllMethodName");
3528 std::string
getRuleConfigClassName() const {
3529 return getClassName().str() + "RuleConfig";
3532 void gatherRules(std::vector
<RuleMatcher
> &Rules
,
3533 const std::vector
<Record
*> &&RulesAndGroups
);
3536 explicit GICombinerEmitter(RecordKeeper
&RK
, const CodeGenTarget
&Target
,
3537 StringRef Name
, Record
*Combiner
);
3538 ~GICombinerEmitter() {}
3540 void run(raw_ostream
&OS
);
3543 void GICombinerEmitter::emitRuleConfigImpl(raw_ostream
&OS
) {
3544 OS
<< "struct " << getRuleConfigClassName() << " {\n"
3545 << " SparseBitVector<> DisabledRules;\n\n"
3546 << " bool isRuleEnabled(unsigned RuleID) const;\n"
3547 << " bool parseCommandLineOption();\n"
3548 << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
3549 << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
3552 std::vector
<std::pair
<std::string
, std::string
>> Cases
;
3553 Cases
.reserve(AllCombineRules
.size());
3555 for (const auto &[ID
, Name
] : AllCombineRules
)
3556 Cases
.emplace_back(Name
, "return " + to_string(ID
) + ";\n");
3558 OS
<< "static std::optional<uint64_t> getRuleIdxForIdentifier(StringRef "
3559 "RuleIdentifier) {\n"
3561 << " // getAtInteger(...) returns false on success\n"
3562 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
3565 << "#ifndef NDEBUG\n";
3566 StringMatcher
Matcher("RuleIdentifier", Cases
, OS
);
3568 OS
<< "#endif // ifndef NDEBUG\n\n"
3569 << " return std::nullopt;\n"
3572 OS
<< "static std::optional<std::pair<uint64_t, uint64_t>> "
3573 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
3574 << " std::pair<StringRef, StringRef> RangePair = "
3575 "RuleIdentifier.split('-');\n"
3576 << " if (!RangePair.second.empty()) {\n"
3577 << " const auto First = "
3578 "getRuleIdxForIdentifier(RangePair.first);\n"
3579 << " const auto Last = "
3580 "getRuleIdxForIdentifier(RangePair.second);\n"
3581 << " if (!First || !Last)\n"
3582 << " return std::nullopt;\n"
3583 << " if (First >= Last)\n"
3584 << " report_fatal_error(\"Beginning of range should be before "
3585 "end of range\");\n"
3586 << " return {{*First, *Last + 1}};\n"
3588 << " if (RangePair.first == \"*\") {\n"
3589 << " return {{0, " << AllCombineRules
.size() << "}};\n"
3591 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
3593 << " return std::nullopt;\n"
3594 << " return {{*I, *I + 1}};\n"
3597 for (bool Enabled
: {true, false}) {
3598 OS
<< "bool " << getRuleConfigClassName() << "::setRule"
3599 << (Enabled
? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
3600 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
3601 << " if (!MaybeRange)\n"
3602 << " return false;\n"
3603 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
3604 << " DisabledRules." << (Enabled
? "reset" : "set") << "(I);\n"
3605 << " return true;\n"
3609 OS
<< "static std::vector<std::string> " << Name
<< "Option;\n"
3610 << "static cl::list<std::string> " << Name
<< "DisableOption(\n"
3611 << " \"" << Name
.lower() << "-disable-rule\",\n"
3612 << " cl::desc(\"Disable one or more combiner rules temporarily in "
3613 << "the " << Name
<< " pass\"),\n"
3614 << " cl::CommaSeparated,\n"
3616 << " cl::cat(GICombinerOptionCategory),\n"
3617 << " cl::callback([](const std::string &Str) {\n"
3618 << " " << Name
<< "Option.push_back(Str);\n"
3620 << "static cl::list<std::string> " << Name
<< "OnlyEnableOption(\n"
3621 << " \"" << Name
.lower() << "-only-enable-rule\",\n"
3622 << " cl::desc(\"Disable all rules in the " << Name
3623 << " pass then re-enable the specified ones\"),\n"
3625 << " cl::cat(GICombinerOptionCategory),\n"
3626 << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
3627 << " StringRef Str = CommaSeparatedArg;\n"
3628 << " " << Name
<< "Option.push_back(\"*\");\n"
3630 << " auto X = Str.split(\",\");\n"
3631 << " " << Name
<< "Option.push_back((\"!\" + X.first).str());\n"
3632 << " Str = X.second;\n"
3633 << " } while (!Str.empty());\n"
3636 << "bool " << getRuleConfigClassName()
3637 << "::isRuleEnabled(unsigned RuleID) const {\n"
3638 << " return !DisabledRules.test(RuleID);\n"
3640 << "bool " << getRuleConfigClassName() << "::parseCommandLineOption() {\n"
3641 << " for (StringRef Identifier : " << Name
<< "Option) {\n"
3642 << " bool Enabled = Identifier.consume_front(\"!\");\n"
3643 << " if (Enabled && !setRuleEnabled(Identifier))\n"
3644 << " return false;\n"
3645 << " if (!Enabled && !setRuleDisabled(Identifier))\n"
3646 << " return false;\n"
3648 << " return true;\n"
3652 void GICombinerEmitter::emitAdditionalImpl(raw_ostream
&OS
) {
3653 OS
<< "bool " << getClassName() << "::" << getCombineAllMethodName()
3654 << "(MachineInstr &I) const {\n"
3655 << " const TargetSubtargetInfo &ST = MF.getSubtarget();\n"
3656 << " const PredicateBitset AvailableFeatures = "
3657 "getAvailableFeatures();\n"
3658 << " B.setInstrAndDebugLoc(I);\n"
3659 << " State.MIs.clear();\n"
3660 << " State.MIs.push_back(&I);\n"
3661 << " " << MatchDataInfo::StructName
<< " = "
3662 << MatchDataInfo::StructTypeName
<< "();\n\n"
3663 << " if (executeMatchTable(*this, State, ExecInfo, B"
3664 << ", getMatchTable(), *ST.getInstrInfo(), MRI, "
3665 "*MRI.getTargetRegisterInfo(), *ST.getRegBankInfo(), AvailableFeatures"
3666 << ", /*CoverageInfo*/ nullptr)) {\n"
3667 << " return true;\n"
3669 << " return false;\n"
3673 void GICombinerEmitter::emitMIPredicateFns(raw_ostream
&OS
) {
3674 auto MatchCode
= CXXPredicateCode::getAllMatchCode();
3675 emitMIPredicateFnsImpl
<const CXXPredicateCode
*>(
3676 OS
, "", ArrayRef
<const CXXPredicateCode
*>(MatchCode
),
3677 [](const CXXPredicateCode
*C
) -> StringRef
{ return C
->BaseEnumName
; },
3678 [](const CXXPredicateCode
*C
) -> StringRef
{ return C
->Code
; });
3681 void GICombinerEmitter::emitI64ImmPredicateFns(raw_ostream
&OS
) {
3682 // Unused, but still needs to be called.
3683 emitImmPredicateFnsImpl
<unsigned>(
3684 OS
, "I64", "int64_t", {}, [](unsigned) { return ""; },
3685 [](unsigned) { return ""; });
3688 void GICombinerEmitter::emitAPFloatImmPredicateFns(raw_ostream
&OS
) {
3689 // Unused, but still needs to be called.
3690 emitImmPredicateFnsImpl
<unsigned>(
3691 OS
, "APFloat", "const APFloat &", {}, [](unsigned) { return ""; },
3692 [](unsigned) { return ""; });
3695 void GICombinerEmitter::emitAPIntImmPredicateFns(raw_ostream
&OS
) {
3696 // Unused, but still needs to be called.
3697 emitImmPredicateFnsImpl
<unsigned>(
3698 OS
, "APInt", "const APInt &", {}, [](unsigned) { return ""; },
3699 [](unsigned) { return ""; });
3702 void GICombinerEmitter::emitTestSimplePredicate(raw_ostream
&OS
) {
3703 if (!AllCombineRules
.empty()) {
3705 std::string EnumeratorSeparator
= " = GICXXPred_Invalid + 1,\n";
3706 // To avoid emitting a switch, we expect that all those rules are in order.
3707 // That way we can just get the RuleID from the enum by subtracting
3708 // (GICXXPred_Invalid + 1).
3709 unsigned ExpectedID
= 0;
3711 for (const auto &ID
: keys(AllCombineRules
)) {
3712 assert(ExpectedID
++ == ID
&& "combine rules are not ordered!");
3713 OS
<< " " << getIsEnabledPredicateEnumName(ID
) << EnumeratorSeparator
;
3714 EnumeratorSeparator
= ",\n";
3719 OS
<< "bool " << getClassName()
3720 << "::testSimplePredicate(unsigned Predicate) const {\n"
3721 << " return RuleConfig.isRuleEnabled(Predicate - "
3722 "GICXXPred_Invalid - "
3727 void GICombinerEmitter::emitRunCustomAction(raw_ostream
&OS
) {
3728 const auto ApplyCode
= CXXPredicateCode::getAllApplyCode();
3730 if (!ApplyCode
.empty()) {
3732 std::string EnumeratorSeparator
= " = GICXXCustomAction_Invalid + 1,\n";
3733 for (const auto &Apply
: ApplyCode
) {
3734 OS
<< " " << Apply
->getEnumNameWithPrefix(CXXApplyPrefix
)
3735 << EnumeratorSeparator
;
3736 EnumeratorSeparator
= ",\n";
3741 OS
<< "void " << getClassName()
3742 << "::runCustomAction(unsigned ApplyID, const MatcherState &State, "
3743 "NewMIVector &OutMIs) const "
3745 if (!ApplyCode
.empty()) {
3746 OS
<< " switch(ApplyID) {\n";
3747 for (const auto &Apply
: ApplyCode
) {
3748 OS
<< " case " << Apply
->getEnumNameWithPrefix(CXXApplyPrefix
) << ":{\n"
3749 << " " << join(split(Apply
->Code
, "\n"), "\n ") << "\n"
3755 OS
<< " llvm_unreachable(\"Unknown Apply Action\");\n"
3759 void GICombinerEmitter::emitAdditionalTemporariesDecl(raw_ostream
&OS
,
3761 OS
<< Indent
<< "struct " << MatchDataInfo::StructTypeName
<< " {\n";
3762 for (const auto &[Type
, VarNames
] : AllMatchDataVars
) {
3763 assert(!VarNames
.empty() && "Cannot have no vars for this type!");
3764 OS
<< Indent
<< " " << Type
<< " " << join(VarNames
, ", ") << ";\n";
3766 OS
<< Indent
<< "};\n"
3767 << Indent
<< "mutable " << MatchDataInfo::StructTypeName
<< " "
3768 << MatchDataInfo::StructName
<< ";\n\n";
3771 GICombinerEmitter::GICombinerEmitter(RecordKeeper
&RK
,
3772 const CodeGenTarget
&Target
,
3773 StringRef Name
, Record
*Combiner
)
3774 : Records(RK
), Name(Name
), Target(Target
), Combiner(Combiner
) {}
3777 GICombinerEmitter::buildMatchTable(MutableArrayRef
<RuleMatcher
> Rules
) {
3778 std::vector
<Matcher
*> InputRules
;
3779 for (Matcher
&Rule
: Rules
)
3780 InputRules
.push_back(&Rule
);
3782 unsigned CurrentOrdering
= 0;
3783 StringMap
<unsigned> OpcodeOrder
;
3784 for (RuleMatcher
&Rule
: Rules
) {
3785 const StringRef Opcode
= Rule
.getOpcode();
3786 assert(!Opcode
.empty() && "Didn't expect an undefined opcode");
3787 if (OpcodeOrder
.count(Opcode
) == 0)
3788 OpcodeOrder
[Opcode
] = CurrentOrdering
++;
3791 llvm::stable_sort(InputRules
, [&OpcodeOrder
](const Matcher
*A
,
3793 auto *L
= static_cast<const RuleMatcher
*>(A
);
3794 auto *R
= static_cast<const RuleMatcher
*>(B
);
3795 return std::make_tuple(OpcodeOrder
[L
->getOpcode()], L
->getNumOperands()) <
3796 std::make_tuple(OpcodeOrder
[R
->getOpcode()], R
->getNumOperands());
3799 for (Matcher
*Rule
: InputRules
)
3802 std::vector
<std::unique_ptr
<Matcher
>> MatcherStorage
;
3803 std::vector
<Matcher
*> OptRules
=
3804 optimizeRules
<GroupMatcher
>(InputRules
, MatcherStorage
);
3806 for (Matcher
*Rule
: OptRules
)
3809 OptRules
= optimizeRules
<SwitchMatcher
>(OptRules
, MatcherStorage
);
3811 return MatchTable::buildTable(OptRules
, /*WithCoverage*/ false,
3812 /*IsCombiner*/ true);
3815 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
3816 void GICombinerEmitter::gatherRules(
3817 std::vector
<RuleMatcher
> &ActiveRules
,
3818 const std::vector
<Record
*> &&RulesAndGroups
) {
3819 for (Record
*Rec
: RulesAndGroups
) {
3820 if (!Rec
->isValueUnset("Rules")) {
3821 gatherRules(ActiveRules
, Rec
->getValueAsListOfDefs("Rules"));
3825 StringRef RuleName
= Rec
->getName();
3826 if (!RulesSeen
.insert(RuleName
).second
) {
3827 PrintWarning(Rec
->getLoc(),
3828 "skipping rule '" + Rec
->getName() +
3829 "' because it has already been processed");
3833 AllCombineRules
.emplace_back(NextRuleID
, Rec
->getName().str());
3834 CombineRuleBuilder
CRB(Target
, SubtargetFeatures
, *Rec
, NextRuleID
++,
3837 if (!CRB
.parseAll()) {
3838 assert(ErrorsPrinted
&& "Parsing failed without errors!");
3842 if (StopAfterParse
) {
3847 if (!CRB
.emitRuleMatchers()) {
3848 assert(ErrorsPrinted
&& "Emission failed without errors!");
3854 void GICombinerEmitter::run(raw_ostream
&OS
) {
3855 InstructionOpcodeMatcher::initOpcodeValuesMap(Target
);
3856 LLTOperandMatcher::initTypeIDValuesMap();
3858 Records
.startTimer("Gather rules");
3859 std::vector
<RuleMatcher
> Rules
;
3860 gatherRules(Rules
, Combiner
->getValueAsListOfDefs("Rules"));
3862 PrintFatalError(Combiner
->getLoc(), "Failed to parse one or more rules");
3867 Records
.startTimer("Creating Match Table");
3868 unsigned MaxTemporaries
= 0;
3869 for (const auto &Rule
: Rules
)
3870 MaxTemporaries
= std::max(MaxTemporaries
, Rule
.countRendererFns());
3872 llvm::stable_sort(Rules
, [&](const RuleMatcher
&A
, const RuleMatcher
&B
) {
3873 if (A
.isHigherPriorityThan(B
)) {
3874 assert(!B
.isHigherPriorityThan(A
) && "Cannot be more important "
3875 "and less important at "
3882 const MatchTable Table
= buildMatchTable(Rules
);
3884 Records
.startTimer("Emit combiner");
3886 emitSourceFileHeader(getClassName().str() + " Combiner Match Table", OS
);
3889 std::vector
<StringRef
> CustomRendererFns
;
3891 std::vector
<Record
*> ComplexPredicates
;
3893 SmallVector
<LLTCodeGen
, 16> TypeObjects
;
3894 append_range(TypeObjects
, KnownTypes
);
3895 llvm::sort(TypeObjects
);
3897 // Hack: Avoid empty declarator.
3898 if (TypeObjects
.empty())
3899 TypeObjects
.push_back(LLT::scalar(1));
3901 // GET_GICOMBINER_DEPS, which pulls in extra dependencies.
3902 OS
<< "#ifdef GET_GICOMBINER_DEPS\n"
3903 << "#include \"llvm/ADT/SparseBitVector.h\"\n"
3904 << "namespace llvm {\n"
3905 << "extern cl::OptionCategory GICombinerOptionCategory;\n"
3906 << "} // end namespace llvm\n"
3907 << "#endif // ifdef GET_GICOMBINER_DEPS\n\n";
3909 // GET_GICOMBINER_TYPES, which needs to be included before the declaration of
3911 OS
<< "#ifdef GET_GICOMBINER_TYPES\n";
3912 emitRuleConfigImpl(OS
);
3913 OS
<< "#endif // ifdef GET_GICOMBINER_TYPES\n\n";
3914 emitPredicateBitset(OS
, "GET_GICOMBINER_TYPES");
3916 // GET_GICOMBINER_CLASS_MEMBERS, which need to be included inside the class.
3917 emitPredicatesDecl(OS
, "GET_GICOMBINER_CLASS_MEMBERS");
3918 emitTemporariesDecl(OS
, "GET_GICOMBINER_CLASS_MEMBERS");
3920 // GET_GICOMBINER_IMPL, which needs to be included outside the class.
3921 emitExecutorImpl(OS
, Table
, TypeObjects
, Rules
, ComplexPredicates
,
3922 CustomRendererFns
, "GET_GICOMBINER_IMPL");
3924 // GET_GICOMBINER_CONSTRUCTOR_INITS, which are in the constructor's
3925 // initializer list.
3926 emitPredicatesInit(OS
, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3927 emitTemporariesInit(OS
, MaxTemporaries
, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3930 } // end anonymous namespace
3932 //===----------------------------------------------------------------------===//
3934 static void EmitGICombiner(RecordKeeper
&RK
, raw_ostream
&OS
) {
3935 EnablePrettyStackTrace();
3936 CodeGenTarget
Target(RK
);
3938 if (SelectedCombiners
.empty())
3939 PrintFatalError("No combiners selected with -combiners");
3940 for (const auto &Combiner
: SelectedCombiners
) {
3941 Record
*CombinerDef
= RK
.getDef(Combiner
);
3943 PrintFatalError("Could not find " + Combiner
);
3944 GICombinerEmitter(RK
, Target
, Combiner
, CombinerDef
).run(OS
);
3948 static TableGen::Emitter::Opt
X("gen-global-isel-combiner", EmitGICombiner
,
3949 "Generate GlobalISel Combiner");