1//===- Patterns.h ----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file Contains the Pattern hierarchy alongside helper classes such as
10/// PatFrag, MIFlagsInfo, PatternType, etc.
11///
12/// These classes are used by the GlobalISel Combiner backend to help parse,
13/// process and emit MIR patterns.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H
18#define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H
19
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"
26#include <memory>
27#include <optional>
28#include <string>
29
30namespace llvm {
31
32class Record;
33class SMLoc;
34class StringInit;
35class CodeExpansions;
36class CodeGenInstruction;
37struct CodeGenIntrinsic;
38
39namespace gi {
40
41class CXXPredicateCode;
42class LLTCodeGen;
43class LLTCodeGenOrTempType;
44class RuleMatcher;
45
46//===- PatternType --------------------------------------------------------===//
47
48struct VariadicPackTypeInfo {
49 VariadicPackTypeInfo(unsigned Min, unsigned Max) : Min(Min), Max(Max) {
50 assert(Min >= 1 && (Max >= Min || Max == 0));
51 }
52
53 bool operator==(const VariadicPackTypeInfo &Other) const {
54 return Min == Other.Min && Max == Other.Max;
55 }
56
57 unsigned Min;
58 unsigned Max;
59};
60
61/// Represent the type of a Pattern Operand.
62///
63/// Types have two form:
64/// - LLTs, which are straightforward.
65/// - Special types, e.g. GITypeOf, Variadic arguments list.
66class PatternType {
67public:
68 static constexpr StringLiteral SpecialTyClassName = "GISpecialType";
69 static constexpr StringLiteral TypeOfClassName = "GITypeOf";
70 static constexpr StringLiteral VariadicClassName = "GIVariadic";
71
72 enum PTKind : uint8_t {
73 PT_None,
74
75 PT_ValueType,
76 PT_TypeOf,
77 PT_VariadicPack,
78 };
79
80 PatternType() : Kind(PT_None), Data() {}
81
82 static std::optional<PatternType> get(ArrayRef<SMLoc> DiagLoc,
83 const Record *R, Twine DiagCtx);
84 static PatternType getTypeOf(StringRef OpName);
85
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; }
91
92 PTKind getKind() const { return Kind; }
93
94 StringRef getTypeOfOpName() const;
95 const Record *getLLTRecord() const;
96 VariadicPackTypeInfo getVariadicPackTypeInfo() const;
97
98 explicit operator bool() const { return !isNone(); }
99
100 bool operator==(const PatternType &Other) const;
101 bool operator!=(const PatternType &Other) const { return !operator==(Other); }
102
103 std::string str() const;
104
105private:
106 PatternType(PTKind Kind) : Kind(Kind), Data() {}
107
108 PTKind Kind;
109 union DataT {
110 DataT() : Str() {}
111
112 /// PT_ValueType -> ValueType Def.
113 const Record *Def;
114
115 /// PT_TypeOf -> Operand name (without the '$')
116 StringRef Str;
117
118 /// PT_VariadicPack -> min-max number of operands allowed.
119 VariadicPackTypeInfo VPTI;
120 } Data;
121};
122
123//===- Pattern Base Class -------------------------------------------------===//
124
125/// Base class for all patterns that can be written in an `apply`, `match` or
126/// `pattern` DAG operator.
127///
128/// For example:
129///
130/// (apply (G_ZEXT $x, $y), (G_ZEXT $y, $z), "return isFoo(${z})")
131///
132/// Creates 3 Pattern objects:
133/// - Two CodeGenInstruction Patterns
134/// - A CXXPattern
135class Pattern {
136public:
137 enum {
138 K_AnyOpcode,
139 K_CXX,
140
141 K_CodeGenInstruction,
142 K_PatFrag,
143 K_Builtin,
144 };
145
146 virtual ~Pattern() = default;
147
148 unsigned getKind() const { return Kind; }
149 const char *getKindName() const;
150
151 bool hasName() const { return !Name.empty(); }
152 StringRef getName() const { return Name; }
153
154 virtual void print(raw_ostream &OS, bool PrintName = true) const = 0;
155 void dump() const;
156
157protected:
158 Pattern(unsigned Kind, StringRef Name) : Kind(Kind), Name(Name) {
159 assert(!Name.empty() && "unnamed pattern!");
160 }
161
162 void printImpl(raw_ostream &OS, bool PrintName,
163 function_ref<void()> ContentPrinter) const;
164
165private:
166 unsigned Kind;
167 StringRef Name;
168};
169
170//===- AnyOpcodePattern ---------------------------------------------------===//
171
172/// `wip_match_opcode` patterns.
173/// This matches one or more opcodes, and does not check any operands
174/// whatsoever.
175///
176/// TODO: Long-term, this needs to be removed. It's a hack around MIR
177/// pattern matching limitations.
178class AnyOpcodePattern : public Pattern {
179public:
180 AnyOpcodePattern(StringRef Name) : Pattern(K_AnyOpcode, Name) {}
181
182 static bool classof(const Pattern *P) { return P->getKind() == K_AnyOpcode; }
183
184 void addOpcode(const CodeGenInstruction *I) { Insts.push_back(Elt: I); }
185 const auto &insts() const { return Insts; }
186
187 void print(raw_ostream &OS, bool PrintName = true) const override;
188
189private:
190 SmallVector<const CodeGenInstruction *, 4> Insts;
191};
192
193//===- CXXPattern ---------------------------------------------------------===//
194
195/// Represents raw C++ code which may need some expansions.
196///
197/// e.g. [{ return isFooBux(${src}.getReg()); }]
198///
199/// For the expanded code, \see CXXPredicateCode. CXXPredicateCode objects are
200/// created through `expandCode`.
201///
202/// \see CodeExpander and \see CodeExpansions for more information on code
203/// expansions.
204///
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.
210///
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.
215class CXXPattern : public Pattern {
216public:
217 CXXPattern(const StringInit &Code, StringRef Name);
218
219 CXXPattern(StringRef Code, StringRef Name)
220 : Pattern(K_CXX, Name), RawCode(Code.trim().str()) {}
221
222 static bool classof(const Pattern *P) { return P->getKind() == K_CXX; }
223
224 void setIsApply(bool Value = true) { IsApply = Value; }
225 StringRef getRawCode() const { return RawCode; }
226
227 /// Expands raw code, replacing things such as `${foo}` with their
228 /// substitution in \p CE.
229 ///
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.
233 ///
234 /// \param CE Map of Code Expansions
235 /// \param Locs SMLocs for the Code Expander, in case it needs to emit
236 /// diagnostics.
237 /// \param AddComment Optionally called to emit a comment before the expanded
238 /// code.
239 ///
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;
246
247 void print(raw_ostream &OS, bool PrintName = true) const override;
248
249private:
250 bool IsApply = false;
251 std::string RawCode;
252};
253
254//===- InstructionPattern ---------------------------------------------===//
255
256/// An operand for an InstructionPattern.
257///
258/// Operands are composed of three elements:
259/// - (Optional) Value
260/// - (Optional) Name
261/// - (Optional) Type
262///
263/// Some examples:
264/// (i32 0):$x -> V=int(0), Name='x', Type=i32
265/// 0:$x -> V=int(0), Name='x'
266/// $x -> Name='x'
267/// i32:$x -> Name='x', Type = i32
268class InstructionOperand {
269public:
270 using IntImmTy = int64_t;
271
272 InstructionOperand(IntImmTy Imm, StringRef Name, PatternType Type)
273 : Value(Imm), Name(Name), Type(Type) {}
274
275 InstructionOperand(StringRef Name, PatternType Type)
276 : Name(Name), Type(Type) {}
277
278 bool isNamedImmediate() const { return hasImmValue() && isNamedOperand(); }
279
280 bool hasImmValue() const { return Value.has_value(); }
281 IntImmTy getImmValue() const { return *Value; }
282
283 bool isNamedOperand() const { return !Name.empty(); }
284 StringRef getOperandName() const {
285 assert(isNamedOperand() && "Operand is unnamed");
286 return Name;
287 }
288
289 InstructionOperand withNewName(StringRef NewName) const {
290 InstructionOperand Result = *this;
291 Result.Name = NewName;
292 return Result;
293 }
294
295 void setIsDef(bool Value = true) { Def = Value; }
296 bool isDef() const { return Def; }
297
298 void setType(PatternType NewType) {
299 assert((!Type || (Type == NewType)) && "Overwriting type!");
300 Type = NewType;
301 }
302 PatternType getType() const { return Type; }
303
304 std::string describe() const;
305 void print(raw_ostream &OS) const;
306
307 void dump() const;
308
309private:
310 std::optional<int64_t> Value;
311 StringRef Name;
312 PatternType Type;
313 bool Def = false;
314};
315
316/// Base class for CodeGenInstructionPattern & PatFragPattern, which handles all
317/// the boilerplate for patterns that have a list of operands for some (pseudo)
318/// instruction.
319class InstructionPattern : public Pattern {
320public:
321 virtual ~InstructionPattern() = default;
322
323 static bool classof(const Pattern *P) {
324 return P->getKind() == K_CodeGenInstruction || P->getKind() == K_PatFrag ||
325 P->getKind() == K_Builtin;
326 }
327
328 template <typename... Ty> void addOperand(Ty &&...Init) {
329 Operands.emplace_back(std::forward<Ty>(Init)...);
330 }
331
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]; }
337
338 const InstructionOperand &operands_back() const { return Operands.back(); }
339
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
342 /// valid.
343 ///
344 /// For most patterns, this just returns the defs.
345 /// For PatFrag this only returns the root of the PF.
346 ///
347 /// Returns an empty array on error.
348 virtual ArrayRef<InstructionOperand> getApplyDefsNeeded() const {
349 return {operands().begin(), getNumInstDefs()};
350 }
351
352 auto named_operands() {
353 return make_filter_range(Range&: Operands,
354 Pred: [&](auto &O) { return O.isNamedOperand(); });
355 }
356
357 auto named_operands() const {
358 return make_filter_range(Range: Operands,
359 Pred: [&](auto &O) { return O.isNamedOperand(); });
360 }
361
362 virtual bool isVariadic() const { return false; }
363 virtual unsigned getNumInstOperands() const = 0;
364 virtual unsigned getNumInstDefs() const = 0;
365
366 bool hasAllDefs() const { return operands_size() >= getNumInstDefs(); }
367
368 virtual StringRef getInstName() const = 0;
369
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;
373
374 void reportUnreachable(ArrayRef<SMLoc> Locs) const;
375 virtual bool checkSemantics(ArrayRef<SMLoc> Loc);
376
377 void print(raw_ostream &OS, bool PrintName = true) const override;
378
379protected:
380 InstructionPattern(unsigned K, StringRef Name) : Pattern(K, Name) {}
381
382 virtual void printExtras(raw_ostream &OS) const {}
383
384 SmallVector<InstructionOperand, 4> Operands;
385};
386
387//===- OperandTable -------------------------------------------------------===//
388
389/// Maps InstructionPattern operands to their definitions. This allows us to tie
390/// different patterns of a (apply), (match) or (patterns) set of patterns
391/// together.
392class OperandTable {
393public:
394 bool addPattern(InstructionPattern *P,
395 function_ref<void(StringRef)> DiagnoseRedef);
396
397 struct LookupResult {
398 LookupResult() = default;
399 LookupResult(InstructionPattern *Def) : Found(true), Def(Def) {}
400
401 bool Found = false;
402 InstructionPattern *Def = nullptr;
403
404 bool isLiveIn() const { return Found && !Def; }
405 };
406
407 LookupResult lookup(StringRef OpName) const {
408 if (auto It = Table.find(Key: OpName); It != Table.end())
409 return LookupResult(It->second);
410 return LookupResult();
411 }
412
413 InstructionPattern *getDef(StringRef OpName) const {
414 return lookup(OpName).Def;
415 }
416
417 void print(raw_ostream &OS, StringRef Name = "", StringRef Indent = "") const;
418
419 auto begin() const { return Table.begin(); }
420 auto end() const { return Table.end(); }
421
422 void dump() const;
423
424private:
425 StringMap<InstructionPattern *> Table;
426};
427
428//===- MIFlagsInfo --------------------------------------------------------===//
429
430/// Helper class to contain data associated with a MIFlags operand.
431class MIFlagsInfo {
432public:
433 void addSetFlag(const Record *R);
434 void addUnsetFlag(const Record *R);
435 void addCopyFlag(StringRef InstName);
436
437 const auto &set_flags() const { return SetF; }
438 const auto &unset_flags() const { return UnsetF; }
439 const auto &copy_flags() const { return CopyF; }
440
441private:
442 SetVector<StringRef> SetF, UnsetF, CopyF;
443};
444
445//===- CodeGenInstructionPattern ------------------------------------------===//
446
447/// Matches an instruction or intrinsic:
448/// e.g. `G_ADD $x, $y, $z` or `int_amdgcn_cos $a`
449///
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
455/// operands.
456class CodeGenInstructionPattern : public InstructionPattern {
457public:
458 CodeGenInstructionPattern(const CodeGenInstruction &I, StringRef Name)
459 : InstructionPattern(K_CodeGenInstruction, Name), I(I) {}
460
461 static bool classof(const Pattern *P) {
462 return P->getKind() == K_CodeGenInstruction;
463 }
464
465 bool is(StringRef OpcodeName) const;
466
467 void setIntrinsic(const CodeGenIntrinsic *I) { IntrinInfo = I; }
468 const CodeGenIntrinsic *getIntrinsic() const { return IntrinInfo; }
469 bool isIntrinsic() const { return IntrinInfo; }
470
471 bool hasVariadicDefs() const;
472 bool isVariadic() const override;
473 unsigned getNumInstDefs() const override;
474 unsigned getNumInstOperands() const override;
475
476 MIFlagsInfo &getOrCreateMIFlagsInfo();
477 const MIFlagsInfo *getMIFlagsInfo() const { return FI.get(); }
478
479 const CodeGenInstruction &getInst() const { return I; }
480 StringRef getInstName() const override;
481
482private:
483 void printExtras(raw_ostream &OS) const override;
484
485 const CodeGenInstruction &I;
486 const CodeGenIntrinsic *IntrinInfo = nullptr;
487 std::unique_ptr<MIFlagsInfo> FI;
488};
489
490//===- OperandTypeChecker -------------------------------------------------===//
491
492/// This is a trivial type checker for all operands in a set of
493/// InstructionPatterns.
494///
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
497/// propagateTypes.
498///
499/// It also handles verifying correctness of special types.
500class OperandTypeChecker {
501public:
502 OperandTypeChecker(ArrayRef<SMLoc> DiagLoc) : DiagLoc(DiagLoc) {}
503
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);
508
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();
512
513protected:
514 ArrayRef<SMLoc> DiagLoc;
515
516private:
517 using InconsistentTypeDiagFn = std::function<void()>;
518
519 void PrintSeenWithTypeIn(InstructionPattern &P, StringRef OpName,
520 PatternType Ty) const;
521
522 struct OpTypeInfo {
523 PatternType Type;
524 InconsistentTypeDiagFn PrintTypeSrcNote = []() {};
525 };
526
527 StringMap<OpTypeInfo> Types;
528
529 SmallVector<InstructionPattern *, 16> Pats;
530};
531
532//===- PatFrag ------------------------------------------------------------===//
533
534/// Represents a parsed GICombinePatFrag. This can be thought of as the
535/// equivalent of a CodeGenInstruction, but for PatFragPatterns.
536///
537/// PatFrags are made of 3 things:
538/// - Out parameters (defs)
539/// - In parameters
540/// - A set of pattern lists (alternatives).
541///
542/// If the PatFrag uses instruction patterns, the root must be one of the defs.
543///
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
546/// PatFragPattern.
547///
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
553/// PatFragPattern.
554class PatFrag {
555public:
556 static constexpr StringLiteral ClassName = "GICombinePatFrag";
557
558 enum ParamKind {
559 PK_Root,
560 PK_MachineOperand,
561 PK_Imm,
562 };
563
564 struct Param {
565 StringRef Name;
566 ParamKind Kind;
567 };
568
569 using ParamVec = SmallVector<Param, 4>;
570 using ParamIt = ParamVec::const_iterator;
571
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.
575 ///
576 /// Each argument to the `pattern` DAG operator is parsed into a Pattern
577 /// instance.
578 struct Alternative {
579 OperandTable OpTable;
580 SmallVector<std::unique_ptr<Pattern>, 4> Pats;
581 };
582
583 explicit PatFrag(const Record &Def);
584
585 static StringRef getParamKindStr(ParamKind OK);
586
587 StringRef getName() const;
588
589 const Record &getDef() const { return Def; }
590 ArrayRef<SMLoc> getLoc() const;
591
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(); }
595
596 void addInParam(StringRef Name, ParamKind Kind);
597 iterator_range<ParamIt> in_params() const;
598 unsigned num_in_params() const { return Params.size() - NumOutParams; }
599
600 void addOutParam(StringRef Name, ParamKind Kind);
601 iterator_range<ParamIt> out_params() const;
602 unsigned num_out_params() const { return NumOutParams; }
603
604 unsigned num_roots() const;
605 unsigned num_params() const { return num_in_params() + num_out_params(); }
606
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]; }
613
614 bool canBeMatchRoot() const { return num_roots() == 1; }
615
616 void print(raw_ostream &OS, StringRef Indent = "") const;
617 void dump() const;
618
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.
621 ///
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.
625 ///
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;
630
631 bool checkSemantics();
632 bool buildOperandsTables();
633
634private:
635 static void printParamsList(raw_ostream &OS, iterator_range<ParamIt> Params);
636
637 void PrintError(Twine Msg) const;
638
639 const Record &Def;
640 unsigned NumOutParams = 0;
641 ParamVec Params;
642 SmallVector<Alternative, 2> Alts;
643};
644
645//===- PatFragPattern -----------------------------------------------------===//
646
647/// Represents a use of a GICombinePatFrag.
648class PatFragPattern : public InstructionPattern {
649public:
650 PatFragPattern(const PatFrag &PF, StringRef Name)
651 : InstructionPattern(K_PatFrag, Name), PF(PF) {}
652
653 static bool classof(const Pattern *P) { return P->getKind() == K_PatFrag; }
654
655 const PatFrag &getPatFrag() const { return PF; }
656 StringRef getInstName() const override { return PF.getName(); }
657
658 unsigned getNumInstDefs() const override { return PF.num_out_params(); }
659 unsigned getNumInstOperands() const override { return PF.num_params(); }
660
661 ArrayRef<InstructionOperand> getApplyDefsNeeded() const override;
662
663 bool checkSemantics(ArrayRef<SMLoc> DiagLoc) override;
664
665 /// Before emitting the patterns inside the PatFrag, add all necessary code
666 /// expansions to \p PatFragCEs imported from \p ParentCEs.
667 ///
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.
671 ///
672 /// For an Immediate PatFrag parameter this simply adds the integer value to
673 /// \p PatFragCEs as an expansion.
674 ///
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;
684
685private:
686 const PatFrag &PF;
687};
688
689//===- BuiltinPattern -----------------------------------------------------===//
690
691/// Represents builtin instructions such as "GIReplaceReg" and "GIEraseRoot".
692enum BuiltinKind {
693 BI_ReplaceReg,
694 BI_EraseRoot,
695};
696
697class BuiltinPattern : public InstructionPattern {
698 struct BuiltinInfo {
699 StringLiteral DefName;
700 BuiltinKind Kind;
701 unsigned NumOps;
702 unsigned NumDefs;
703 };
704
705 static constexpr std::array<BuiltinInfo, 2> KnownBuiltins = {._M_elems: {
706 {.DefName: "GIReplaceReg", .Kind: BI_ReplaceReg, .NumOps: 2, .NumDefs: 1},
707 {.DefName: "GIEraseRoot", .Kind: BI_EraseRoot, .NumOps: 0, .NumDefs: 0},
708 }};
709
710public:
711 static constexpr StringLiteral ClassName = "GIBuiltinInst";
712
713 BuiltinPattern(const Record &Def, StringRef Name)
714 : InstructionPattern(K_Builtin, Name), I(getBuiltinInfo(Def)) {}
715
716 static bool classof(const Pattern *P) { return P->getKind() == K_Builtin; }
717
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; }
722
723 bool checkSemantics(ArrayRef<SMLoc> Loc) override;
724
725private:
726 static BuiltinInfo getBuiltinInfo(const Record &Def);
727
728 BuiltinInfo I;
729};
730
731} // namespace gi
732} // end namespace llvm
733
734#endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H
735