xref: /llvm-project/llvm/utils/TableGen/Common/GlobalISel/Patterns.h (revision 8a61bfcf8f3e569d7f1d8fcb8958c02ec4aa6e7f)
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 
30 namespace llvm {
31 
32 class Record;
33 class SMLoc;
34 class StringInit;
35 class CodeExpansions;
36 class CodeGenInstruction;
37 struct CodeGenIntrinsic;
38 
39 namespace gi {
40 
41 class CXXPredicateCode;
42 class LLTCodeGen;
43 class LLTCodeGenOrTempType;
44 class RuleMatcher;
45 
46 //===- PatternType --------------------------------------------------------===//
47 
48 struct 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.
66 class PatternType {
67 public:
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 
105 private:
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
135 class Pattern {
136 public:
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 
157 protected:
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 
165 private:
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.
178 class AnyOpcodePattern : public Pattern {
179 public:
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(I); }
185   const auto &insts() const { return Insts; }
186 
187   void print(raw_ostream &OS, bool PrintName = true) const override;
188 
189 private:
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.
215 class CXXPattern : public Pattern {
216 public:
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 
249 private:
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
268 class InstructionOperand {
269 public:
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 
309 private:
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.
319 class InstructionPattern : public Pattern {
320 public:
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(Operands,
354                              [&](auto &O) { return O.isNamedOperand(); });
355   }
356 
357   auto named_operands() const {
358     return make_filter_range(Operands,
359                              [&](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 
379 protected:
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.
392 class OperandTable {
393 public:
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(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 
424 private:
425   StringMap<InstructionPattern *> Table;
426 };
427 
428 //===- MIFlagsInfo --------------------------------------------------------===//
429 
430 /// Helper class to contain data associated with a MIFlags operand.
431 class MIFlagsInfo {
432 public:
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 
441 private:
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.
456 class CodeGenInstructionPattern : public InstructionPattern {
457 public:
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 
482 private:
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.
500 class OperandTypeChecker {
501 public:
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 
513 protected:
514   ArrayRef<SMLoc> DiagLoc;
515 
516 private:
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.
554 class PatFrag {
555 public:
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 
634 private:
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.
648 class PatFragPattern : public InstructionPattern {
649 public:
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 
685 private:
686   const PatFrag &PF;
687 };
688 
689 //===- BuiltinPattern -----------------------------------------------------===//
690 
691 /// Represents builtin instructions such as "GIReplaceReg" and "GIEraseRoot".
692 enum BuiltinKind {
693   BI_ReplaceReg,
694   BI_EraseRoot,
695 };
696 
697 class 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 = {{
706       {"GIReplaceReg", BI_ReplaceReg, 2, 1},
707       {"GIEraseRoot", BI_EraseRoot, 0, 0},
708   }};
709 
710 public:
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 
725 private:
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