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