xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- GlobalISelMatchTable.h ---------------------------------------------===//
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
10 /// This file contains the code related to the GlobalISel Match Table emitted by
11 /// GlobalISelEmitter.cpp. The generated match table is interpreted at runtime
12 /// by `GIMatchTableExecutorImpl.h` to match & apply ISel patterns.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLE_H
17 #define LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLE_H
18 
19 #include "Common/CodeGenDAGPatterns.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/CodeGenTypes/LowLevelType.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/SaveAndRestore.h"
28 #include <deque>
29 #include <list>
30 #include <map>
31 #include <memory>
32 #include <optional>
33 #include <set>
34 #include <string>
35 #include <vector>
36 
37 namespace llvm {
38 
39 class raw_ostream;
40 class Record;
41 class SMLoc;
42 class CodeGenRegisterClass;
43 
44 // Use a namespace to avoid conflicts because there's some fairly generic names
45 // in there (e.g. Matcher).
46 namespace gi {
47 class MatchTable;
48 class Matcher;
49 class OperandMatcher;
50 class MatchAction;
51 class PredicateMatcher;
52 class InstructionMatcher;
53 
54 enum {
55   GISF_IgnoreCopies = 0x1,
56 };
57 
58 using GISelFlags = std::uint16_t;
59 
60 //===- Helper functions ---------------------------------------------------===//
61 
62 void emitEncodingMacrosDef(raw_ostream &OS);
63 void emitEncodingMacrosUndef(raw_ostream &OS);
64 
65 std::string getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset,
66                                     int HwModeIdx);
67 
68 /// Takes a sequence of \p Rules and group them based on the predicates
69 /// they share. \p MatcherStorage is used as a memory container
70 /// for the group that are created as part of this process.
71 ///
72 /// What this optimization does looks like if GroupT = GroupMatcher:
73 /// Output without optimization:
74 /// \verbatim
75 /// # R1
76 ///  # predicate A
77 ///  # predicate B
78 ///  ...
79 /// # R2
80 ///  # predicate A // <-- effectively this is going to be checked twice.
81 ///                //     Once in R1 and once in R2.
82 ///  # predicate C
83 /// \endverbatim
84 /// Output with optimization:
85 /// \verbatim
86 /// # Group1_2
87 ///  # predicate A // <-- Check is now shared.
88 ///  # R1
89 ///   # predicate B
90 ///  # R2
91 ///   # predicate C
92 /// \endverbatim
93 template <class GroupT>
94 std::vector<Matcher *>
95 optimizeRules(ArrayRef<Matcher *> Rules,
96               std::vector<std::unique_ptr<Matcher>> &MatcherStorage);
97 
98 /// A record to be stored in a MatchTable.
99 ///
100 /// This class represents any and all output that may be required to emit the
101 /// MatchTable. Instances  are most often configured to represent an opcode or
102 /// value that will be emitted to the table with some formatting but it can also
103 /// represent commas, comments, and other formatting instructions.
104 struct MatchTableRecord {
105   enum RecordFlagsBits {
106     MTRF_None = 0x0,
107     /// Causes EmitStr to be formatted as comment when emitted.
108     MTRF_Comment = 0x1,
109     /// Causes the record value to be followed by a comma when emitted.
110     MTRF_CommaFollows = 0x2,
111     /// Causes the record value to be followed by a line break when emitted.
112     MTRF_LineBreakFollows = 0x4,
113     /// Indicates that the record defines a label and causes an additional
114     /// comment to be emitted containing the index of the label.
115     MTRF_Label = 0x8,
116     /// Causes the record to be emitted as the index of the label specified by
117     /// LabelID along with a comment indicating where that label is.
118     MTRF_JumpTarget = 0x10,
119     /// Causes the formatter to add a level of indentation before emitting the
120     /// record.
121     MTRF_Indent = 0x20,
122     /// Causes the formatter to remove a level of indentation after emitting the
123     /// record.
124     MTRF_Outdent = 0x40,
125     /// Causes the formatter to not use encoding macros to emit this multi-byte
126     /// value.
127     MTRF_PreEncoded = 0x80,
128   };
129 
130   /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
131   /// reference or define.
132   unsigned LabelID;
133   /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
134   /// value, a label name.
135   std::string EmitStr;
136 
137 private:
138   /// The number of MatchTable elements described by this record. Comments are 0
139   /// while values are typically 1. Values >1 may occur when we need to emit
140   /// values that exceed the size of a MatchTable element.
141   unsigned NumElements;
142 
143 public:
144   /// A bitfield of RecordFlagsBits flags.
145   unsigned Flags;
146 
147   /// The actual run-time value, if known
148   int64_t RawValue;
149 
150   MatchTableRecord(std::optional<unsigned> LabelID_, StringRef EmitStr,
151                    unsigned NumElements, unsigned Flags,
152                    int64_t RawValue = std::numeric_limits<int64_t>::min())
153       : LabelID(LabelID_.value_or(~0u)), EmitStr(EmitStr),
154         NumElements(NumElements), Flags(Flags), RawValue(RawValue) {
155     assert((!LabelID_ || LabelID != ~0u) &&
156            "This value is reserved for non-labels");
157   }
158   MatchTableRecord(const MatchTableRecord &Other) = default;
159   MatchTableRecord(MatchTableRecord &&Other) = default;
160 
161   /// Useful if a Match Table Record gets optimized out
turnIntoCommentMatchTableRecord162   void turnIntoComment() {
163     Flags |= MTRF_Comment;
164     Flags &= ~MTRF_CommaFollows;
165     NumElements = 0;
166   }
167 
168   /// For Jump Table generation purposes
169   bool operator<(const MatchTableRecord &Other) const {
170     return RawValue < Other.RawValue;
171   }
getRawValueMatchTableRecord172   int64_t getRawValue() const { return RawValue; }
173 
174   void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
175             const MatchTable &Table) const;
sizeMatchTableRecord176   unsigned size() const { return NumElements; }
177 };
178 
179 /// Holds the contents of a generated MatchTable to enable formatting and the
180 /// necessary index tracking needed to support GIM_Try.
181 class MatchTable {
182   /// An unique identifier for the table. The generated table will be named
183   /// MatchTable${ID}.
184   unsigned ID;
185   /// The records that make up the table. Also includes comments describing the
186   /// values being emitted and line breaks to format it.
187   std::vector<MatchTableRecord> Contents;
188   /// The currently defined labels.
189   DenseMap<unsigned, unsigned> LabelMap;
190   /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
191   unsigned CurrentSize = 0;
192   /// A unique identifier for a MatchTable label.
193   unsigned CurrentLabelID = 0;
194   /// Determines if the table should be instrumented for rule coverage tracking.
195   bool IsWithCoverage;
196   /// Whether this table is for the GISel combiner.
197   bool IsCombinerTable;
198 
199 public:
200   static MatchTableRecord LineBreak;
201   static MatchTableRecord Comment(StringRef Comment);
202   static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0);
203   static MatchTableRecord NamedValue(unsigned NumBytes, StringRef NamedValue);
204   static MatchTableRecord NamedValue(unsigned NumBytes, StringRef NamedValue,
205                                      int64_t RawValue);
206   static MatchTableRecord NamedValue(unsigned NumBytes, StringRef Namespace,
207                                      StringRef NamedValue);
208   static MatchTableRecord NamedValue(unsigned NumBytes, StringRef Namespace,
209                                      StringRef NamedValue, int64_t RawValue);
210   static MatchTableRecord IntValue(unsigned NumBytes, int64_t IntValue);
211   static MatchTableRecord ULEB128Value(uint64_t IntValue);
212   static MatchTableRecord Label(unsigned LabelID);
213   static MatchTableRecord JumpTarget(unsigned LabelID);
214 
215   static MatchTable buildTable(ArrayRef<Matcher *> Rules, bool WithCoverage,
216                                bool IsCombiner = false);
217 
218   MatchTable(bool WithCoverage, bool IsCombinerTable, unsigned ID = 0)
ID(ID)219       : ID(ID), IsWithCoverage(WithCoverage), IsCombinerTable(IsCombinerTable) {
220   }
221 
isWithCoverage()222   bool isWithCoverage() const { return IsWithCoverage; }
isCombiner()223   bool isCombiner() const { return IsCombinerTable; }
224 
push_back(const MatchTableRecord & Value)225   void push_back(const MatchTableRecord &Value) {
226     if (Value.Flags & MatchTableRecord::MTRF_Label)
227       defineLabel(Value.LabelID);
228     Contents.push_back(Value);
229     CurrentSize += Value.size();
230   }
231 
allocateLabelID()232   unsigned allocateLabelID() { return CurrentLabelID++; }
233 
defineLabel(unsigned LabelID)234   void defineLabel(unsigned LabelID) {
235     LabelMap.insert(std::pair(LabelID, CurrentSize));
236   }
237 
getLabelIndex(unsigned LabelID)238   unsigned getLabelIndex(unsigned LabelID) const {
239     const auto I = LabelMap.find(LabelID);
240     assert(I != LabelMap.end() && "Use of undeclared label");
241     return I->second;
242   }
243 
244   void emitUse(raw_ostream &OS) const;
245   void emitDeclaration(raw_ostream &OS) const;
246 };
247 
248 inline MatchTable &operator<<(MatchTable &Table,
249                               const MatchTableRecord &Value) {
250   Table.push_back(Value);
251   return Table;
252 }
253 
254 /// This class stands in for LLT wherever we want to tablegen-erate an
255 /// equivalent at compiler run-time.
256 class LLTCodeGen {
257 private:
258   LLT Ty;
259 
260 public:
261   LLTCodeGen() = default;
LLTCodeGen(const LLT & Ty)262   LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
263 
264   std::string getCxxEnumValue() const;
265 
266   void emitCxxEnumValue(raw_ostream &OS) const;
267   void emitCxxConstructorCall(raw_ostream &OS) const;
268 
get()269   const LLT &get() const { return Ty; }
270 
271   /// This ordering is used for std::unique() and llvm::sort(). There's no
272   /// particular logic behind the order but either A < B or B < A must be
273   /// true if A != B.
274   bool operator<(const LLTCodeGen &Other) const;
275   bool operator==(const LLTCodeGen &B) const { return Ty == B.Ty; }
276 };
277 
278 // Track all types that are used so we can emit the corresponding enum.
279 extern std::set<LLTCodeGen> KnownTypes;
280 
281 /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
282 /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
283 std::optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT);
284 
285 using TempTypeIdx = int64_t;
286 class LLTCodeGenOrTempType {
287 public:
LLTCodeGenOrTempType(const LLTCodeGen & LLT)288   LLTCodeGenOrTempType(const LLTCodeGen &LLT) : Data(LLT) {}
LLTCodeGenOrTempType(TempTypeIdx TempTy)289   LLTCodeGenOrTempType(TempTypeIdx TempTy) : Data(TempTy) {}
290 
isLLTCodeGen()291   bool isLLTCodeGen() const { return std::holds_alternative<LLTCodeGen>(Data); }
isTempTypeIdx()292   bool isTempTypeIdx() const {
293     return std::holds_alternative<TempTypeIdx>(Data);
294   }
295 
getLLTCodeGen()296   const LLTCodeGen &getLLTCodeGen() const {
297     assert(isLLTCodeGen());
298     return std::get<LLTCodeGen>(Data);
299   }
300 
getTempTypeIdx()301   TempTypeIdx getTempTypeIdx() const {
302     assert(isTempTypeIdx());
303     return std::get<TempTypeIdx>(Data);
304   }
305 
306 private:
307   std::variant<LLTCodeGen, TempTypeIdx> Data;
308 };
309 
310 inline MatchTable &operator<<(MatchTable &Table,
311                               const LLTCodeGenOrTempType &Ty) {
312   if (Ty.isLLTCodeGen())
313     Table << MatchTable::NamedValue(1, Ty.getLLTCodeGen().getCxxEnumValue());
314   else
315     Table << MatchTable::IntValue(1, Ty.getTempTypeIdx());
316   return Table;
317 }
318 
319 //===- Matchers -----------------------------------------------------------===//
320 class Matcher {
321 public:
322   virtual ~Matcher();
323   virtual void optimize();
324   virtual void emit(MatchTable &Table) = 0;
325 
326   virtual bool hasFirstCondition() const = 0;
327   virtual const PredicateMatcher &getFirstCondition() const = 0;
328   virtual std::unique_ptr<PredicateMatcher> popFirstCondition() = 0;
329 };
330 
331 class GroupMatcher final : public Matcher {
332   /// Conditions that form a common prefix of all the matchers contained.
333   SmallVector<std::unique_ptr<PredicateMatcher>, 1> Conditions;
334 
335   /// All the nested matchers, sharing a common prefix.
336   std::vector<Matcher *> Matchers;
337 
338   /// An owning collection for any auxiliary matchers created while optimizing
339   /// nested matchers contained.
340   std::vector<std::unique_ptr<Matcher>> MatcherStorage;
341 
342 public:
343   /// Add a matcher to the collection of nested matchers if it meets the
344   /// requirements, and return true. If it doesn't, do nothing and return false.
345   ///
346   /// Expected to preserve its argument, so it could be moved out later on.
347   bool addMatcher(Matcher &Candidate);
348 
349   /// Mark the matcher as fully-built and ensure any invariants expected by both
350   /// optimize() and emit(...) methods. Generally, both sequences of calls
351   /// are expected to lead to a sensible result:
352   ///
353   /// addMatcher(...)*; finalize(); optimize(); emit(...); and
354   /// addMatcher(...)*; finalize(); emit(...);
355   ///
356   /// or generally
357   ///
358   /// addMatcher(...)*; finalize(); { optimize()*; emit(...); }*
359   ///
360   /// Multiple calls to optimize() are expected to be handled gracefully, though
361   /// optimize() is not expected to be idempotent. Multiple calls to finalize()
362   /// aren't generally supported. emit(...) is expected to be non-mutating and
363   /// producing the exact same results upon repeated calls.
364   ///
365   /// addMatcher() calls after the finalize() call are not supported.
366   ///
367   /// finalize() and optimize() are both allowed to mutate the contained
368   /// matchers, so moving them out after finalize() is not supported.
369   void finalize();
370   void optimize() override;
371   void emit(MatchTable &Table) override;
372 
373   /// Could be used to move out the matchers added previously, unless finalize()
374   /// has been already called. If any of the matchers are moved out, the group
375   /// becomes safe to destroy, but not safe to re-use for anything else.
matchers()376   iterator_range<std::vector<Matcher *>::iterator> matchers() {
377     return make_range(Matchers.begin(), Matchers.end());
378   }
size()379   size_t size() const { return Matchers.size(); }
empty()380   bool empty() const { return Matchers.empty(); }
381 
popFirstCondition()382   std::unique_ptr<PredicateMatcher> popFirstCondition() override {
383     assert(!Conditions.empty() &&
384            "Trying to pop a condition from a condition-less group");
385     std::unique_ptr<PredicateMatcher> P = std::move(Conditions.front());
386     Conditions.erase(Conditions.begin());
387     return P;
388   }
getFirstCondition()389   const PredicateMatcher &getFirstCondition() const override {
390     assert(!Conditions.empty() &&
391            "Trying to get a condition from a condition-less group");
392     return *Conditions.front();
393   }
hasFirstCondition()394   bool hasFirstCondition() const override { return !Conditions.empty(); }
395 
396 private:
397   /// See if a candidate matcher could be added to this group solely by
398   /// analyzing its first condition.
399   bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
400 };
401 
402 class SwitchMatcher : public Matcher {
403   /// All the nested matchers, representing distinct switch-cases. The first
404   /// conditions (as Matcher::getFirstCondition() reports) of all the nested
405   /// matchers must share the same type and path to a value they check, in other
406   /// words, be isIdenticalDownToValue, but have different values they check
407   /// against.
408   std::vector<Matcher *> Matchers;
409 
410   /// The representative condition, with a type and a path (InsnVarID and OpIdx
411   /// in most cases)  shared by all the matchers contained.
412   std::unique_ptr<PredicateMatcher> Condition = nullptr;
413 
414   /// Temporary set used to check that the case values don't repeat within the
415   /// same switch.
416   std::set<MatchTableRecord> Values;
417 
418   /// An owning collection for any auxiliary matchers created while optimizing
419   /// nested matchers contained.
420   std::vector<std::unique_ptr<Matcher>> MatcherStorage;
421 
422 public:
423   bool addMatcher(Matcher &Candidate);
424 
425   void finalize();
426   void emit(MatchTable &Table) override;
427 
matchers()428   iterator_range<std::vector<Matcher *>::iterator> matchers() {
429     return make_range(Matchers.begin(), Matchers.end());
430   }
size()431   size_t size() const { return Matchers.size(); }
empty()432   bool empty() const { return Matchers.empty(); }
433 
popFirstCondition()434   std::unique_ptr<PredicateMatcher> popFirstCondition() override {
435     // SwitchMatcher doesn't have a common first condition for its cases, as all
436     // the cases only share a kind of a value (a type and a path to it) they
437     // match, but deliberately differ in the actual value they match.
438     llvm_unreachable("Trying to pop a condition from a condition-less group");
439   }
440 
getFirstCondition()441   const PredicateMatcher &getFirstCondition() const override {
442     llvm_unreachable("Trying to pop a condition from a condition-less group");
443   }
444 
hasFirstCondition()445   bool hasFirstCondition() const override { return false; }
446 
447 private:
448   /// See if the predicate type has a Switch-implementation for it.
449   static bool isSupportedPredicateType(const PredicateMatcher &Predicate);
450 
451   bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
452 
453   /// emit()-helper
454   static void emitPredicateSpecificOpcodes(const PredicateMatcher &P,
455                                            MatchTable &Table);
456 };
457 
458 /// Generates code to check that a match rule matches.
459 class RuleMatcher : public Matcher {
460 public:
461   using ActionList = std::list<std::unique_ptr<MatchAction>>;
462   using action_iterator = ActionList::iterator;
463 
464 protected:
465   /// A list of matchers that all need to succeed for the current rule to match.
466   /// FIXME: This currently supports a single match position but could be
467   /// extended to support multiple positions to support div/rem fusion or
468   /// load-multiple instructions.
469   using MatchersTy = std::vector<std::unique_ptr<InstructionMatcher>>;
470   MatchersTy Matchers;
471 
472   /// A list of actions that need to be taken when all predicates in this rule
473   /// have succeeded.
474   ActionList Actions;
475 
476   /// Combiners can sometimes just run C++ code to finish matching a rule &
477   /// mutate instructions instead of relying on MatchActions. Empty if unused.
478   std::string CustomCXXAction;
479 
480   using DefinedInsnVariablesMap = std::map<InstructionMatcher *, unsigned>;
481 
482   /// A map of instruction matchers to the local variables
483   DefinedInsnVariablesMap InsnVariableIDs;
484 
485   using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
486 
487   // The set of instruction matchers that have not yet been claimed for mutation
488   // by a BuildMI.
489   MutatableInsnSet MutatableInsns;
490 
491   /// A map of named operands defined by the matchers that may be referenced by
492   /// the renderers.
493   StringMap<OperandMatcher *> DefinedOperands;
494 
495   /// A map of anonymous physical register operands defined by the matchers that
496   /// may be referenced by the renderers.
497   DenseMap<Record *, OperandMatcher *> PhysRegOperands;
498 
499   /// ID for the next instruction variable defined with
500   /// implicitlyDefineInsnVar()
501   unsigned NextInsnVarID;
502 
503   /// ID for the next output instruction allocated with allocateOutputInsnID()
504   unsigned NextOutputInsnID;
505 
506   /// ID for the next temporary register ID allocated with allocateTempRegID()
507   unsigned NextTempRegID;
508 
509   /// ID for the next recorded type. Starts at -1 and counts down.
510   TempTypeIdx NextTempTypeIdx = -1;
511 
512   // HwMode predicate index for this rule. -1 if no HwMode.
513   int HwModeIdx = -1;
514 
515   /// Current GISelFlags
516   GISelFlags Flags = 0;
517 
518   std::vector<std::string> RequiredSimplePredicates;
519   std::vector<Record *> RequiredFeatures;
520   std::vector<std::unique_ptr<PredicateMatcher>> EpilogueMatchers;
521 
522   DenseSet<unsigned> ErasedInsnIDs;
523 
524   ArrayRef<SMLoc> SrcLoc;
525 
526   typedef std::tuple<Record *, unsigned, unsigned>
527       DefinedComplexPatternSubOperand;
528   typedef StringMap<DefinedComplexPatternSubOperand>
529       DefinedComplexPatternSubOperandMap;
530   /// A map of Symbolic Names to ComplexPattern sub-operands.
531   DefinedComplexPatternSubOperandMap ComplexSubOperands;
532   /// A map used to for multiple referenced error check of ComplexSubOperand.
533   /// ComplexSubOperand can't be referenced multiple from different operands,
534   /// however multiple references from same operand are allowed since that is
535   /// how 'same operand checks' are generated.
536   StringMap<std::string> ComplexSubOperandsParentName;
537 
538   uint64_t RuleID;
539   static uint64_t NextRuleID;
540 
541   GISelFlags updateGISelFlag(GISelFlags CurFlags, const Record *R,
542                              StringRef FlagName, GISelFlags FlagBit);
543 
544 public:
RuleMatcher(ArrayRef<SMLoc> SrcLoc)545   RuleMatcher(ArrayRef<SMLoc> SrcLoc)
546       : NextInsnVarID(0), NextOutputInsnID(0), NextTempRegID(0), SrcLoc(SrcLoc),
547         RuleID(NextRuleID++) {}
548   RuleMatcher(RuleMatcher &&Other) = default;
549   RuleMatcher &operator=(RuleMatcher &&Other) = default;
550 
getNextTempTypeIdx()551   TempTypeIdx getNextTempTypeIdx() { return NextTempTypeIdx--; }
552 
getRuleID()553   uint64_t getRuleID() const { return RuleID; }
554 
555   InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
556   void addRequiredFeature(Record *Feature);
557   const std::vector<Record *> &getRequiredFeatures() const;
558 
addHwModeIdx(unsigned Idx)559   void addHwModeIdx(unsigned Idx) { HwModeIdx = Idx; }
getHwModeIdx()560   int getHwModeIdx() const { return HwModeIdx; }
561 
562   void addRequiredSimplePredicate(StringRef PredName);
563   const std::vector<std::string> &getRequiredSimplePredicates();
564 
565   /// Attempts to mark \p ID as erased (GIR_EraseFromParent called on it).
566   /// If \p ID has already been erased, returns false and GIR_EraseFromParent
567   /// should NOT be emitted.
tryEraseInsnID(unsigned ID)568   bool tryEraseInsnID(unsigned ID) { return ErasedInsnIDs.insert(ID).second; }
569 
setCustomCXXAction(StringRef FnEnumName)570   void setCustomCXXAction(StringRef FnEnumName) {
571     CustomCXXAction = FnEnumName.str();
572   }
573 
574   // Emplaces an action of the specified Kind at the end of the action list.
575   //
576   // Returns a reference to the newly created action.
577   //
578   // Like std::vector::emplace_back(), may invalidate all iterators if the new
579   // size exceeds the capacity. Otherwise, only invalidates the past-the-end
580   // iterator.
addAction(Args &&...args)581   template <class Kind, class... Args> Kind &addAction(Args &&...args) {
582     Actions.emplace_back(std::make_unique<Kind>(std::forward<Args>(args)...));
583     return *static_cast<Kind *>(Actions.back().get());
584   }
585 
586   // Emplaces an action of the specified Kind before the given insertion point.
587   //
588   // Returns an iterator pointing at the newly created instruction.
589   //
590   // Like std::vector::insert(), may invalidate all iterators if the new size
591   // exceeds the capacity. Otherwise, only invalidates the iterators from the
592   // insertion point onwards.
593   template <class Kind, class... Args>
insertAction(action_iterator InsertPt,Args &&...args)594   action_iterator insertAction(action_iterator InsertPt, Args &&...args) {
595     return Actions.emplace(InsertPt,
596                            std::make_unique<Kind>(std::forward<Args>(args)...));
597   }
598 
setPermanentGISelFlags(GISelFlags V)599   void setPermanentGISelFlags(GISelFlags V) { Flags = V; }
600 
601   // Update the active GISelFlags based on the GISelFlags Record R.
602   // A SaveAndRestore object is returned so the old GISelFlags are restored
603   // at the end of the scope.
604   SaveAndRestore<GISelFlags> setGISelFlags(const Record *R);
getGISelFlags()605   GISelFlags getGISelFlags() const { return Flags; }
606 
607   /// Define an instruction without emitting any code to do so.
608   unsigned implicitlyDefineInsnVar(InstructionMatcher &Matcher);
609 
610   unsigned getInsnVarID(InstructionMatcher &InsnMatcher) const;
defined_insn_vars_begin()611   DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
612     return InsnVariableIDs.begin();
613   }
defined_insn_vars_end()614   DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
615     return InsnVariableIDs.end();
616   }
617   iterator_range<typename DefinedInsnVariablesMap::const_iterator>
defined_insn_vars()618   defined_insn_vars() const {
619     return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
620   }
621 
mutatable_insns_begin()622   MutatableInsnSet::const_iterator mutatable_insns_begin() const {
623     return MutatableInsns.begin();
624   }
mutatable_insns_end()625   MutatableInsnSet::const_iterator mutatable_insns_end() const {
626     return MutatableInsns.end();
627   }
628   iterator_range<typename MutatableInsnSet::const_iterator>
mutatable_insns()629   mutatable_insns() const {
630     return make_range(mutatable_insns_begin(), mutatable_insns_end());
631   }
reserveInsnMatcherForMutation(InstructionMatcher * InsnMatcher)632   void reserveInsnMatcherForMutation(InstructionMatcher *InsnMatcher) {
633     bool R = MutatableInsns.erase(InsnMatcher);
634     assert(R && "Reserving a mutatable insn that isn't available");
635     (void)R;
636   }
637 
actions_begin()638   action_iterator actions_begin() { return Actions.begin(); }
actions_end()639   action_iterator actions_end() { return Actions.end(); }
actions()640   iterator_range<action_iterator> actions() {
641     return make_range(actions_begin(), actions_end());
642   }
643 
644   void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
645 
646   void definePhysRegOperand(Record *Reg, OperandMatcher &OM);
647 
648   Error defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
649                                 unsigned RendererID, unsigned SubOperandID,
650                                 StringRef ParentSymbolicName);
651 
652   std::optional<DefinedComplexPatternSubOperand>
getComplexSubOperand(StringRef SymbolicName)653   getComplexSubOperand(StringRef SymbolicName) const {
654     const auto &I = ComplexSubOperands.find(SymbolicName);
655     if (I == ComplexSubOperands.end())
656       return std::nullopt;
657     return I->second;
658   }
659 
660   InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
661   OperandMatcher &getOperandMatcher(StringRef Name);
662   const OperandMatcher &getOperandMatcher(StringRef Name) const;
663   const OperandMatcher &getPhysRegOperandMatcher(Record *) const;
664 
665   void optimize() override;
666   void emit(MatchTable &Table) override;
667 
668   /// Compare the priority of this object and B.
669   ///
670   /// Returns true if this object is more important than B.
671   bool isHigherPriorityThan(const RuleMatcher &B) const;
672 
673   /// Report the maximum number of temporary operands needed by the rule
674   /// matcher.
675   unsigned countRendererFns() const;
676 
677   std::unique_ptr<PredicateMatcher> popFirstCondition() override;
678   const PredicateMatcher &getFirstCondition() const override;
679   LLTCodeGen getFirstConditionAsRootType();
680   bool hasFirstCondition() const override;
681   unsigned getNumOperands() const;
682   StringRef getOpcode() const;
683 
684   // FIXME: Remove this as soon as possible
insnmatchers_front()685   InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
686 
allocateOutputInsnID()687   unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
allocateTempRegID()688   unsigned allocateTempRegID() { return NextTempRegID++; }
689 
insnmatchers()690   iterator_range<MatchersTy::iterator> insnmatchers() {
691     return make_range(Matchers.begin(), Matchers.end());
692   }
insnmatchers_empty()693   bool insnmatchers_empty() const { return Matchers.empty(); }
insnmatchers_pop_front()694   void insnmatchers_pop_front() { Matchers.erase(Matchers.begin()); }
695 };
696 
697 template <class PredicateTy> class PredicateListMatcher {
698 private:
699   /// Template instantiations should specialize this to return a string to use
700   /// for the comment emitted when there are no predicates.
701   std::string getNoPredicateComment() const;
702 
703 protected:
704   using PredicatesTy = std::deque<std::unique_ptr<PredicateTy>>;
705   PredicatesTy Predicates;
706 
707   /// Track if the list of predicates was manipulated by one of the optimization
708   /// methods.
709   bool Optimized = false;
710 
711 public:
predicates_begin()712   typename PredicatesTy::iterator predicates_begin() {
713     return Predicates.begin();
714   }
predicates_end()715   typename PredicatesTy::iterator predicates_end() { return Predicates.end(); }
predicates()716   iterator_range<typename PredicatesTy::iterator> predicates() {
717     return make_range(predicates_begin(), predicates_end());
718   }
predicates_size()719   typename PredicatesTy::size_type predicates_size() const {
720     return Predicates.size();
721   }
predicates_empty()722   bool predicates_empty() const { return Predicates.empty(); }
723 
contains()724   template <typename Ty> bool contains() const {
725     return any_of(Predicates, [&](auto &P) { return isa<Ty>(P.get()); });
726   }
727 
predicates_pop_front()728   std::unique_ptr<PredicateTy> predicates_pop_front() {
729     std::unique_ptr<PredicateTy> Front = std::move(Predicates.front());
730     Predicates.pop_front();
731     Optimized = true;
732     return Front;
733   }
734 
prependPredicate(std::unique_ptr<PredicateTy> && Predicate)735   void prependPredicate(std::unique_ptr<PredicateTy> &&Predicate) {
736     Predicates.push_front(std::move(Predicate));
737   }
738 
eraseNullPredicates()739   void eraseNullPredicates() {
740     const auto NewEnd =
741         std::stable_partition(Predicates.begin(), Predicates.end(),
742                               std::logical_not<std::unique_ptr<PredicateTy>>());
743     if (NewEnd != Predicates.begin()) {
744       Predicates.erase(Predicates.begin(), NewEnd);
745       Optimized = true;
746     }
747   }
748 
749   /// Emit MatchTable opcodes that tests whether all the predicates are met.
750   template <class... Args>
emitPredicateListOpcodes(MatchTable & Table,Args &&...args)751   void emitPredicateListOpcodes(MatchTable &Table, Args &&...args) {
752     if (Predicates.empty() && !Optimized) {
753       Table << MatchTable::Comment(getNoPredicateComment())
754             << MatchTable::LineBreak;
755       return;
756     }
757 
758     for (const auto &Predicate : predicates())
759       Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
760   }
761 
762   /// Provide a function to avoid emitting certain predicates. This is used to
763   /// defer some predicate checks until after others
764   using PredicateFilterFunc = std::function<bool(const PredicateTy &)>;
765 
766   /// Emit MatchTable opcodes for predicates which satisfy \p
767   /// ShouldEmitPredicate. This should be called multiple times to ensure all
768   /// predicates are eventually added to the match table.
769   template <class... Args>
emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate,MatchTable & Table,Args &&...args)770   void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate,
771                                         MatchTable &Table, Args &&...args) {
772     if (Predicates.empty() && !Optimized) {
773       Table << MatchTable::Comment(getNoPredicateComment())
774             << MatchTable::LineBreak;
775       return;
776     }
777 
778     for (const auto &Predicate : predicates()) {
779       if (ShouldEmitPredicate(*Predicate))
780         Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
781     }
782   }
783 };
784 
785 class PredicateMatcher {
786 public:
787   /// This enum is used for RTTI and also defines the priority that is given to
788   /// the predicate when generating the matcher code. Kinds with higher priority
789   /// must be tested first.
790   ///
791   /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
792   /// but OPM_Int must have priority over OPM_RegBank since constant integers
793   /// are represented by a virtual register defined by a G_CONSTANT instruction.
794   ///
795   /// Note: The relative priority between IPM_ and OPM_ does not matter, they
796   /// are currently not compared between each other.
797   enum PredicateKind {
798     IPM_Opcode,
799     IPM_NumOperands,
800     IPM_ImmPredicate,
801     IPM_Imm,
802     IPM_AtomicOrderingMMO,
803     IPM_MemoryLLTSize,
804     IPM_MemoryVsLLTSize,
805     IPM_MemoryAddressSpace,
806     IPM_MemoryAlignment,
807     IPM_VectorSplatImm,
808     IPM_NoUse,
809     IPM_OneUse,
810     IPM_GenericPredicate,
811     IPM_MIFlags,
812     OPM_SameOperand,
813     OPM_ComplexPattern,
814     OPM_IntrinsicID,
815     OPM_CmpPredicate,
816     OPM_Instruction,
817     OPM_Int,
818     OPM_LiteralInt,
819     OPM_LLT,
820     OPM_PointerToAny,
821     OPM_RegBank,
822     OPM_MBB,
823     OPM_RecordNamedOperand,
824     OPM_RecordRegType,
825   };
826 
827 protected:
828   PredicateKind Kind;
829   unsigned InsnVarID;
830   unsigned OpIdx;
831 
832 public:
833   PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
Kind(Kind)834       : Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
835   virtual ~PredicateMatcher();
836 
getInsnVarID()837   unsigned getInsnVarID() const { return InsnVarID; }
getOpIdx()838   unsigned getOpIdx() const { return OpIdx; }
839 
840   /// Emit MatchTable opcodes that check the predicate for the given operand.
841   virtual void emitPredicateOpcodes(MatchTable &Table,
842                                     RuleMatcher &Rule) const = 0;
843 
getKind()844   PredicateKind getKind() const { return Kind; }
845 
dependsOnOperands()846   bool dependsOnOperands() const {
847     // Custom predicates really depend on the context pattern of the
848     // instruction, not just the individual instruction. This therefore
849     // implicitly depends on all other pattern constraints.
850     return Kind == IPM_GenericPredicate;
851   }
852 
isIdentical(const PredicateMatcher & B)853   virtual bool isIdentical(const PredicateMatcher &B) const {
854     return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
855            OpIdx == B.OpIdx;
856   }
857 
isIdenticalDownToValue(const PredicateMatcher & B)858   virtual bool isIdenticalDownToValue(const PredicateMatcher &B) const {
859     return hasValue() && PredicateMatcher::isIdentical(B);
860   }
861 
getValue()862   virtual MatchTableRecord getValue() const {
863     assert(hasValue() && "Can not get a value of a value-less predicate!");
864     llvm_unreachable("Not implemented yet");
865   }
hasValue()866   virtual bool hasValue() const { return false; }
867 
868   /// Report the maximum number of temporary operands needed by the predicate
869   /// matcher.
countRendererFns()870   virtual unsigned countRendererFns() const { return 0; }
871 };
872 
873 /// Generates code to check a predicate of an operand.
874 ///
875 /// Typical predicates include:
876 /// * Operand is a particular register.
877 /// * Operand is assigned a particular register bank.
878 /// * Operand is an MBB.
879 class OperandPredicateMatcher : public PredicateMatcher {
880 public:
OperandPredicateMatcher(PredicateKind Kind,unsigned InsnVarID,unsigned OpIdx)881   OperandPredicateMatcher(PredicateKind Kind, unsigned InsnVarID,
882                           unsigned OpIdx)
883       : PredicateMatcher(Kind, InsnVarID, OpIdx) {}
884   virtual ~OperandPredicateMatcher();
885 
886   /// Compare the priority of this object and B.
887   ///
888   /// Returns true if this object is more important than B.
889   virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
890 };
891 
892 template <>
893 inline std::string
getNoPredicateComment()894 PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
895   return "No operand predicates";
896 }
897 
898 /// Generates code to check that a register operand is defined by the same exact
899 /// one as another.
900 class SameOperandMatcher : public OperandPredicateMatcher {
901   std::string MatchingName;
902   unsigned OrigOpIdx;
903 
904   GISelFlags Flags;
905 
906 public:
SameOperandMatcher(unsigned InsnVarID,unsigned OpIdx,StringRef MatchingName,unsigned OrigOpIdx,GISelFlags Flags)907   SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName,
908                      unsigned OrigOpIdx, GISelFlags Flags)
909       : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx),
910         MatchingName(MatchingName), OrigOpIdx(OrigOpIdx), Flags(Flags) {}
911 
classof(const PredicateMatcher * P)912   static bool classof(const PredicateMatcher *P) {
913     return P->getKind() == OPM_SameOperand;
914   }
915 
916   void emitPredicateOpcodes(MatchTable &Table,
917                             RuleMatcher &Rule) const override;
918 
isIdentical(const PredicateMatcher & B)919   bool isIdentical(const PredicateMatcher &B) const override {
920     return OperandPredicateMatcher::isIdentical(B) &&
921            OrigOpIdx == cast<SameOperandMatcher>(&B)->OrigOpIdx &&
922            MatchingName == cast<SameOperandMatcher>(&B)->MatchingName;
923   }
924 };
925 
926 /// Generates code to check that an operand is a particular LLT.
927 class LLTOperandMatcher : public OperandPredicateMatcher {
928 protected:
929   LLTCodeGen Ty;
930 
931 public:
932   static std::map<LLTCodeGen, unsigned> TypeIDValues;
933 
initTypeIDValuesMap()934   static void initTypeIDValuesMap() {
935     TypeIDValues.clear();
936 
937     unsigned ID = 0;
938     for (const LLTCodeGen &LLTy : KnownTypes)
939       TypeIDValues[LLTy] = ID++;
940   }
941 
LLTOperandMatcher(unsigned InsnVarID,unsigned OpIdx,const LLTCodeGen & Ty)942   LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty)
943       : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
944     KnownTypes.insert(Ty);
945   }
946 
classof(const PredicateMatcher * P)947   static bool classof(const PredicateMatcher *P) {
948     return P->getKind() == OPM_LLT;
949   }
950 
isIdentical(const PredicateMatcher & B)951   bool isIdentical(const PredicateMatcher &B) const override {
952     return OperandPredicateMatcher::isIdentical(B) &&
953            Ty == cast<LLTOperandMatcher>(&B)->Ty;
954   }
955 
956   MatchTableRecord getValue() const override;
957   bool hasValue() const override;
958 
getTy()959   LLTCodeGen getTy() const { return Ty; }
960 
961   void emitPredicateOpcodes(MatchTable &Table,
962                             RuleMatcher &Rule) const override;
963 };
964 
965 /// Generates code to check that an operand is a pointer to any address space.
966 ///
967 /// In SelectionDAG, the types did not describe pointers or address spaces. As a
968 /// result, iN is used to describe a pointer of N bits to any address space and
969 /// PatFrag predicates are typically used to constrain the address space.
970 /// There's no reliable means to derive the missing type information from the
971 /// pattern so imported rules must test the components of a pointer separately.
972 ///
973 /// If SizeInBits is zero, then the pointer size will be obtained from the
974 /// subtarget.
975 class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
976 protected:
977   unsigned SizeInBits;
978 
979 public:
PointerToAnyOperandMatcher(unsigned InsnVarID,unsigned OpIdx,unsigned SizeInBits)980   PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
981                              unsigned SizeInBits)
982       : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
983         SizeInBits(SizeInBits) {}
984 
classof(const PredicateMatcher * P)985   static bool classof(const PredicateMatcher *P) {
986     return P->getKind() == OPM_PointerToAny;
987   }
988 
isIdentical(const PredicateMatcher & B)989   bool isIdentical(const PredicateMatcher &B) const override {
990     return OperandPredicateMatcher::isIdentical(B) &&
991            SizeInBits == cast<PointerToAnyOperandMatcher>(&B)->SizeInBits;
992   }
993 
994   void emitPredicateOpcodes(MatchTable &Table,
995                             RuleMatcher &Rule) const override;
996 };
997 
998 /// Generates code to record named operand in RecordedOperands list at StoreIdx.
999 /// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
1000 /// an argument to predicate's c++ code once all operands have been matched.
1001 class RecordNamedOperandMatcher : public OperandPredicateMatcher {
1002 protected:
1003   unsigned StoreIdx;
1004   std::string Name;
1005 
1006 public:
RecordNamedOperandMatcher(unsigned InsnVarID,unsigned OpIdx,unsigned StoreIdx,StringRef Name)1007   RecordNamedOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1008                             unsigned StoreIdx, StringRef Name)
1009       : OperandPredicateMatcher(OPM_RecordNamedOperand, InsnVarID, OpIdx),
1010         StoreIdx(StoreIdx), Name(Name) {}
1011 
classof(const PredicateMatcher * P)1012   static bool classof(const PredicateMatcher *P) {
1013     return P->getKind() == OPM_RecordNamedOperand;
1014   }
1015 
isIdentical(const PredicateMatcher & B)1016   bool isIdentical(const PredicateMatcher &B) const override {
1017     return OperandPredicateMatcher::isIdentical(B) &&
1018            StoreIdx == cast<RecordNamedOperandMatcher>(&B)->StoreIdx &&
1019            Name == cast<RecordNamedOperandMatcher>(&B)->Name;
1020   }
1021 
1022   void emitPredicateOpcodes(MatchTable &Table,
1023                             RuleMatcher &Rule) const override;
1024 };
1025 
1026 /// Generates code to store a register operand's type into the set of temporary
1027 /// LLTs.
1028 class RecordRegisterType : public OperandPredicateMatcher {
1029 protected:
1030   TempTypeIdx Idx;
1031 
1032 public:
RecordRegisterType(unsigned InsnVarID,unsigned OpIdx,TempTypeIdx Idx)1033   RecordRegisterType(unsigned InsnVarID, unsigned OpIdx, TempTypeIdx Idx)
1034       : OperandPredicateMatcher(OPM_RecordRegType, InsnVarID, OpIdx), Idx(Idx) {
1035   }
1036 
classof(const PredicateMatcher * P)1037   static bool classof(const PredicateMatcher *P) {
1038     return P->getKind() == OPM_RecordRegType;
1039   }
1040 
isIdentical(const PredicateMatcher & B)1041   bool isIdentical(const PredicateMatcher &B) const override {
1042     return OperandPredicateMatcher::isIdentical(B) &&
1043            Idx == cast<RecordRegisterType>(&B)->Idx;
1044   }
1045 
1046   void emitPredicateOpcodes(MatchTable &Table,
1047                             RuleMatcher &Rule) const override;
1048 };
1049 
1050 /// Generates code to check that an operand is a particular target constant.
1051 class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
1052 protected:
1053   const OperandMatcher &Operand;
1054   const Record &TheDef;
1055 
1056   unsigned getAllocatedTemporariesBaseID() const;
1057 
1058 public:
isIdentical(const PredicateMatcher & B)1059   bool isIdentical(const PredicateMatcher &B) const override { return false; }
1060 
ComplexPatternOperandMatcher(unsigned InsnVarID,unsigned OpIdx,const OperandMatcher & Operand,const Record & TheDef)1061   ComplexPatternOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1062                                const OperandMatcher &Operand,
1063                                const Record &TheDef)
1064       : OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx),
1065         Operand(Operand), TheDef(TheDef) {}
1066 
classof(const PredicateMatcher * P)1067   static bool classof(const PredicateMatcher *P) {
1068     return P->getKind() == OPM_ComplexPattern;
1069   }
1070 
1071   void emitPredicateOpcodes(MatchTable &Table,
1072                             RuleMatcher &Rule) const override;
countRendererFns()1073   unsigned countRendererFns() const override { return 1; }
1074 };
1075 
1076 /// Generates code to check that an operand is in a particular register bank.
1077 class RegisterBankOperandMatcher : public OperandPredicateMatcher {
1078 protected:
1079   const CodeGenRegisterClass &RC;
1080 
1081 public:
RegisterBankOperandMatcher(unsigned InsnVarID,unsigned OpIdx,const CodeGenRegisterClass & RC)1082   RegisterBankOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1083                              const CodeGenRegisterClass &RC)
1084       : OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {}
1085 
1086   bool isIdentical(const PredicateMatcher &B) const override;
1087 
classof(const PredicateMatcher * P)1088   static bool classof(const PredicateMatcher *P) {
1089     return P->getKind() == OPM_RegBank;
1090   }
1091 
1092   void emitPredicateOpcodes(MatchTable &Table,
1093                             RuleMatcher &Rule) const override;
1094 };
1095 
1096 /// Generates code to check that an operand is a basic block.
1097 class MBBOperandMatcher : public OperandPredicateMatcher {
1098 public:
MBBOperandMatcher(unsigned InsnVarID,unsigned OpIdx)1099   MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1100       : OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
1101 
classof(const PredicateMatcher * P)1102   static bool classof(const PredicateMatcher *P) {
1103     return P->getKind() == OPM_MBB;
1104   }
1105 
1106   void emitPredicateOpcodes(MatchTable &Table,
1107                             RuleMatcher &Rule) const override;
1108 };
1109 
1110 class ImmOperandMatcher : public OperandPredicateMatcher {
1111 public:
ImmOperandMatcher(unsigned InsnVarID,unsigned OpIdx)1112   ImmOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1113       : OperandPredicateMatcher(IPM_Imm, InsnVarID, OpIdx) {}
1114 
classof(const PredicateMatcher * P)1115   static bool classof(const PredicateMatcher *P) {
1116     return P->getKind() == IPM_Imm;
1117   }
1118 
1119   void emitPredicateOpcodes(MatchTable &Table,
1120                             RuleMatcher &Rule) const override;
1121 };
1122 
1123 /// Generates code to check that an operand is a G_CONSTANT with a particular
1124 /// int.
1125 class ConstantIntOperandMatcher : public OperandPredicateMatcher {
1126 protected:
1127   int64_t Value;
1128 
1129 public:
ConstantIntOperandMatcher(unsigned InsnVarID,unsigned OpIdx,int64_t Value)1130   ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1131       : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {}
1132 
isIdentical(const PredicateMatcher & B)1133   bool isIdentical(const PredicateMatcher &B) const override {
1134     return OperandPredicateMatcher::isIdentical(B) &&
1135            Value == cast<ConstantIntOperandMatcher>(&B)->Value;
1136   }
1137 
classof(const PredicateMatcher * P)1138   static bool classof(const PredicateMatcher *P) {
1139     return P->getKind() == OPM_Int;
1140   }
1141 
1142   void emitPredicateOpcodes(MatchTable &Table,
1143                             RuleMatcher &Rule) const override;
1144 };
1145 
1146 /// Generates code to check that an operand is a raw int (where MO.isImm() or
1147 /// MO.isCImm() is true).
1148 class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1149 protected:
1150   int64_t Value;
1151 
1152 public:
LiteralIntOperandMatcher(unsigned InsnVarID,unsigned OpIdx,int64_t Value)1153   LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1154       : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
1155         Value(Value) {}
1156 
isIdentical(const PredicateMatcher & B)1157   bool isIdentical(const PredicateMatcher &B) const override {
1158     return OperandPredicateMatcher::isIdentical(B) &&
1159            Value == cast<LiteralIntOperandMatcher>(&B)->Value;
1160   }
1161 
classof(const PredicateMatcher * P)1162   static bool classof(const PredicateMatcher *P) {
1163     return P->getKind() == OPM_LiteralInt;
1164   }
1165 
1166   void emitPredicateOpcodes(MatchTable &Table,
1167                             RuleMatcher &Rule) const override;
1168 };
1169 
1170 /// Generates code to check that an operand is an CmpInst predicate
1171 class CmpPredicateOperandMatcher : public OperandPredicateMatcher {
1172 protected:
1173   std::string PredName;
1174 
1175 public:
CmpPredicateOperandMatcher(unsigned InsnVarID,unsigned OpIdx,std::string P)1176   CmpPredicateOperandMatcher(unsigned InsnVarID, unsigned OpIdx, std::string P)
1177       : OperandPredicateMatcher(OPM_CmpPredicate, InsnVarID, OpIdx),
1178         PredName(std::move(P)) {}
1179 
isIdentical(const PredicateMatcher & B)1180   bool isIdentical(const PredicateMatcher &B) const override {
1181     return OperandPredicateMatcher::isIdentical(B) &&
1182            PredName == cast<CmpPredicateOperandMatcher>(&B)->PredName;
1183   }
1184 
classof(const PredicateMatcher * P)1185   static bool classof(const PredicateMatcher *P) {
1186     return P->getKind() == OPM_CmpPredicate;
1187   }
1188 
1189   void emitPredicateOpcodes(MatchTable &Table,
1190                             RuleMatcher &Rule) const override;
1191 };
1192 
1193 /// Generates code to check that an operand is an intrinsic ID.
1194 class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1195 protected:
1196   const CodeGenIntrinsic *II;
1197 
1198 public:
IntrinsicIDOperandMatcher(unsigned InsnVarID,unsigned OpIdx,const CodeGenIntrinsic * II)1199   IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1200                             const CodeGenIntrinsic *II)
1201       : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
1202 
isIdentical(const PredicateMatcher & B)1203   bool isIdentical(const PredicateMatcher &B) const override {
1204     return OperandPredicateMatcher::isIdentical(B) &&
1205            II == cast<IntrinsicIDOperandMatcher>(&B)->II;
1206   }
1207 
classof(const PredicateMatcher * P)1208   static bool classof(const PredicateMatcher *P) {
1209     return P->getKind() == OPM_IntrinsicID;
1210   }
1211 
1212   void emitPredicateOpcodes(MatchTable &Table,
1213                             RuleMatcher &Rule) const override;
1214 };
1215 
1216 /// Generates code to check that this operand is an immediate whose value meets
1217 /// an immediate predicate.
1218 class OperandImmPredicateMatcher : public OperandPredicateMatcher {
1219 protected:
1220   TreePredicateFn Predicate;
1221 
1222 public:
OperandImmPredicateMatcher(unsigned InsnVarID,unsigned OpIdx,const TreePredicateFn & Predicate)1223   OperandImmPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
1224                              const TreePredicateFn &Predicate)
1225       : OperandPredicateMatcher(IPM_ImmPredicate, InsnVarID, OpIdx),
1226         Predicate(Predicate) {}
1227 
isIdentical(const PredicateMatcher & B)1228   bool isIdentical(const PredicateMatcher &B) const override {
1229     return OperandPredicateMatcher::isIdentical(B) &&
1230            Predicate.getOrigPatFragRecord() ==
1231                cast<OperandImmPredicateMatcher>(&B)
1232                    ->Predicate.getOrigPatFragRecord();
1233   }
1234 
classof(const PredicateMatcher * P)1235   static bool classof(const PredicateMatcher *P) {
1236     return P->getKind() == IPM_ImmPredicate;
1237   }
1238 
1239   void emitPredicateOpcodes(MatchTable &Table,
1240                             RuleMatcher &Rule) const override;
1241 };
1242 
1243 /// Generates code to check that a set of predicates match for a particular
1244 /// operand.
1245 class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1246 protected:
1247   InstructionMatcher &Insn;
1248   unsigned OpIdx;
1249   std::string SymbolicName;
1250 
1251   /// The index of the first temporary variable allocated to this operand. The
1252   /// number of allocated temporaries can be found with
1253   /// countRendererFns().
1254   unsigned AllocatedTemporariesBaseID;
1255 
1256   TempTypeIdx TTIdx = 0;
1257 
1258 public:
OperandMatcher(InstructionMatcher & Insn,unsigned OpIdx,const std::string & SymbolicName,unsigned AllocatedTemporariesBaseID)1259   OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
1260                  const std::string &SymbolicName,
1261                  unsigned AllocatedTemporariesBaseID)
1262       : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1263         AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
1264 
hasSymbolicName()1265   bool hasSymbolicName() const { return !SymbolicName.empty(); }
getSymbolicName()1266   StringRef getSymbolicName() const { return SymbolicName; }
setSymbolicName(StringRef Name)1267   void setSymbolicName(StringRef Name) {
1268     assert(SymbolicName.empty() && "Operand already has a symbolic name");
1269     SymbolicName = std::string(Name);
1270   }
1271 
1272   /// Construct a new operand predicate and add it to the matcher.
1273   template <class Kind, class... Args>
addPredicate(Args &&...args)1274   std::optional<Kind *> addPredicate(Args &&...args) {
1275     if (isSameAsAnotherOperand())
1276       return std::nullopt;
1277     Predicates.emplace_back(std::make_unique<Kind>(
1278         getInsnVarID(), getOpIdx(), std::forward<Args>(args)...));
1279     return static_cast<Kind *>(Predicates.back().get());
1280   }
1281 
getOpIdx()1282   unsigned getOpIdx() const { return OpIdx; }
1283   unsigned getInsnVarID() const;
1284 
1285   /// If this OperandMatcher has not been assigned a TempTypeIdx yet, assigns it
1286   /// one and adds a `RecordRegisterType` predicate to this matcher. If one has
1287   /// already been assigned, simply returns it.
1288   TempTypeIdx getTempTypeIdx(RuleMatcher &Rule);
1289 
1290   std::string getOperandExpr(unsigned InsnVarID) const;
1291 
getInstructionMatcher()1292   InstructionMatcher &getInstructionMatcher() const { return Insn; }
1293 
1294   Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1295                               bool OperandIsAPointer);
1296 
1297   /// Emit MatchTable opcodes that test whether the instruction named in
1298   /// InsnVarID matches all the predicates and all the operands.
1299   void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule);
1300 
1301   /// Compare the priority of this object and B.
1302   ///
1303   /// Returns true if this object is more important than B.
1304   bool isHigherPriorityThan(OperandMatcher &B);
1305 
1306   /// Report the maximum number of temporary operands needed by the operand
1307   /// matcher.
1308   unsigned countRendererFns();
1309 
getAllocatedTemporariesBaseID()1310   unsigned getAllocatedTemporariesBaseID() const {
1311     return AllocatedTemporariesBaseID;
1312   }
1313 
isSameAsAnotherOperand()1314   bool isSameAsAnotherOperand() {
1315     for (const auto &Predicate : predicates())
1316       if (isa<SameOperandMatcher>(Predicate))
1317         return true;
1318     return false;
1319   }
1320 };
1321 
1322 /// Generates code to check a predicate on an instruction.
1323 ///
1324 /// Typical predicates include:
1325 /// * The opcode of the instruction is a particular value.
1326 /// * The nsw/nuw flag is/isn't set.
1327 class InstructionPredicateMatcher : public PredicateMatcher {
1328 public:
InstructionPredicateMatcher(PredicateKind Kind,unsigned InsnVarID)1329   InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
1330       : PredicateMatcher(Kind, InsnVarID) {}
~InstructionPredicateMatcher()1331   virtual ~InstructionPredicateMatcher() {}
1332 
1333   /// Compare the priority of this object and B.
1334   ///
1335   /// Returns true if this object is more important than B.
1336   virtual bool
isHigherPriorityThan(const InstructionPredicateMatcher & B)1337   isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
1338     return Kind < B.Kind;
1339   };
1340 };
1341 
1342 template <>
1343 inline std::string
getNoPredicateComment()1344 PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
1345   return "No instruction predicates";
1346 }
1347 
1348 /// Generates code to check the opcode of an instruction.
1349 class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1350 protected:
1351   // Allow matching one to several, similar opcodes that share properties. This
1352   // is to handle patterns where one SelectionDAG operation maps to multiple
1353   // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
1354   // is treated as the canonical opcode.
1355   SmallVector<const CodeGenInstruction *, 2> Insts;
1356 
1357   static DenseMap<const CodeGenInstruction *, unsigned> OpcodeValues;
1358 
1359   MatchTableRecord getInstValue(const CodeGenInstruction *I) const;
1360 
1361 public:
1362   static void initOpcodeValuesMap(const CodeGenTarget &Target);
1363 
InstructionOpcodeMatcher(unsigned InsnVarID,ArrayRef<const CodeGenInstruction * > I)1364   InstructionOpcodeMatcher(unsigned InsnVarID,
1365                            ArrayRef<const CodeGenInstruction *> I)
1366       : InstructionPredicateMatcher(IPM_Opcode, InsnVarID),
1367         Insts(I.begin(), I.end()) {
1368     assert((Insts.size() == 1 || Insts.size() == 2) &&
1369            "unexpected number of opcode alternatives");
1370   }
1371 
classof(const PredicateMatcher * P)1372   static bool classof(const PredicateMatcher *P) {
1373     return P->getKind() == IPM_Opcode;
1374   }
1375 
isIdentical(const PredicateMatcher & B)1376   bool isIdentical(const PredicateMatcher &B) const override {
1377     return InstructionPredicateMatcher::isIdentical(B) &&
1378            Insts == cast<InstructionOpcodeMatcher>(&B)->Insts;
1379   }
1380 
hasValue()1381   bool hasValue() const override {
1382     return Insts.size() == 1 && OpcodeValues.count(Insts[0]);
1383   }
1384 
1385   // TODO: This is used for the SwitchMatcher optimization. We should be able to
1386   // return a list of the opcodes to match.
1387   MatchTableRecord getValue() const override;
1388 
1389   void emitPredicateOpcodes(MatchTable &Table,
1390                             RuleMatcher &Rule) const override;
1391 
1392   /// Compare the priority of this object and B.
1393   ///
1394   /// Returns true if this object is more important than B.
1395   bool
1396   isHigherPriorityThan(const InstructionPredicateMatcher &B) const override;
1397 
1398   bool isConstantInstruction() const;
1399 
1400   // The first opcode is the canonical opcode, and later are alternatives.
1401   StringRef getOpcode() const;
getAlternativeOpcodes()1402   ArrayRef<const CodeGenInstruction *> getAlternativeOpcodes() { return Insts; }
1403   bool isVariadicNumOperands() const;
1404   StringRef getOperandType(unsigned OpIdx) const;
1405 };
1406 
1407 class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher {
1408   unsigned NumOperands = 0;
1409 
1410 public:
InstructionNumOperandsMatcher(unsigned InsnVarID,unsigned NumOperands)1411   InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands)
1412       : InstructionPredicateMatcher(IPM_NumOperands, InsnVarID),
1413         NumOperands(NumOperands) {}
1414 
classof(const PredicateMatcher * P)1415   static bool classof(const PredicateMatcher *P) {
1416     return P->getKind() == IPM_NumOperands;
1417   }
1418 
isIdentical(const PredicateMatcher & B)1419   bool isIdentical(const PredicateMatcher &B) const override {
1420     return InstructionPredicateMatcher::isIdentical(B) &&
1421            NumOperands == cast<InstructionNumOperandsMatcher>(&B)->NumOperands;
1422   }
1423 
1424   void emitPredicateOpcodes(MatchTable &Table,
1425                             RuleMatcher &Rule) const override;
1426 };
1427 
1428 /// Generates code to check that this instruction is a constant whose value
1429 /// meets an immediate predicate.
1430 ///
1431 /// Immediates are slightly odd since they are typically used like an operand
1432 /// but are represented as an operator internally. We typically write simm8:$src
1433 /// in a tablegen pattern, but this is just syntactic sugar for
1434 /// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1435 /// that will be matched and the predicate (which is attached to the imm
1436 /// operator) that will be tested. In SelectionDAG this describes a
1437 /// ConstantSDNode whose internal value will be tested using the simm8
1438 /// predicate.
1439 ///
1440 /// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1441 /// this representation, the immediate could be tested with an
1442 /// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1443 /// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1444 /// there are two implementation issues with producing that matcher
1445 /// configuration from the SelectionDAG pattern:
1446 /// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1447 ///   were we to sink the immediate predicate to the operand we would have to
1448 ///   have two partial implementations of PatFrag support, one for immediates
1449 ///   and one for non-immediates.
1450 /// * At the point we handle the predicate, the OperandMatcher hasn't been
1451 ///   created yet. If we were to sink the predicate to the OperandMatcher we
1452 ///   would also have to complicate (or duplicate) the code that descends and
1453 ///   creates matchers for the subtree.
1454 /// Overall, it's simpler to handle it in the place it was found.
1455 class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1456 protected:
1457   TreePredicateFn Predicate;
1458 
1459 public:
InstructionImmPredicateMatcher(unsigned InsnVarID,const TreePredicateFn & Predicate)1460   InstructionImmPredicateMatcher(unsigned InsnVarID,
1461                                  const TreePredicateFn &Predicate)
1462       : InstructionPredicateMatcher(IPM_ImmPredicate, InsnVarID),
1463         Predicate(Predicate) {}
1464 
1465   bool isIdentical(const PredicateMatcher &B) const override;
1466 
classof(const PredicateMatcher * P)1467   static bool classof(const PredicateMatcher *P) {
1468     return P->getKind() == IPM_ImmPredicate;
1469   }
1470 
1471   void emitPredicateOpcodes(MatchTable &Table,
1472                             RuleMatcher &Rule) const override;
1473 };
1474 
1475 /// Generates code to check that a memory instruction has a atomic ordering
1476 /// MachineMemoryOperand.
1477 class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
1478 public:
1479   enum AOComparator {
1480     AO_Exactly,
1481     AO_OrStronger,
1482     AO_WeakerThan,
1483   };
1484 
1485 protected:
1486   StringRef Order;
1487   AOComparator Comparator;
1488 
1489 public:
1490   AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
1491                                     AOComparator Comparator = AO_Exactly)
InstructionPredicateMatcher(IPM_AtomicOrderingMMO,InsnVarID)1492       : InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
1493         Order(Order), Comparator(Comparator) {}
1494 
classof(const PredicateMatcher * P)1495   static bool classof(const PredicateMatcher *P) {
1496     return P->getKind() == IPM_AtomicOrderingMMO;
1497   }
1498 
1499   bool isIdentical(const PredicateMatcher &B) const override;
1500 
1501   void emitPredicateOpcodes(MatchTable &Table,
1502                             RuleMatcher &Rule) const override;
1503 };
1504 
1505 /// Generates code to check that the size of an MMO is exactly N bytes.
1506 class MemorySizePredicateMatcher : public InstructionPredicateMatcher {
1507 protected:
1508   unsigned MMOIdx;
1509   uint64_t Size;
1510 
1511 public:
MemorySizePredicateMatcher(unsigned InsnVarID,unsigned MMOIdx,unsigned Size)1512   MemorySizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx, unsigned Size)
1513       : InstructionPredicateMatcher(IPM_MemoryLLTSize, InsnVarID),
1514         MMOIdx(MMOIdx), Size(Size) {}
1515 
classof(const PredicateMatcher * P)1516   static bool classof(const PredicateMatcher *P) {
1517     return P->getKind() == IPM_MemoryLLTSize;
1518   }
isIdentical(const PredicateMatcher & B)1519   bool isIdentical(const PredicateMatcher &B) const override {
1520     return InstructionPredicateMatcher::isIdentical(B) &&
1521            MMOIdx == cast<MemorySizePredicateMatcher>(&B)->MMOIdx &&
1522            Size == cast<MemorySizePredicateMatcher>(&B)->Size;
1523   }
1524 
1525   void emitPredicateOpcodes(MatchTable &Table,
1526                             RuleMatcher &Rule) const override;
1527 };
1528 
1529 class MemoryAddressSpacePredicateMatcher : public InstructionPredicateMatcher {
1530 protected:
1531   unsigned MMOIdx;
1532   SmallVector<unsigned, 4> AddrSpaces;
1533 
1534 public:
MemoryAddressSpacePredicateMatcher(unsigned InsnVarID,unsigned MMOIdx,ArrayRef<unsigned> AddrSpaces)1535   MemoryAddressSpacePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1536                                      ArrayRef<unsigned> AddrSpaces)
1537       : InstructionPredicateMatcher(IPM_MemoryAddressSpace, InsnVarID),
1538         MMOIdx(MMOIdx), AddrSpaces(AddrSpaces.begin(), AddrSpaces.end()) {}
1539 
classof(const PredicateMatcher * P)1540   static bool classof(const PredicateMatcher *P) {
1541     return P->getKind() == IPM_MemoryAddressSpace;
1542   }
1543 
1544   bool isIdentical(const PredicateMatcher &B) const override;
1545 
1546   void emitPredicateOpcodes(MatchTable &Table,
1547                             RuleMatcher &Rule) const override;
1548 };
1549 
1550 class MemoryAlignmentPredicateMatcher : public InstructionPredicateMatcher {
1551 protected:
1552   unsigned MMOIdx;
1553   int MinAlign;
1554 
1555 public:
MemoryAlignmentPredicateMatcher(unsigned InsnVarID,unsigned MMOIdx,int MinAlign)1556   MemoryAlignmentPredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1557                                   int MinAlign)
1558       : InstructionPredicateMatcher(IPM_MemoryAlignment, InsnVarID),
1559         MMOIdx(MMOIdx), MinAlign(MinAlign) {
1560     assert(MinAlign > 0);
1561   }
1562 
classof(const PredicateMatcher * P)1563   static bool classof(const PredicateMatcher *P) {
1564     return P->getKind() == IPM_MemoryAlignment;
1565   }
1566 
1567   bool isIdentical(const PredicateMatcher &B) const override;
1568 
1569   void emitPredicateOpcodes(MatchTable &Table,
1570                             RuleMatcher &Rule) const override;
1571 };
1572 
1573 /// Generates code to check that the size of an MMO is less-than, equal-to, or
1574 /// greater than a given LLT.
1575 class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher {
1576 public:
1577   enum RelationKind {
1578     GreaterThan,
1579     EqualTo,
1580     LessThan,
1581   };
1582 
1583 protected:
1584   unsigned MMOIdx;
1585   RelationKind Relation;
1586   unsigned OpIdx;
1587 
1588 public:
MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID,unsigned MMOIdx,enum RelationKind Relation,unsigned OpIdx)1589   MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1590                                   enum RelationKind Relation, unsigned OpIdx)
1591       : InstructionPredicateMatcher(IPM_MemoryVsLLTSize, InsnVarID),
1592         MMOIdx(MMOIdx), Relation(Relation), OpIdx(OpIdx) {}
1593 
classof(const PredicateMatcher * P)1594   static bool classof(const PredicateMatcher *P) {
1595     return P->getKind() == IPM_MemoryVsLLTSize;
1596   }
1597   bool isIdentical(const PredicateMatcher &B) const override;
1598 
1599   void emitPredicateOpcodes(MatchTable &Table,
1600                             RuleMatcher &Rule) const override;
1601 };
1602 
1603 // Matcher for immAllOnesV/immAllZerosV
1604 class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher {
1605 public:
1606   enum SplatKind { AllZeros, AllOnes };
1607 
1608 private:
1609   SplatKind Kind;
1610 
1611 public:
VectorSplatImmPredicateMatcher(unsigned InsnVarID,SplatKind K)1612   VectorSplatImmPredicateMatcher(unsigned InsnVarID, SplatKind K)
1613       : InstructionPredicateMatcher(IPM_VectorSplatImm, InsnVarID), Kind(K) {}
1614 
classof(const PredicateMatcher * P)1615   static bool classof(const PredicateMatcher *P) {
1616     return P->getKind() == IPM_VectorSplatImm;
1617   }
1618 
isIdentical(const PredicateMatcher & B)1619   bool isIdentical(const PredicateMatcher &B) const override {
1620     return InstructionPredicateMatcher::isIdentical(B) &&
1621            Kind == static_cast<const VectorSplatImmPredicateMatcher &>(B).Kind;
1622   }
1623 
1624   void emitPredicateOpcodes(MatchTable &Table,
1625                             RuleMatcher &Rule) const override;
1626 };
1627 
1628 /// Generates code to check an arbitrary C++ instruction predicate.
1629 class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
1630 protected:
1631   std::string EnumVal;
1632 
1633 public:
1634   GenericInstructionPredicateMatcher(unsigned InsnVarID,
1635                                      TreePredicateFn Predicate);
1636 
GenericInstructionPredicateMatcher(unsigned InsnVarID,const std::string & EnumVal)1637   GenericInstructionPredicateMatcher(unsigned InsnVarID,
1638                                      const std::string &EnumVal)
1639       : InstructionPredicateMatcher(IPM_GenericPredicate, InsnVarID),
1640         EnumVal(EnumVal) {}
1641 
classof(const InstructionPredicateMatcher * P)1642   static bool classof(const InstructionPredicateMatcher *P) {
1643     return P->getKind() == IPM_GenericPredicate;
1644   }
1645   bool isIdentical(const PredicateMatcher &B) const override;
1646   void emitPredicateOpcodes(MatchTable &Table,
1647                             RuleMatcher &Rule) const override;
1648 };
1649 
1650 class MIFlagsInstructionPredicateMatcher : public InstructionPredicateMatcher {
1651   SmallVector<StringRef, 2> Flags;
1652   bool CheckNot; // false = GIM_MIFlags, true = GIM_MIFlagsNot
1653 
1654 public:
1655   MIFlagsInstructionPredicateMatcher(unsigned InsnVarID,
1656                                      ArrayRef<StringRef> FlagsToCheck,
1657                                      bool CheckNot = false)
InstructionPredicateMatcher(IPM_MIFlags,InsnVarID)1658       : InstructionPredicateMatcher(IPM_MIFlags, InsnVarID),
1659         Flags(FlagsToCheck), CheckNot(CheckNot) {
1660     sort(Flags);
1661   }
1662 
classof(const InstructionPredicateMatcher * P)1663   static bool classof(const InstructionPredicateMatcher *P) {
1664     return P->getKind() == IPM_MIFlags;
1665   }
1666 
1667   bool isIdentical(const PredicateMatcher &B) const override;
1668   void emitPredicateOpcodes(MatchTable &Table,
1669                             RuleMatcher &Rule) const override;
1670 };
1671 
1672 /// Generates code to check for the absence of use of the result.
1673 // TODO? Generalize this to support checking for one use.
1674 class NoUsePredicateMatcher : public InstructionPredicateMatcher {
1675 public:
NoUsePredicateMatcher(unsigned InsnVarID)1676   NoUsePredicateMatcher(unsigned InsnVarID)
1677       : InstructionPredicateMatcher(IPM_NoUse, InsnVarID) {}
1678 
classof(const PredicateMatcher * P)1679   static bool classof(const PredicateMatcher *P) {
1680     return P->getKind() == IPM_NoUse;
1681   }
1682 
isIdentical(const PredicateMatcher & B)1683   bool isIdentical(const PredicateMatcher &B) const override {
1684     return InstructionPredicateMatcher::isIdentical(B);
1685   }
1686 
emitPredicateOpcodes(MatchTable & Table,RuleMatcher & Rule)1687   void emitPredicateOpcodes(MatchTable &Table,
1688                             RuleMatcher &Rule) const override {
1689     Table << MatchTable::Opcode("GIM_CheckHasNoUse")
1690           << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
1691           << MatchTable::LineBreak;
1692   }
1693 };
1694 
1695 /// Generates code to check that the first result has only one use.
1696 class OneUsePredicateMatcher : public InstructionPredicateMatcher {
1697 public:
OneUsePredicateMatcher(unsigned InsnVarID)1698   OneUsePredicateMatcher(unsigned InsnVarID)
1699       : InstructionPredicateMatcher(IPM_OneUse, InsnVarID) {}
1700 
classof(const PredicateMatcher * P)1701   static bool classof(const PredicateMatcher *P) {
1702     return P->getKind() == IPM_OneUse;
1703   }
1704 
isIdentical(const PredicateMatcher & B)1705   bool isIdentical(const PredicateMatcher &B) const override {
1706     return InstructionPredicateMatcher::isIdentical(B);
1707   }
1708 
emitPredicateOpcodes(MatchTable & Table,RuleMatcher & Rule)1709   void emitPredicateOpcodes(MatchTable &Table,
1710                             RuleMatcher &Rule) const override {
1711     Table << MatchTable::Opcode("GIM_CheckHasOneUse")
1712           << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
1713           << MatchTable::LineBreak;
1714   }
1715 };
1716 
1717 /// Generates code to check that a set of predicates and operands match for a
1718 /// particular instruction.
1719 ///
1720 /// Typical predicates include:
1721 /// * Has a specific opcode.
1722 /// * Has an nsw/nuw flag or doesn't.
1723 class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
1724 protected:
1725   typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
1726 
1727   RuleMatcher &Rule;
1728 
1729   /// The operands to match. All rendered operands must be present even if the
1730   /// condition is always true.
1731   OperandVec Operands;
1732   bool NumOperandsCheck = true;
1733 
1734   std::string SymbolicName;
1735   unsigned InsnVarID;
1736 
1737   /// PhysRegInputs - List list has an entry for each explicitly specified
1738   /// physreg input to the pattern.  The first elt is the Register node, the
1739   /// second is the recorded slot number the input pattern match saved it in.
1740   SmallVector<std::pair<Record *, unsigned>, 2> PhysRegInputs;
1741 
1742 public:
1743   InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
1744                      bool NumOpsCheck = true)
Rule(Rule)1745       : Rule(Rule), NumOperandsCheck(NumOpsCheck), SymbolicName(SymbolicName) {
1746     // We create a new instruction matcher.
1747     // Get a new ID for that instruction.
1748     InsnVarID = Rule.implicitlyDefineInsnVar(*this);
1749   }
1750 
1751   /// Construct a new instruction predicate and add it to the matcher.
1752   template <class Kind, class... Args>
addPredicate(Args &&...args)1753   std::optional<Kind *> addPredicate(Args &&...args) {
1754     Predicates.emplace_back(
1755         std::make_unique<Kind>(getInsnVarID(), std::forward<Args>(args)...));
1756     return static_cast<Kind *>(Predicates.back().get());
1757   }
1758 
getRuleMatcher()1759   RuleMatcher &getRuleMatcher() const { return Rule; }
1760 
getInsnVarID()1761   unsigned getInsnVarID() const { return InsnVarID; }
1762 
1763   /// Add an operand to the matcher.
1764   OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1765                              unsigned AllocatedTemporariesBaseID);
1766   OperandMatcher &getOperand(unsigned OpIdx);
1767   OperandMatcher &addPhysRegInput(Record *Reg, unsigned OpIdx,
1768                                   unsigned TempOpIdx);
1769 
getPhysRegInputs()1770   ArrayRef<std::pair<Record *, unsigned>> getPhysRegInputs() const {
1771     return PhysRegInputs;
1772   }
1773 
getSymbolicName()1774   StringRef getSymbolicName() const { return SymbolicName; }
getNumOperands()1775   unsigned getNumOperands() const { return Operands.size(); }
operands_begin()1776   OperandVec::iterator operands_begin() { return Operands.begin(); }
operands_end()1777   OperandVec::iterator operands_end() { return Operands.end(); }
operands()1778   iterator_range<OperandVec::iterator> operands() {
1779     return make_range(operands_begin(), operands_end());
1780   }
operands_begin()1781   OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
operands_end()1782   OperandVec::const_iterator operands_end() const { return Operands.end(); }
operands()1783   iterator_range<OperandVec::const_iterator> operands() const {
1784     return make_range(operands_begin(), operands_end());
1785   }
operands_empty()1786   bool operands_empty() const { return Operands.empty(); }
1787 
pop_front()1788   void pop_front() { Operands.erase(Operands.begin()); }
1789 
1790   void optimize();
1791 
1792   /// Emit MatchTable opcodes that test whether the instruction named in
1793   /// InsnVarName matches all the predicates and all the operands.
1794   void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule);
1795 
1796   /// Compare the priority of this object and B.
1797   ///
1798   /// Returns true if this object is more important than B.
1799   bool isHigherPriorityThan(InstructionMatcher &B);
1800 
1801   /// Report the maximum number of temporary operands needed by the instruction
1802   /// matcher.
1803   unsigned countRendererFns();
1804 
getOpcodeMatcher()1805   InstructionOpcodeMatcher &getOpcodeMatcher() {
1806     for (auto &P : predicates())
1807       if (auto *OpMatcher = dyn_cast<InstructionOpcodeMatcher>(P.get()))
1808         return *OpMatcher;
1809     llvm_unreachable("Didn't find an opcode matcher");
1810   }
1811 
isConstantInstruction()1812   bool isConstantInstruction() {
1813     return getOpcodeMatcher().isConstantInstruction();
1814   }
1815 
getOpcode()1816   StringRef getOpcode() { return getOpcodeMatcher().getOpcode(); }
1817 };
1818 
1819 /// Generates code to check that the operand is a register defined by an
1820 /// instruction that matches the given instruction matcher.
1821 ///
1822 /// For example, the pattern:
1823 ///   (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1824 /// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1825 /// the:
1826 ///   (G_ADD $src1, $src2)
1827 /// subpattern.
1828 class InstructionOperandMatcher : public OperandPredicateMatcher {
1829 protected:
1830   std::unique_ptr<InstructionMatcher> InsnMatcher;
1831 
1832   GISelFlags Flags;
1833 
1834 public:
1835   InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1836                             RuleMatcher &Rule, StringRef SymbolicName,
1837                             bool NumOpsCheck = true)
OperandPredicateMatcher(OPM_Instruction,InsnVarID,OpIdx)1838       : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
1839         InsnMatcher(new InstructionMatcher(Rule, SymbolicName, NumOpsCheck)),
1840         Flags(Rule.getGISelFlags()) {}
1841 
classof(const PredicateMatcher * P)1842   static bool classof(const PredicateMatcher *P) {
1843     return P->getKind() == OPM_Instruction;
1844   }
1845 
getInsnMatcher()1846   InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1847 
1848   void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const;
emitPredicateOpcodes(MatchTable & Table,RuleMatcher & Rule)1849   void emitPredicateOpcodes(MatchTable &Table,
1850                             RuleMatcher &Rule) const override {
1851     emitCaptureOpcodes(Table, Rule);
1852     InsnMatcher->emitPredicateOpcodes(Table, Rule);
1853   }
1854 
1855   bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override;
1856 
1857   /// Report the maximum number of temporary operands needed by the predicate
1858   /// matcher.
countRendererFns()1859   unsigned countRendererFns() const override {
1860     return InsnMatcher->countRendererFns();
1861   }
1862 };
1863 
1864 //===- Actions ------------------------------------------------------------===//
1865 class OperandRenderer {
1866 public:
1867   enum RendererKind {
1868     OR_Copy,
1869     OR_CopyOrAddZeroReg,
1870     OR_CopySubReg,
1871     OR_CopyPhysReg,
1872     OR_CopyConstantAsImm,
1873     OR_CopyFConstantAsFPImm,
1874     OR_Imm,
1875     OR_SubRegIndex,
1876     OR_Register,
1877     OR_TempRegister,
1878     OR_ComplexPattern,
1879     OR_Intrinsic,
1880     OR_Custom,
1881     OR_CustomOperand
1882   };
1883 
1884 protected:
1885   RendererKind Kind;
1886 
1887 public:
OperandRenderer(RendererKind Kind)1888   OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1889   virtual ~OperandRenderer();
1890 
getKind()1891   RendererKind getKind() const { return Kind; }
1892 
1893   virtual void emitRenderOpcodes(MatchTable &Table,
1894                                  RuleMatcher &Rule) const = 0;
1895 };
1896 
1897 /// A CopyRenderer emits code to copy a single operand from an existing
1898 /// instruction to the one being built.
1899 class CopyRenderer : public OperandRenderer {
1900 protected:
1901   unsigned NewInsnID;
1902   /// The name of the operand.
1903   const StringRef SymbolicName;
1904 
1905 public:
CopyRenderer(unsigned NewInsnID,StringRef SymbolicName)1906   CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1907       : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
1908         SymbolicName(SymbolicName) {
1909     assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1910   }
1911 
classof(const OperandRenderer * R)1912   static bool classof(const OperandRenderer *R) {
1913     return R->getKind() == OR_Copy;
1914   }
1915 
getSymbolicName()1916   StringRef getSymbolicName() const { return SymbolicName; }
1917 
1918   static void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule,
1919                                 unsigned NewInsnID, unsigned OldInsnID,
1920                                 unsigned OpIdx, StringRef Name);
1921 
1922   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1923 };
1924 
1925 /// A CopyRenderer emits code to copy a virtual register to a specific physical
1926 /// register.
1927 class CopyPhysRegRenderer : public OperandRenderer {
1928 protected:
1929   unsigned NewInsnID;
1930   Record *PhysReg;
1931 
1932 public:
CopyPhysRegRenderer(unsigned NewInsnID,Record * Reg)1933   CopyPhysRegRenderer(unsigned NewInsnID, Record *Reg)
1934       : OperandRenderer(OR_CopyPhysReg), NewInsnID(NewInsnID), PhysReg(Reg) {
1935     assert(PhysReg);
1936   }
1937 
classof(const OperandRenderer * R)1938   static bool classof(const OperandRenderer *R) {
1939     return R->getKind() == OR_CopyPhysReg;
1940   }
1941 
getPhysReg()1942   Record *getPhysReg() const { return PhysReg; }
1943 
1944   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1945 };
1946 
1947 /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1948 /// existing instruction to the one being built. If the operand turns out to be
1949 /// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1950 class CopyOrAddZeroRegRenderer : public OperandRenderer {
1951 protected:
1952   unsigned NewInsnID;
1953   /// The name of the operand.
1954   const StringRef SymbolicName;
1955   const Record *ZeroRegisterDef;
1956 
1957 public:
CopyOrAddZeroRegRenderer(unsigned NewInsnID,StringRef SymbolicName,Record * ZeroRegisterDef)1958   CopyOrAddZeroRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
1959                            Record *ZeroRegisterDef)
1960       : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
1961         SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
1962     assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1963   }
1964 
classof(const OperandRenderer * R)1965   static bool classof(const OperandRenderer *R) {
1966     return R->getKind() == OR_CopyOrAddZeroReg;
1967   }
1968 
getSymbolicName()1969   StringRef getSymbolicName() const { return SymbolicName; }
1970 
1971   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1972 };
1973 
1974 /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1975 /// an extended immediate operand.
1976 class CopyConstantAsImmRenderer : public OperandRenderer {
1977 protected:
1978   unsigned NewInsnID;
1979   /// The name of the operand.
1980   const std::string SymbolicName;
1981   bool Signed;
1982 
1983 public:
CopyConstantAsImmRenderer(unsigned NewInsnID,StringRef SymbolicName)1984   CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1985       : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1986         SymbolicName(SymbolicName), Signed(true) {}
1987 
classof(const OperandRenderer * R)1988   static bool classof(const OperandRenderer *R) {
1989     return R->getKind() == OR_CopyConstantAsImm;
1990   }
1991 
getSymbolicName()1992   StringRef getSymbolicName() const { return SymbolicName; }
1993 
1994   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1995 };
1996 
1997 /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1998 /// instruction to an extended immediate operand.
1999 class CopyFConstantAsFPImmRenderer : public OperandRenderer {
2000 protected:
2001   unsigned NewInsnID;
2002   /// The name of the operand.
2003   const std::string SymbolicName;
2004 
2005 public:
CopyFConstantAsFPImmRenderer(unsigned NewInsnID,StringRef SymbolicName)2006   CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2007       : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
2008         SymbolicName(SymbolicName) {}
2009 
classof(const OperandRenderer * R)2010   static bool classof(const OperandRenderer *R) {
2011     return R->getKind() == OR_CopyFConstantAsFPImm;
2012   }
2013 
getSymbolicName()2014   StringRef getSymbolicName() const { return SymbolicName; }
2015 
2016   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2017 };
2018 
2019 /// A CopySubRegRenderer emits code to copy a single register operand from an
2020 /// existing instruction to the one being built and indicate that only a
2021 /// subregister should be copied.
2022 class CopySubRegRenderer : public OperandRenderer {
2023 protected:
2024   unsigned NewInsnID;
2025   /// The name of the operand.
2026   const StringRef SymbolicName;
2027   /// The subregister to extract.
2028   const CodeGenSubRegIndex *SubReg;
2029 
2030 public:
CopySubRegRenderer(unsigned NewInsnID,StringRef SymbolicName,const CodeGenSubRegIndex * SubReg)2031   CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
2032                      const CodeGenSubRegIndex *SubReg)
2033       : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
2034         SymbolicName(SymbolicName), SubReg(SubReg) {}
2035 
classof(const OperandRenderer * R)2036   static bool classof(const OperandRenderer *R) {
2037     return R->getKind() == OR_CopySubReg;
2038   }
2039 
getSymbolicName()2040   StringRef getSymbolicName() const { return SymbolicName; }
2041 
2042   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2043 };
2044 
2045 /// Adds a specific physical register to the instruction being built.
2046 /// This is typically useful for WZR/XZR on AArch64.
2047 class AddRegisterRenderer : public OperandRenderer {
2048 protected:
2049   unsigned InsnID;
2050   const Record *RegisterDef;
2051   bool IsDef;
2052   const CodeGenTarget &Target;
2053 
2054 public:
2055   AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
2056                       const Record *RegisterDef, bool IsDef = false)
OperandRenderer(OR_Register)2057       : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef),
2058         IsDef(IsDef), Target(Target) {}
2059 
classof(const OperandRenderer * R)2060   static bool classof(const OperandRenderer *R) {
2061     return R->getKind() == OR_Register;
2062   }
2063 
2064   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2065 };
2066 
2067 /// Adds a specific temporary virtual register to the instruction being built.
2068 /// This is used to chain instructions together when emitting multiple
2069 /// instructions.
2070 class TempRegRenderer : public OperandRenderer {
2071 protected:
2072   unsigned InsnID;
2073   unsigned TempRegID;
2074   const CodeGenSubRegIndex *SubRegIdx;
2075   bool IsDef;
2076   bool IsDead;
2077 
2078 public:
2079   TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false,
2080                   const CodeGenSubRegIndex *SubReg = nullptr,
2081                   bool IsDead = false)
OperandRenderer(OR_Register)2082       : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
2083         SubRegIdx(SubReg), IsDef(IsDef), IsDead(IsDead) {}
2084 
classof(const OperandRenderer * R)2085   static bool classof(const OperandRenderer *R) {
2086     return R->getKind() == OR_TempRegister;
2087   }
2088 
2089   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2090 };
2091 
2092 /// Adds a specific immediate to the instruction being built.
2093 /// If a LLT is passed, a ConstantInt immediate is created instead.
2094 class ImmRenderer : public OperandRenderer {
2095 protected:
2096   unsigned InsnID;
2097   int64_t Imm;
2098   std::optional<LLTCodeGenOrTempType> CImmLLT;
2099 
2100 public:
ImmRenderer(unsigned InsnID,int64_t Imm)2101   ImmRenderer(unsigned InsnID, int64_t Imm)
2102       : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
2103 
ImmRenderer(unsigned InsnID,int64_t Imm,const LLTCodeGenOrTempType & CImmLLT)2104   ImmRenderer(unsigned InsnID, int64_t Imm, const LLTCodeGenOrTempType &CImmLLT)
2105       : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm), CImmLLT(CImmLLT) {
2106     if (CImmLLT.isLLTCodeGen())
2107       KnownTypes.insert(CImmLLT.getLLTCodeGen());
2108   }
2109 
classof(const OperandRenderer * R)2110   static bool classof(const OperandRenderer *R) {
2111     return R->getKind() == OR_Imm;
2112   }
2113 
2114   static void emitAddImm(MatchTable &Table, RuleMatcher &RM, unsigned InsnID,
2115                          int64_t Imm, StringRef ImmName = "Imm");
2116 
2117   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2118 };
2119 
2120 /// Adds an enum value for a subreg index to the instruction being built.
2121 class SubRegIndexRenderer : public OperandRenderer {
2122 protected:
2123   unsigned InsnID;
2124   const CodeGenSubRegIndex *SubRegIdx;
2125 
2126 public:
SubRegIndexRenderer(unsigned InsnID,const CodeGenSubRegIndex * SRI)2127   SubRegIndexRenderer(unsigned InsnID, const CodeGenSubRegIndex *SRI)
2128       : OperandRenderer(OR_SubRegIndex), InsnID(InsnID), SubRegIdx(SRI) {}
2129 
classof(const OperandRenderer * R)2130   static bool classof(const OperandRenderer *R) {
2131     return R->getKind() == OR_SubRegIndex;
2132   }
2133 
2134   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2135 };
2136 
2137 /// Adds operands by calling a renderer function supplied by the ComplexPattern
2138 /// matcher function.
2139 class RenderComplexPatternOperand : public OperandRenderer {
2140 private:
2141   unsigned InsnID;
2142   const Record &TheDef;
2143   /// The name of the operand.
2144   const StringRef SymbolicName;
2145   /// The renderer number. This must be unique within a rule since it's used to
2146   /// identify a temporary variable to hold the renderer function.
2147   unsigned RendererID;
2148   /// When provided, this is the suboperand of the ComplexPattern operand to
2149   /// render. Otherwise all the suboperands will be rendered.
2150   std::optional<unsigned> SubOperand;
2151   /// The subregister to extract. Render the whole register if not specified.
2152   const CodeGenSubRegIndex *SubReg;
2153 
getNumOperands()2154   unsigned getNumOperands() const {
2155     return TheDef.getValueAsDag("Operands")->getNumArgs();
2156   }
2157 
2158 public:
2159   RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
2160                               StringRef SymbolicName, unsigned RendererID,
2161                               std::optional<unsigned> SubOperand = std::nullopt,
2162                               const CodeGenSubRegIndex *SubReg = nullptr)
OperandRenderer(OR_ComplexPattern)2163       : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
2164         SymbolicName(SymbolicName), RendererID(RendererID),
2165         SubOperand(SubOperand), SubReg(SubReg) {}
2166 
classof(const OperandRenderer * R)2167   static bool classof(const OperandRenderer *R) {
2168     return R->getKind() == OR_ComplexPattern;
2169   }
2170 
2171   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2172 };
2173 
2174 /// Adds an intrinsic ID operand to the instruction being built.
2175 class IntrinsicIDRenderer : public OperandRenderer {
2176 protected:
2177   unsigned InsnID;
2178   const CodeGenIntrinsic *II;
2179 
2180 public:
IntrinsicIDRenderer(unsigned InsnID,const CodeGenIntrinsic * II)2181   IntrinsicIDRenderer(unsigned InsnID, const CodeGenIntrinsic *II)
2182       : OperandRenderer(OR_Intrinsic), InsnID(InsnID), II(II) {}
2183 
classof(const OperandRenderer * R)2184   static bool classof(const OperandRenderer *R) {
2185     return R->getKind() == OR_Intrinsic;
2186   }
2187 
2188   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2189 };
2190 
2191 class CustomRenderer : public OperandRenderer {
2192 protected:
2193   unsigned InsnID;
2194   const Record &Renderer;
2195   /// The name of the operand.
2196   const std::string SymbolicName;
2197 
2198 public:
CustomRenderer(unsigned InsnID,const Record & Renderer,StringRef SymbolicName)2199   CustomRenderer(unsigned InsnID, const Record &Renderer,
2200                  StringRef SymbolicName)
2201       : OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer),
2202         SymbolicName(SymbolicName) {}
2203 
classof(const OperandRenderer * R)2204   static bool classof(const OperandRenderer *R) {
2205     return R->getKind() == OR_Custom;
2206   }
2207 
2208   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2209 };
2210 
2211 class CustomOperandRenderer : public OperandRenderer {
2212 protected:
2213   unsigned InsnID;
2214   const Record &Renderer;
2215   /// The name of the operand.
2216   const std::string SymbolicName;
2217 
2218 public:
CustomOperandRenderer(unsigned InsnID,const Record & Renderer,StringRef SymbolicName)2219   CustomOperandRenderer(unsigned InsnID, const Record &Renderer,
2220                         StringRef SymbolicName)
2221       : OperandRenderer(OR_CustomOperand), InsnID(InsnID), Renderer(Renderer),
2222         SymbolicName(SymbolicName) {}
2223 
classof(const OperandRenderer * R)2224   static bool classof(const OperandRenderer *R) {
2225     return R->getKind() == OR_CustomOperand;
2226   }
2227 
2228   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2229 };
2230 
2231 /// An action taken when all Matcher predicates succeeded for a parent rule.
2232 ///
2233 /// Typical actions include:
2234 /// * Changing the opcode of an instruction.
2235 /// * Adding an operand to an instruction.
2236 class MatchAction {
2237 public:
2238   enum ActionKind {
2239     AK_DebugComment,
2240     AK_BuildMI,
2241     AK_BuildConstantMI,
2242     AK_EraseInst,
2243     AK_ReplaceReg,
2244     AK_ConstraintOpsToDef,
2245     AK_ConstraintOpsToRC,
2246     AK_MakeTempReg,
2247   };
2248 
MatchAction(ActionKind K)2249   MatchAction(ActionKind K) : Kind(K) {}
2250 
getKind()2251   ActionKind getKind() const { return Kind; }
2252 
~MatchAction()2253   virtual ~MatchAction() {}
2254 
2255   // Some actions may need to add extra predicates to ensure they can run.
emitAdditionalPredicates(MatchTable & Table,RuleMatcher & Rule)2256   virtual void emitAdditionalPredicates(MatchTable &Table,
2257                                         RuleMatcher &Rule) const {}
2258 
2259   /// Emit the MatchTable opcodes to implement the action.
2260   virtual void emitActionOpcodes(MatchTable &Table,
2261                                  RuleMatcher &Rule) const = 0;
2262 
2263   /// If this opcode has an overload that can call GIR_Done directly, emit that
2264   /// instead of the usual opcode and return "true". Return "false" if GIR_Done
2265   /// still needs to be emitted.
emitActionOpcodesAndDone(MatchTable & Table,RuleMatcher & Rule)2266   virtual bool emitActionOpcodesAndDone(MatchTable &Table,
2267                                         RuleMatcher &Rule) const {
2268     emitActionOpcodes(Table, Rule);
2269     return false;
2270   }
2271 
2272 private:
2273   ActionKind Kind;
2274 };
2275 
2276 /// Generates a comment describing the matched rule being acted upon.
2277 class DebugCommentAction : public MatchAction {
2278 private:
2279   std::string S;
2280 
2281 public:
DebugCommentAction(StringRef S)2282   DebugCommentAction(StringRef S)
2283       : MatchAction(AK_DebugComment), S(std::string(S)) {}
2284 
classof(const MatchAction * A)2285   static bool classof(const MatchAction *A) {
2286     return A->getKind() == AK_DebugComment;
2287   }
2288 
emitActionOpcodes(MatchTable & Table,RuleMatcher & Rule)2289   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2290     Table << MatchTable::Comment(S) << MatchTable::LineBreak;
2291   }
2292 };
2293 
2294 /// Generates code to build an instruction or mutate an existing instruction
2295 /// into the desired instruction when this is possible.
2296 class BuildMIAction : public MatchAction {
2297 private:
2298   unsigned InsnID;
2299   const CodeGenInstruction *I;
2300   InstructionMatcher *Matched;
2301   std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
2302   SmallPtrSet<Record *, 4> DeadImplicitDefs;
2303 
2304   std::vector<const InstructionMatcher *> CopiedFlags;
2305   std::vector<StringRef> SetFlags;
2306   std::vector<StringRef> UnsetFlags;
2307 
2308   /// True if the instruction can be built solely by mutating the opcode.
2309   bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const;
2310 
2311 public:
BuildMIAction(unsigned InsnID,const CodeGenInstruction * I)2312   BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
2313       : MatchAction(AK_BuildMI), InsnID(InsnID), I(I), Matched(nullptr) {}
2314 
classof(const MatchAction * A)2315   static bool classof(const MatchAction *A) {
2316     return A->getKind() == AK_BuildMI;
2317   }
2318 
getInsnID()2319   unsigned getInsnID() const { return InsnID; }
getCGI()2320   const CodeGenInstruction *getCGI() const { return I; }
2321 
addSetMIFlags(StringRef Flag)2322   void addSetMIFlags(StringRef Flag) { SetFlags.push_back(Flag); }
addUnsetMIFlags(StringRef Flag)2323   void addUnsetMIFlags(StringRef Flag) { UnsetFlags.push_back(Flag); }
addCopiedMIFlags(const InstructionMatcher & IM)2324   void addCopiedMIFlags(const InstructionMatcher &IM) {
2325     CopiedFlags.push_back(&IM);
2326   }
2327 
2328   void chooseInsnToMutate(RuleMatcher &Rule);
2329 
setDeadImplicitDef(Record * R)2330   void setDeadImplicitDef(Record *R) { DeadImplicitDefs.insert(R); }
2331 
addRenderer(Args &&...args)2332   template <class Kind, class... Args> Kind &addRenderer(Args &&...args) {
2333     OperandRenderers.emplace_back(
2334         std::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
2335     return *static_cast<Kind *>(OperandRenderers.back().get());
2336   }
2337 
2338   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2339 };
2340 
2341 /// Generates code to create a constant that defines a TempReg.
2342 /// The instruction created is usually a G_CONSTANT but it could also be a
2343 /// G_BUILD_VECTOR for vector types.
2344 class BuildConstantAction : public MatchAction {
2345   unsigned TempRegID;
2346   int64_t Val;
2347 
2348 public:
BuildConstantAction(unsigned TempRegID,int64_t Val)2349   BuildConstantAction(unsigned TempRegID, int64_t Val)
2350       : MatchAction(AK_BuildConstantMI), TempRegID(TempRegID), Val(Val) {}
2351 
classof(const MatchAction * A)2352   static bool classof(const MatchAction *A) {
2353     return A->getKind() == AK_BuildConstantMI;
2354   }
2355 
2356   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2357 };
2358 
2359 class EraseInstAction : public MatchAction {
2360   unsigned InsnID;
2361 
2362 public:
EraseInstAction(unsigned InsnID)2363   EraseInstAction(unsigned InsnID)
2364       : MatchAction(AK_EraseInst), InsnID(InsnID) {}
2365 
getInsnID()2366   unsigned getInsnID() const { return InsnID; }
2367 
classof(const MatchAction * A)2368   static bool classof(const MatchAction *A) {
2369     return A->getKind() == AK_EraseInst;
2370   }
2371 
2372   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2373   bool emitActionOpcodesAndDone(MatchTable &Table,
2374                                 RuleMatcher &Rule) const override;
2375 };
2376 
2377 class ReplaceRegAction : public MatchAction {
2378   unsigned OldInsnID, OldOpIdx;
2379   unsigned NewInsnId = -1, NewOpIdx;
2380   unsigned TempRegID = -1;
2381 
2382 public:
ReplaceRegAction(unsigned OldInsnID,unsigned OldOpIdx,unsigned NewInsnId,unsigned NewOpIdx)2383   ReplaceRegAction(unsigned OldInsnID, unsigned OldOpIdx, unsigned NewInsnId,
2384                    unsigned NewOpIdx)
2385       : MatchAction(AK_ReplaceReg), OldInsnID(OldInsnID), OldOpIdx(OldOpIdx),
2386         NewInsnId(NewInsnId), NewOpIdx(NewOpIdx) {}
2387 
ReplaceRegAction(unsigned OldInsnID,unsigned OldOpIdx,unsigned TempRegID)2388   ReplaceRegAction(unsigned OldInsnID, unsigned OldOpIdx, unsigned TempRegID)
2389       : MatchAction(AK_ReplaceReg), OldInsnID(OldInsnID), OldOpIdx(OldOpIdx),
2390         TempRegID(TempRegID) {}
2391 
classof(const MatchAction * A)2392   static bool classof(const MatchAction *A) {
2393     return A->getKind() == AK_ReplaceReg;
2394   }
2395 
2396   void emitAdditionalPredicates(MatchTable &Table,
2397                                 RuleMatcher &Rule) const override;
2398   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2399 };
2400 
2401 /// Generates code to constrain the operands of an output instruction to the
2402 /// register classes specified by the definition of that instruction.
2403 class ConstrainOperandsToDefinitionAction : public MatchAction {
2404   unsigned InsnID;
2405 
2406 public:
ConstrainOperandsToDefinitionAction(unsigned InsnID)2407   ConstrainOperandsToDefinitionAction(unsigned InsnID)
2408       : MatchAction(AK_ConstraintOpsToDef), InsnID(InsnID) {}
2409 
classof(const MatchAction * A)2410   static bool classof(const MatchAction *A) {
2411     return A->getKind() == AK_ConstraintOpsToDef;
2412   }
2413 
emitActionOpcodes(MatchTable & Table,RuleMatcher & Rule)2414   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2415     if (InsnID == 0) {
2416       Table << MatchTable::Opcode("GIR_RootConstrainSelectedInstOperands")
2417             << MatchTable::LineBreak;
2418     } else {
2419       Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2420             << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
2421             << MatchTable::LineBreak;
2422     }
2423   }
2424 };
2425 
2426 /// Generates code to constrain the specified operand of an output instruction
2427 /// to the specified register class.
2428 class ConstrainOperandToRegClassAction : public MatchAction {
2429   unsigned InsnID;
2430   unsigned OpIdx;
2431   const CodeGenRegisterClass &RC;
2432 
2433 public:
ConstrainOperandToRegClassAction(unsigned InsnID,unsigned OpIdx,const CodeGenRegisterClass & RC)2434   ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
2435                                    const CodeGenRegisterClass &RC)
2436       : MatchAction(AK_ConstraintOpsToRC), InsnID(InsnID), OpIdx(OpIdx),
2437         RC(RC) {}
2438 
classof(const MatchAction * A)2439   static bool classof(const MatchAction *A) {
2440     return A->getKind() == AK_ConstraintOpsToRC;
2441   }
2442 
2443   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2444 };
2445 
2446 /// Generates code to create a temporary register which can be used to chain
2447 /// instructions together.
2448 class MakeTempRegisterAction : public MatchAction {
2449 private:
2450   LLTCodeGenOrTempType Ty;
2451   unsigned TempRegID;
2452 
2453 public:
MakeTempRegisterAction(const LLTCodeGenOrTempType & Ty,unsigned TempRegID)2454   MakeTempRegisterAction(const LLTCodeGenOrTempType &Ty, unsigned TempRegID)
2455       : MatchAction(AK_MakeTempReg), Ty(Ty), TempRegID(TempRegID) {
2456     if (Ty.isLLTCodeGen())
2457       KnownTypes.insert(Ty.getLLTCodeGen());
2458   }
2459 
classof(const MatchAction * A)2460   static bool classof(const MatchAction *A) {
2461     return A->getKind() == AK_MakeTempReg;
2462   }
2463 
2464   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2465 };
2466 
2467 } // namespace gi
2468 } // namespace llvm
2469 
2470 #endif
2471