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