1 //===- Patterns.h ----------------------------------------------*- C++ -*-===//
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 Contains the Pattern hierarchy alongside helper classes such as
10 /// PatFrag, MIFlagsInfo, PatternType, etc.
12 /// These classes are used by the GlobalISel Combiner backend to help parse,
13 /// process and emit MIR patterns.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H
18 #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/SetVector.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/Twine.h"
36 class CodeGenInstruction
;
37 struct CodeGenIntrinsic
;
41 class CXXPredicateCode
;
43 class LLTCodeGenOrTempType
;
46 //===- PatternType --------------------------------------------------------===//
48 struct VariadicPackTypeInfo
{
49 VariadicPackTypeInfo(unsigned Min
, unsigned Max
) : Min(Min
), Max(Max
) {
50 assert(Min
>= 1 && (Max
>= Min
|| Max
== 0));
53 bool operator==(const VariadicPackTypeInfo
&Other
) const {
54 return Min
== Other
.Min
&& Max
== Other
.Max
;
61 /// Represent the type of a Pattern Operand.
63 /// Types have two form:
64 /// - LLTs, which are straightforward.
65 /// - Special types, e.g. GITypeOf, Variadic arguments list.
68 static constexpr StringLiteral SpecialTyClassName
= "GISpecialType";
69 static constexpr StringLiteral TypeOfClassName
= "GITypeOf";
70 static constexpr StringLiteral VariadicClassName
= "GIVariadic";
72 enum PTKind
: uint8_t {
80 PatternType() : Kind(PT_None
), Data() {}
82 static std::optional
<PatternType
> get(ArrayRef
<SMLoc
> DiagLoc
,
83 const Record
*R
, Twine DiagCtx
);
84 static PatternType
getTypeOf(StringRef OpName
);
86 bool isNone() const { return Kind
== PT_None
; }
87 bool isLLT() const { return Kind
== PT_ValueType
; }
88 bool isSpecial() const { return isTypeOf() || isVariadicPack(); }
89 bool isTypeOf() const { return Kind
== PT_TypeOf
; }
90 bool isVariadicPack() const { return Kind
== PT_VariadicPack
; }
92 PTKind
getKind() const { return Kind
; }
94 StringRef
getTypeOfOpName() const;
95 const Record
*getLLTRecord() const;
96 VariadicPackTypeInfo
getVariadicPackTypeInfo() const;
98 explicit operator bool() const { return !isNone(); }
100 bool operator==(const PatternType
&Other
) const;
101 bool operator!=(const PatternType
&Other
) const { return !operator==(Other
); }
103 std::string
str() const;
106 PatternType(PTKind Kind
) : Kind(Kind
), Data() {}
112 /// PT_ValueType -> ValueType Def.
115 /// PT_TypeOf -> Operand name (without the '$')
118 /// PT_VariadicPack -> min-max number of operands allowed.
119 VariadicPackTypeInfo VPTI
;
123 //===- Pattern Base Class -------------------------------------------------===//
125 /// Base class for all patterns that can be written in an `apply`, `match` or
126 /// `pattern` DAG operator.
130 /// (apply (G_ZEXT $x, $y), (G_ZEXT $y, $z), "return isFoo(${z})")
132 /// Creates 3 Pattern objects:
133 /// - Two CodeGenInstruction Patterns
141 K_CodeGenInstruction
,
146 virtual ~Pattern() = default;
148 unsigned getKind() const { return Kind
; }
149 const char *getKindName() const;
151 bool hasName() const { return !Name
.empty(); }
152 StringRef
getName() const { return Name
; }
154 virtual void print(raw_ostream
&OS
, bool PrintName
= true) const = 0;
158 Pattern(unsigned Kind
, StringRef Name
) : Kind(Kind
), Name(Name
) {
159 assert(!Name
.empty() && "unnamed pattern!");
162 void printImpl(raw_ostream
&OS
, bool PrintName
,
163 function_ref
<void()> ContentPrinter
) const;
170 //===- AnyOpcodePattern ---------------------------------------------------===//
172 /// `wip_match_opcode` patterns.
173 /// This matches one or more opcodes, and does not check any operands
176 /// TODO: Long-term, this needs to be removed. It's a hack around MIR
177 /// pattern matching limitations.
178 class AnyOpcodePattern
: public Pattern
{
180 AnyOpcodePattern(StringRef Name
) : Pattern(K_AnyOpcode
, Name
) {}
182 static bool classof(const Pattern
*P
) { return P
->getKind() == K_AnyOpcode
; }
184 void addOpcode(const CodeGenInstruction
*I
) { Insts
.push_back(I
); }
185 const auto &insts() const { return Insts
; }
187 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
190 SmallVector
<const CodeGenInstruction
*, 4> Insts
;
193 //===- CXXPattern ---------------------------------------------------------===//
195 /// Represents raw C++ code which may need some expansions.
197 /// e.g. [{ return isFooBux(${src}.getReg()); }]
199 /// For the expanded code, \see CXXPredicateCode. CXXPredicateCode objects are
200 /// created through `expandCode`.
202 /// \see CodeExpander and \see CodeExpansions for more information on code
205 /// This object has two purposes:
206 /// - Represent C++ code as a pattern entry.
207 /// - Be a factory for expanded C++ code.
208 /// - It's immutable and only holds the raw code so we can expand the same
209 /// CXX pattern multiple times if we need to.
211 /// Note that the code is always trimmed in the constructor, so leading and
212 /// trailing whitespaces are removed. This removes bloat in the output, avoids
213 /// formatting issues, but also allows us to check things like
214 /// `.startswith("return")` trivially without worrying about spaces.
215 class CXXPattern
: public Pattern
{
217 CXXPattern(const StringInit
&Code
, StringRef Name
);
219 CXXPattern(StringRef Code
, StringRef Name
)
220 : Pattern(K_CXX
, Name
), RawCode(Code
.trim().str()) {}
222 static bool classof(const Pattern
*P
) { return P
->getKind() == K_CXX
; }
224 void setIsApply(bool Value
= true) { IsApply
= Value
; }
225 StringRef
getRawCode() const { return RawCode
; }
227 /// Expands raw code, replacing things such as `${foo}` with their
228 /// substitution in \p CE.
230 /// Can only be used on 'match' CXX Patterns. 'apply' CXX pattern emission
231 /// is handled differently as we emit both the 'match' and 'apply' part
232 /// together in a single Custom CXX Action.
234 /// \param CE Map of Code Expansions
235 /// \param Locs SMLocs for the Code Expander, in case it needs to emit
237 /// \param AddComment Optionally called to emit a comment before the expanded
240 /// \return A CXXPredicateCode object that contains the expanded code. Note
241 /// that this may or may not insert a new object. All CXXPredicateCode objects
242 /// are held in a set to avoid emitting duplicate C++ code.
243 const CXXPredicateCode
&
244 expandCode(const CodeExpansions
&CE
, ArrayRef
<SMLoc
> Locs
,
245 function_ref
<void(raw_ostream
&)> AddComment
= {}) const;
247 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
250 bool IsApply
= false;
254 //===- InstructionPattern ---------------------------------------------===//
256 /// An operand for an InstructionPattern.
258 /// Operands are composed of three elements:
259 /// - (Optional) Value
260 /// - (Optional) Name
261 /// - (Optional) Type
264 /// (i32 0):$x -> V=int(0), Name='x', Type=i32
265 /// 0:$x -> V=int(0), Name='x'
267 /// i32:$x -> Name='x', Type = i32
268 class InstructionOperand
{
270 using IntImmTy
= int64_t;
272 InstructionOperand(IntImmTy Imm
, StringRef Name
, PatternType Type
)
273 : Value(Imm
), Name(Name
), Type(Type
) {}
275 InstructionOperand(StringRef Name
, PatternType Type
)
276 : Name(Name
), Type(Type
) {}
278 bool isNamedImmediate() const { return hasImmValue() && isNamedOperand(); }
280 bool hasImmValue() const { return Value
.has_value(); }
281 IntImmTy
getImmValue() const { return *Value
; }
283 bool isNamedOperand() const { return !Name
.empty(); }
284 StringRef
getOperandName() const {
285 assert(isNamedOperand() && "Operand is unnamed");
289 InstructionOperand
withNewName(StringRef NewName
) const {
290 InstructionOperand Result
= *this;
291 Result
.Name
= NewName
;
295 void setIsDef(bool Value
= true) { Def
= Value
; }
296 bool isDef() const { return Def
; }
298 void setType(PatternType NewType
) {
299 assert((!Type
|| (Type
== NewType
)) && "Overwriting type!");
302 PatternType
getType() const { return Type
; }
304 std::string
describe() const;
305 void print(raw_ostream
&OS
) const;
310 std::optional
<int64_t> Value
;
316 /// Base class for CodeGenInstructionPattern & PatFragPattern, which handles all
317 /// the boilerplate for patterns that have a list of operands for some (pseudo)
319 class InstructionPattern
: public Pattern
{
321 virtual ~InstructionPattern() = default;
323 static bool classof(const Pattern
*P
) {
324 return P
->getKind() == K_CodeGenInstruction
|| P
->getKind() == K_PatFrag
||
325 P
->getKind() == K_Builtin
;
328 template <typename
... Ty
> void addOperand(Ty
&&...Init
) {
329 Operands
.emplace_back(std::forward
<Ty
>(Init
)...);
332 auto &operands() { return Operands
; }
333 const auto &operands() const { return Operands
; }
334 unsigned operands_size() const { return Operands
.size(); }
335 InstructionOperand
&getOperand(unsigned K
) { return Operands
[K
]; }
336 const InstructionOperand
&getOperand(unsigned K
) const { return Operands
[K
]; }
338 const InstructionOperand
&operands_back() const { return Operands
.back(); }
340 /// When this InstructionPattern is used as the match root, returns the
341 /// operands that must be redefined in the 'apply' pattern for the rule to be
344 /// For most patterns, this just returns the defs.
345 /// For PatFrag this only returns the root of the PF.
347 /// Returns an empty array on error.
348 virtual ArrayRef
<InstructionOperand
> getApplyDefsNeeded() const {
349 return {operands().begin(), getNumInstDefs()};
352 auto named_operands() {
353 return make_filter_range(Operands
,
354 [&](auto &O
) { return O
.isNamedOperand(); });
357 auto named_operands() const {
358 return make_filter_range(Operands
,
359 [&](auto &O
) { return O
.isNamedOperand(); });
362 virtual bool isVariadic() const { return false; }
363 virtual unsigned getNumInstOperands() const = 0;
364 virtual unsigned getNumInstDefs() const = 0;
366 bool hasAllDefs() const { return operands_size() >= getNumInstDefs(); }
368 virtual StringRef
getInstName() const = 0;
370 /// Diagnoses all uses of special types in this Pattern and returns true if at
371 /// least one diagnostic was emitted.
372 bool diagnoseAllSpecialTypes(ArrayRef
<SMLoc
> Loc
, Twine Msg
) const;
374 void reportUnreachable(ArrayRef
<SMLoc
> Locs
) const;
375 virtual bool checkSemantics(ArrayRef
<SMLoc
> Loc
);
377 void print(raw_ostream
&OS
, bool PrintName
= true) const override
;
380 InstructionPattern(unsigned K
, StringRef Name
) : Pattern(K
, Name
) {}
382 virtual void printExtras(raw_ostream
&OS
) const {}
384 SmallVector
<InstructionOperand
, 4> Operands
;
387 //===- OperandTable -------------------------------------------------------===//
389 /// Maps InstructionPattern operands to their definitions. This allows us to tie
390 /// different patterns of a (apply), (match) or (patterns) set of patterns
394 bool addPattern(InstructionPattern
*P
,
395 function_ref
<void(StringRef
)> DiagnoseRedef
);
397 struct LookupResult
{
398 LookupResult() = default;
399 LookupResult(InstructionPattern
*Def
) : Found(true), Def(Def
) {}
402 InstructionPattern
*Def
= nullptr;
404 bool isLiveIn() const { return Found
&& !Def
; }
407 LookupResult
lookup(StringRef OpName
) const {
408 if (auto It
= Table
.find(OpName
); It
!= Table
.end())
409 return LookupResult(It
->second
);
410 return LookupResult();
413 InstructionPattern
*getDef(StringRef OpName
) const {
414 return lookup(OpName
).Def
;
417 void print(raw_ostream
&OS
, StringRef Name
= "", StringRef Indent
= "") const;
419 auto begin() const { return Table
.begin(); }
420 auto end() const { return Table
.end(); }
425 StringMap
<InstructionPattern
*> Table
;
428 //===- MIFlagsInfo --------------------------------------------------------===//
430 /// Helper class to contain data associated with a MIFlags operand.
433 void addSetFlag(const Record
*R
);
434 void addUnsetFlag(const Record
*R
);
435 void addCopyFlag(StringRef InstName
);
437 const auto &set_flags() const { return SetF
; }
438 const auto &unset_flags() const { return UnsetF
; }
439 const auto ©_flags() const { return CopyF
; }
442 SetVector
<StringRef
> SetF
, UnsetF
, CopyF
;
445 //===- CodeGenInstructionPattern ------------------------------------------===//
447 /// Matches an instruction or intrinsic:
448 /// e.g. `G_ADD $x, $y, $z` or `int_amdgcn_cos $a`
450 /// Intrinsics are just normal instructions with a special operand for intrinsic
451 /// ID. Despite G_INTRINSIC opcodes being variadic, we consider that the
452 /// Intrinsic's info takes priority. This means we return:
453 /// - false for isVariadic() and other variadic-related queries.
454 /// - getNumInstDefs and getNumInstOperands use the intrinsic's in/out
456 class CodeGenInstructionPattern
: public InstructionPattern
{
458 CodeGenInstructionPattern(const CodeGenInstruction
&I
, StringRef Name
)
459 : InstructionPattern(K_CodeGenInstruction
, Name
), I(I
) {}
461 static bool classof(const Pattern
*P
) {
462 return P
->getKind() == K_CodeGenInstruction
;
465 bool is(StringRef OpcodeName
) const;
467 void setIntrinsic(const CodeGenIntrinsic
*I
) { IntrinInfo
= I
; }
468 const CodeGenIntrinsic
*getIntrinsic() const { return IntrinInfo
; }
469 bool isIntrinsic() const { return IntrinInfo
; }
471 bool hasVariadicDefs() const;
472 bool isVariadic() const override
;
473 unsigned getNumInstDefs() const override
;
474 unsigned getNumInstOperands() const override
;
476 MIFlagsInfo
&getOrCreateMIFlagsInfo();
477 const MIFlagsInfo
*getMIFlagsInfo() const { return FI
.get(); }
479 const CodeGenInstruction
&getInst() const { return I
; }
480 StringRef
getInstName() const override
;
483 void printExtras(raw_ostream
&OS
) const override
;
485 const CodeGenInstruction
&I
;
486 const CodeGenIntrinsic
*IntrinInfo
= nullptr;
487 std::unique_ptr
<MIFlagsInfo
> FI
;
490 //===- OperandTypeChecker -------------------------------------------------===//
492 /// This is a trivial type checker for all operands in a set of
493 /// InstructionPatterns.
495 /// It infers the type of each operand, check it's consistent with the known
496 /// type of the operand, and then sets all of the types in all operands in
499 /// It also handles verifying correctness of special types.
500 class OperandTypeChecker
{
502 OperandTypeChecker(ArrayRef
<SMLoc
> DiagLoc
) : DiagLoc(DiagLoc
) {}
504 /// Step 1: Check each pattern one by one. All patterns that pass through here
505 /// are added to a common worklist so propagateTypes can access them.
506 bool check(InstructionPattern
&P
,
507 std::function
<bool(const PatternType
&)> VerifyTypeOfOperand
);
509 /// Step 2: Propagate all types. e.g. if one use of "$a" has type i32, make
510 /// all uses of "$a" have type i32.
511 void propagateTypes();
514 ArrayRef
<SMLoc
> DiagLoc
;
517 using InconsistentTypeDiagFn
= std::function
<void()>;
519 void PrintSeenWithTypeIn(InstructionPattern
&P
, StringRef OpName
,
520 PatternType Ty
) const;
524 InconsistentTypeDiagFn PrintTypeSrcNote
= []() {};
527 StringMap
<OpTypeInfo
> Types
;
529 SmallVector
<InstructionPattern
*, 16> Pats
;
532 //===- PatFrag ------------------------------------------------------------===//
534 /// Represents a parsed GICombinePatFrag. This can be thought of as the
535 /// equivalent of a CodeGenInstruction, but for PatFragPatterns.
537 /// PatFrags are made of 3 things:
538 /// - Out parameters (defs)
540 /// - A set of pattern lists (alternatives).
542 /// If the PatFrag uses instruction patterns, the root must be one of the defs.
544 /// Note that this DOES NOT represent the use of the PatFrag, only its
545 /// definition. The use of the PatFrag in a Pattern is represented by
548 /// PatFrags use the term "parameter" instead of operand because they're
549 /// essentially macros, and using that name avoids confusion. Other than that,
550 /// they're structured similarly to a MachineInstruction - all parameters
551 /// (operands) are in the same list, with defs at the start. This helps mapping
552 /// parameters to values, because, param N of a PatFrag is always operand N of a
556 static constexpr StringLiteral ClassName
= "GICombinePatFrag";
569 using ParamVec
= SmallVector
<Param
, 4>;
570 using ParamIt
= ParamVec::const_iterator
;
572 /// Represents an alternative of the PatFrag. When parsing a GICombinePatFrag,
573 /// this is created from its "Alternatives" list. Each alternative is a list
574 /// of patterns written wrapped in a `(pattern ...)` dag init.
576 /// Each argument to the `pattern` DAG operator is parsed into a Pattern
579 OperandTable OpTable
;
580 SmallVector
<std::unique_ptr
<Pattern
>, 4> Pats
;
583 explicit PatFrag(const Record
&Def
);
585 static StringRef
getParamKindStr(ParamKind OK
);
587 StringRef
getName() const;
589 const Record
&getDef() const { return Def
; }
590 ArrayRef
<SMLoc
> getLoc() const;
592 Alternative
&addAlternative() { return Alts
.emplace_back(); }
593 const Alternative
&getAlternative(unsigned K
) const { return Alts
[K
]; }
594 unsigned num_alternatives() const { return Alts
.size(); }
596 void addInParam(StringRef Name
, ParamKind Kind
);
597 iterator_range
<ParamIt
> in_params() const;
598 unsigned num_in_params() const { return Params
.size() - NumOutParams
; }
600 void addOutParam(StringRef Name
, ParamKind Kind
);
601 iterator_range
<ParamIt
> out_params() const;
602 unsigned num_out_params() const { return NumOutParams
; }
604 unsigned num_roots() const;
605 unsigned num_params() const { return num_in_params() + num_out_params(); }
607 /// Finds the operand \p Name and returns its index or -1 if not found.
608 /// Remember that all params are part of the same list, with out params at the
609 /// start. This means that the index returned can be used to access operands
610 /// of InstructionPatterns.
611 unsigned getParamIdx(StringRef Name
) const;
612 const Param
&getParam(unsigned K
) const { return Params
[K
]; }
614 bool canBeMatchRoot() const { return num_roots() == 1; }
616 void print(raw_ostream
&OS
, StringRef Indent
= "") const;
619 /// Checks if the in-param \p ParamName can be unbound or not.
620 /// \p ArgName is the name of the argument passed to the PatFrag.
622 /// An argument can be unbound only if, for all alternatives:
623 /// - There is no CXX pattern, OR:
624 /// - There is an InstructionPattern that binds the parameter.
626 /// e.g. in (MyPatFrag $foo), if $foo has never been seen before (= it's
627 /// unbound), this checks if MyPatFrag supports it or not.
628 bool handleUnboundInParam(StringRef ParamName
, StringRef ArgName
,
629 ArrayRef
<SMLoc
> DiagLoc
) const;
631 bool checkSemantics();
632 bool buildOperandsTables();
635 static void printParamsList(raw_ostream
&OS
, iterator_range
<ParamIt
> Params
);
637 void PrintError(Twine Msg
) const;
640 unsigned NumOutParams
= 0;
642 SmallVector
<Alternative
, 2> Alts
;
645 //===- PatFragPattern -----------------------------------------------------===//
647 /// Represents a use of a GICombinePatFrag.
648 class PatFragPattern
: public InstructionPattern
{
650 PatFragPattern(const PatFrag
&PF
, StringRef Name
)
651 : InstructionPattern(K_PatFrag
, Name
), PF(PF
) {}
653 static bool classof(const Pattern
*P
) { return P
->getKind() == K_PatFrag
; }
655 const PatFrag
&getPatFrag() const { return PF
; }
656 StringRef
getInstName() const override
{ return PF
.getName(); }
658 unsigned getNumInstDefs() const override
{ return PF
.num_out_params(); }
659 unsigned getNumInstOperands() const override
{ return PF
.num_params(); }
661 ArrayRef
<InstructionOperand
> getApplyDefsNeeded() const override
;
663 bool checkSemantics(ArrayRef
<SMLoc
> DiagLoc
) override
;
665 /// Before emitting the patterns inside the PatFrag, add all necessary code
666 /// expansions to \p PatFragCEs imported from \p ParentCEs.
668 /// For a MachineOperand PatFrag parameter, this will fetch the expansion for
669 /// that operand from \p ParentCEs and add it to \p PatFragCEs. Errors can be
670 /// emitted if the MachineOperand reference is unbound.
672 /// For an Immediate PatFrag parameter this simply adds the integer value to
673 /// \p PatFragCEs as an expansion.
675 /// \param ParentCEs Contains all of the code expansions declared by the other
676 /// patterns emitted so far in the pattern list containing
677 /// this PatFragPattern.
678 /// \param PatFragCEs Output Code Expansions (usually empty)
679 /// \param DiagLoc Diagnostic loc in case an error occurs.
680 /// \return `true` on success, `false` on failure.
681 bool mapInputCodeExpansions(const CodeExpansions
&ParentCEs
,
682 CodeExpansions
&PatFragCEs
,
683 ArrayRef
<SMLoc
> DiagLoc
) const;
689 //===- BuiltinPattern -----------------------------------------------------===//
691 /// Represents builtin instructions such as "GIReplaceReg" and "GIEraseRoot".
697 class BuiltinPattern
: public InstructionPattern
{
699 StringLiteral DefName
;
705 static constexpr std::array
<BuiltinInfo
, 2> KnownBuiltins
= {{
706 {"GIReplaceReg", BI_ReplaceReg
, 2, 1},
707 {"GIEraseRoot", BI_EraseRoot
, 0, 0},
711 static constexpr StringLiteral ClassName
= "GIBuiltinInst";
713 BuiltinPattern(const Record
&Def
, StringRef Name
)
714 : InstructionPattern(K_Builtin
, Name
), I(getBuiltinInfo(Def
)) {}
716 static bool classof(const Pattern
*P
) { return P
->getKind() == K_Builtin
; }
718 unsigned getNumInstOperands() const override
{ return I
.NumOps
; }
719 unsigned getNumInstDefs() const override
{ return I
.NumDefs
; }
720 StringRef
getInstName() const override
{ return I
.DefName
; }
721 BuiltinKind
getBuiltinKind() const { return I
.Kind
; }
723 bool checkSemantics(ArrayRef
<SMLoc
> Loc
) override
;
726 static BuiltinInfo
getBuiltinInfo(const Record
&Def
);
732 } // end namespace llvm
734 #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H