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
38namespace llvm {
39
40class raw_ostream;
41class Record;
42class SMLoc;
43class CodeGenRegisterClass;
44
45// Use a namespace to avoid conflicts because there's some fairly generic names
46// in there (e.g. Matcher).
47namespace gi {
48class MatchTable;
49class Matcher;
50class OperandMatcher;
51class MatchAction;
52class PredicateMatcher;
53class InstructionMatcher;
54
55enum {
56 GISF_IgnoreCopies = 0x1,
57};
58
59using GISelFlags = std::uint32_t;
60
61//===- Helper functions ---------------------------------------------------===//
62
63void emitEncodingMacrosDef(raw_ostream &OS);
64void emitEncodingMacrosUndef(raw_ostream &OS);
65
66std::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
94template <class GroupT>
95std::vector<Matcher *>
96optimizeRules(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.
105struct 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
138private:
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
144public:
145 /// A bitfield of RecordFlagsBits flags.
146 unsigned Flags;
147
148 MatchTableRecord(std::optional<unsigned> LabelID_, StringRef EmitStr,
149 unsigned NumElements, unsigned Flags)
150 : LabelID(LabelID_.value_or(u: ~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
159 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;
167 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.
172class 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
190public:
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)
206 : ID(ID), IsWithCoverage(WithCoverage), IsCombinerTable(IsCombinerTable) {
207 }
208
209 bool isWithCoverage() const { return IsWithCoverage; }
210 bool isCombiner() const { return IsCombinerTable; }
211
212 void push_back(const MatchTableRecord &Value) {
213 if (Value.Flags & MatchTableRecord::MTRF_Label)
214 defineLabel(LabelID: Value.LabelID);
215 Contents.push_back(x: Value);
216 CurrentSize += Value.size();
217 }
218
219 unsigned allocateLabelID() { return CurrentLabelID++; }
220
221 void defineLabel(unsigned LabelID) {
222 LabelMap.try_emplace(Key: LabelID, Args&: CurrentSize);
223 }
224
225 unsigned getLabelIndex(unsigned LabelID) const {
226 const auto I = LabelMap.find(Val: 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
235inline 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.
243class LLTCodeGen {
244private:
245 LLT Ty;
246
247public:
248 LLTCodeGen() = default;
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
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.
266extern 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, ...).
270std::optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT);
271
272using TempTypeIdx = int64_t;
273class LLTCodeGenOrTempType {
274public:
275 LLTCodeGenOrTempType(const LLTCodeGen &LLT) : Data(LLT) {}
276 LLTCodeGenOrTempType(TempTypeIdx TempTy) : Data(TempTy) {}
277
278 bool isLLTCodeGen() const { return std::holds_alternative<LLTCodeGen>(v: Data); }
279 bool isTempTypeIdx() const {
280 return std::holds_alternative<TempTypeIdx>(v: Data);
281 }
282
283 const LLTCodeGen &getLLTCodeGen() const {
284 assert(isLLTCodeGen());
285 return std::get<LLTCodeGen>(v: Data);
286 }
287
288 TempTypeIdx getTempTypeIdx() const {
289 assert(isTempTypeIdx());
290 return std::get<TempTypeIdx>(v: Data);
291 }
292
293private:
294 std::variant<LLTCodeGen, TempTypeIdx> Data;
295};
296
297inline MatchTable &operator<<(MatchTable &Table,
298 const LLTCodeGenOrTempType &Ty) {
299 if (Ty.isLLTCodeGen())
300 Table << MatchTable::NamedValue(NumBytes: 1, NamedValue: Ty.getLLTCodeGen().getCxxEnumValue());
301 else
302 Table << MatchTable::IntValue(NumBytes: 1, IntValue: Ty.getTempTypeIdx());
303 return Table;
304}
305
306//===- Matchers -----------------------------------------------------------===//
307class Matcher {
308public:
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
318class 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
329public:
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.
363 iterator_range<std::vector<Matcher *>::iterator> matchers() {
364 return make_range(x: Matchers.begin(), y: Matchers.end());
365 }
366 size_t size() const { return Matchers.size(); }
367 bool empty() const { return Matchers.empty(); }
368
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(CI: Conditions.begin());
374 return P;
375 }
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 }
381 bool hasFirstCondition() const override { return !Conditions.empty(); }
382
383private:
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.
390struct RecordAndValue {
391 MatchTableRecord Record;
392 int64_t RawValue;
393
394 RecordAndValue(MatchTableRecord Record,
395 int64_t RawValue = std::numeric_limits<int64_t>::min())
396 : Record(std::move(Record)), RawValue(RawValue) {}
397
398 bool operator<(const RecordAndValue &Other) const {
399 return RawValue < Other.RawValue;
400 }
401};
402
403class 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
423public:
424 bool addMatcher(Matcher &Candidate);
425
426 void finalize();
427 void emit(MatchTable &Table) override;
428
429 iterator_range<std::vector<Matcher *>::iterator> matchers() {
430 return make_range(x: Matchers.begin(), y: Matchers.end());
431 }
432 size_t size() const { return Matchers.size(); }
433 bool empty() const { return Matchers.empty(); }
434
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
442 const PredicateMatcher &getFirstCondition() const override {
443 llvm_unreachable("Trying to pop a condition from a condition-less group");
444 }
445
446 bool hasFirstCondition() const override { return false; }
447
448private:
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.
460class RuleMatcher : public Matcher {
461public:
462 using ActionList = std::list<std::unique_ptr<MatchAction>>;
463 using action_iterator = ActionList::iterator;
464
465protected:
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
547public:
548 RuleMatcher(ArrayRef<SMLoc> SrcLoc) : SrcLoc(SrcLoc), RuleID(NextRuleID++) {}
549 RuleMatcher(RuleMatcher &&Other) = default;
550 RuleMatcher &operator=(RuleMatcher &&Other) = default;
551
552 TempTypeIdx getNextTempTypeIdx() { return NextTempTypeIdx--; }
553
554 uint64_t getRuleID() const { return RuleID; }
555
556 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
557 void addRequiredFeature(const Record *Feature) {
558 RequiredFeatures.push_back(x: Feature);
559 }
560 ArrayRef<const Record *> getRequiredFeatures() const {
561 return RequiredFeatures;
562 }
563
564 void addHwModeIdx(unsigned Idx) { HwModeIdx = Idx; }
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.
573 bool tryEraseInsnID(unsigned ID) { return ErasedInsnIDs.insert(V: ID).second; }
574
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.
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>
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
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);
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;
616 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
617 return InsnVariableIDs.begin();
618 }
619 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
620 return InsnVariableIDs.end();
621 }
622 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
623 defined_insn_vars() const {
624 return make_range(x: defined_insn_vars_begin(), y: defined_insn_vars_end());
625 }
626
627 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
628 return MutatableInsns.begin();
629 }
630 MutatableInsnSet::const_iterator mutatable_insns_end() const {
631 return MutatableInsns.end();
632 }
633 iterator_range<typename MutatableInsnSet::const_iterator>
634 mutatable_insns() const {
635 return make_range(x: mutatable_insns_begin(), y: mutatable_insns_end());
636 }
637 void reserveInsnMatcherForMutation(InstructionMatcher *InsnMatcher) {
638 bool R = MutatableInsns.erase(Ptr: InsnMatcher);
639 assert(R && "Reserving a mutatable insn that isn't available");
640 (void)R;
641 }
642
643 action_iterator actions_begin() { return Actions.begin(); }
644 action_iterator actions_end() { return Actions.end(); }
645 iterator_range<action_iterator> actions() {
646 return make_range(x: actions_begin(), y: actions_end());
647 }
648
649 bool hasOperand(StringRef SymbolicName) const {
650 return DefinedOperands.contains(Key: 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>
663 getComplexSubOperand(StringRef SymbolicName) const {
664 const auto &I = ComplexSubOperands.find(Key: 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
694 InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
695
696 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
697 unsigned allocateTempRegID() { return NextTempRegID++; }
698
699 iterator_range<PhysRegOperandsTy::const_iterator> physoperands() const {
700 return make_range(x: PhysRegOperands.begin(), y: PhysRegOperands.end());
701 }
702
703 iterator_range<MatchersTy::iterator> insnmatchers() {
704 return make_range(x: Matchers.begin(), y: Matchers.end());
705 }
706 bool insnmatchers_empty() const { return Matchers.empty(); }
707 void insnmatchers_pop_front() { Matchers.erase(position: Matchers.begin()); }
708};
709
710template <class PredicateTy> class PredicateListMatcher {
711private:
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
716protected:
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
724public:
725 typename PredicatesTy::iterator predicates_begin() {
726 return Predicates.begin();
727 }
728 typename PredicatesTy::iterator predicates_end() { return Predicates.end(); }
729 iterator_range<typename PredicatesTy::iterator> predicates() {
730 return make_range(predicates_begin(), predicates_end());
731 }
732 typename PredicatesTy::size_type predicates_size() const {
733 return Predicates.size();
734 }
735 bool predicates_empty() const { return Predicates.empty(); }
736
737 template <typename Ty> bool contains() const {
738 return any_of(Predicates, [&](auto &P) { return isa<Ty>(P.get()); });
739 }
740
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
748 void prependPredicate(std::unique_ptr<PredicateTy> &&Predicate) {
749 Predicates.push_front(std::move(Predicate));
750 }
751
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>
764 void emitPredicateListOpcodes(MatchTable &Table, Args &&...args) {
765 if (Predicates.empty() && !Optimized) {
766 Table << MatchTable::Comment(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>
783 void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate,
784 MatchTable &Table, Args &&...args) {
785 if (Predicates.empty() && !Optimized) {
786 Table << MatchTable::Comment(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
798class PredicateMatcher {
799public:
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
841protected:
842 PredicateKind Kind;
843 unsigned InsnVarID;
844 unsigned OpIdx;
845
846public:
847 PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
848 : Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
849 virtual ~PredicateMatcher();
850
851 unsigned getInsnVarID() const { return InsnVarID; }
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
858 PredicateKind getKind() const { return Kind; }
859
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
867 virtual bool isIdentical(const PredicateMatcher &B) const {
868 return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
869 OpIdx == B.OpIdx;
870 }
871
872 virtual bool isIdenticalDownToValue(const PredicateMatcher &B) const {
873 return hasValue() && PredicateMatcher::isIdentical(B);
874 }
875
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 }
880 virtual bool hasValue() const { return false; }
881
882 /// Report the maximum number of temporary operands needed by the predicate
883 /// matcher.
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.
893class OperandPredicateMatcher : public PredicateMatcher {
894public:
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
906template <>
907inline std::string
908PredicateListMatcher<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.
914class SameOperandMatcher : public OperandPredicateMatcher {
915 std::string MatchingName;
916 unsigned OrigOpIdx;
917
918 GISelFlags Flags;
919
920public:
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
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
933 bool isIdentical(const PredicateMatcher &B) const override {
934 return OperandPredicateMatcher::isIdentical(B) &&
935 OrigOpIdx == cast<SameOperandMatcher>(Val: &B)->OrigOpIdx &&
936 MatchingName == cast<SameOperandMatcher>(Val: &B)->MatchingName;
937 }
938};
939
940/// Generates code to check that an operand is a particular LLT.
941class LLTOperandMatcher : public OperandPredicateMatcher {
942protected:
943 LLTCodeGen Ty;
944
945public:
946 static std::map<LLTCodeGen, unsigned> TypeIDValues;
947
948 static void initTypeIDValuesMap() {
949 TypeIDValues.clear();
950
951 unsigned ID = 0;
952 for (const LLTCodeGen &LLTy : KnownTypes)
953 TypeIDValues[LLTy] = ID++;
954 }
955
956 LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty)
957 : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
958 KnownTypes.insert(x: Ty);
959 }
960
961 static bool classof(const PredicateMatcher *P) {
962 return P->getKind() == OPM_LLT;
963 }
964
965 bool isIdentical(const PredicateMatcher &B) const override {
966 return OperandPredicateMatcher::isIdentical(B) &&
967 Ty == cast<LLTOperandMatcher>(Val: &B)->Ty;
968 }
969
970 RecordAndValue getValue() const override;
971 bool hasValue() const override;
972
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.
989class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
990protected:
991 unsigned SizeInBits;
992
993public:
994 PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
995 unsigned SizeInBits)
996 : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
997 SizeInBits(SizeInBits) {}
998
999 static bool classof(const PredicateMatcher *P) {
1000 return P->getKind() == OPM_PointerToAny;
1001 }
1002
1003 bool isIdentical(const PredicateMatcher &B) const override {
1004 return OperandPredicateMatcher::isIdentical(B) &&
1005 SizeInBits == cast<PointerToAnyOperandMatcher>(Val: &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.
1015class RecordNamedOperandMatcher : public OperandPredicateMatcher {
1016protected:
1017 unsigned StoreIdx;
1018 std::string Name;
1019
1020public:
1021 RecordNamedOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1022 unsigned StoreIdx, StringRef Name)
1023 : OperandPredicateMatcher(OPM_RecordNamedOperand, InsnVarID, OpIdx),
1024 StoreIdx(StoreIdx), Name(Name) {}
1025
1026 static bool classof(const PredicateMatcher *P) {
1027 return P->getKind() == OPM_RecordNamedOperand;
1028 }
1029
1030 bool isIdentical(const PredicateMatcher &B) const override {
1031 return OperandPredicateMatcher::isIdentical(B) &&
1032 StoreIdx == cast<RecordNamedOperandMatcher>(Val: &B)->StoreIdx &&
1033 Name == cast<RecordNamedOperandMatcher>(Val: &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.
1042class RecordRegisterType : public OperandPredicateMatcher {
1043protected:
1044 TempTypeIdx Idx;
1045
1046public:
1047 RecordRegisterType(unsigned InsnVarID, unsigned OpIdx, TempTypeIdx Idx)
1048 : OperandPredicateMatcher(OPM_RecordRegType, InsnVarID, OpIdx), Idx(Idx) {
1049 }
1050
1051 static bool classof(const PredicateMatcher *P) {
1052 return P->getKind() == OPM_RecordRegType;
1053 }
1054
1055 bool isIdentical(const PredicateMatcher &B) const override {
1056 return OperandPredicateMatcher::isIdentical(B) &&
1057 Idx == cast<RecordRegisterType>(Val: &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.
1065class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
1066protected:
1067 const OperandMatcher &Operand;
1068 const Record &TheDef;
1069
1070 unsigned getAllocatedTemporariesBaseID() const;
1071
1072public:
1073 bool isIdentical(const PredicateMatcher &B) const override { return false; }
1074
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
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;
1087 unsigned countRendererFns() const override { return 1; }
1088};
1089
1090/// Generates code to check that an operand is in a particular register bank.
1091class RegisterBankOperandMatcher : public OperandPredicateMatcher {
1092protected:
1093 const CodeGenRegisterClass &RC;
1094
1095public:
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
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.
1111class MBBOperandMatcher : public OperandPredicateMatcher {
1112public:
1113 MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1114 : OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
1115
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
1124class ImmOperandMatcher : public OperandPredicateMatcher {
1125public:
1126 ImmOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1127 : OperandPredicateMatcher(IPM_Imm, InsnVarID, OpIdx) {}
1128
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.
1139class ConstantIntOperandMatcher : public OperandPredicateMatcher {
1140protected:
1141 int64_t Value;
1142
1143public:
1144 ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1145 : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {}
1146
1147 bool isIdentical(const PredicateMatcher &B) const override {
1148 return OperandPredicateMatcher::isIdentical(B) &&
1149 Value == cast<ConstantIntOperandMatcher>(Val: &B)->Value;
1150 }
1151
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).
1162class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1163protected:
1164 int64_t Value;
1165
1166public:
1167 LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1168 : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
1169 Value(Value) {}
1170
1171 bool isIdentical(const PredicateMatcher &B) const override {
1172 return OperandPredicateMatcher::isIdentical(B) &&
1173 Value == cast<LiteralIntOperandMatcher>(Val: &B)->Value;
1174 }
1175
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
1185class CmpPredicateOperandMatcher : public OperandPredicateMatcher {
1186protected:
1187 std::string PredName;
1188
1189public:
1190 CmpPredicateOperandMatcher(unsigned InsnVarID, unsigned OpIdx, std::string P)
1191 : OperandPredicateMatcher(OPM_CmpPredicate, InsnVarID, OpIdx),
1192 PredName(std::move(P)) {}
1193
1194 bool isIdentical(const PredicateMatcher &B) const override {
1195 return OperandPredicateMatcher::isIdentical(B) &&
1196 PredName == cast<CmpPredicateOperandMatcher>(Val: &B)->PredName;
1197 }
1198
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.
1208class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1209protected:
1210 const CodeGenIntrinsic *II;
1211
1212public:
1213 IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1214 const CodeGenIntrinsic *II)
1215 : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
1216
1217 bool isIdentical(const PredicateMatcher &B) const override {
1218 return OperandPredicateMatcher::isIdentical(B) &&
1219 II == cast<IntrinsicIDOperandMatcher>(Val: &B)->II;
1220 }
1221
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.
1232class OperandImmPredicateMatcher : public OperandPredicateMatcher {
1233protected:
1234 TreePredicateFn Predicate;
1235
1236public:
1237 OperandImmPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
1238 const TreePredicateFn &Predicate)
1239 : OperandPredicateMatcher(IPM_ImmPredicate, InsnVarID, OpIdx),
1240 Predicate(Predicate) {}
1241
1242 bool isIdentical(const PredicateMatcher &B) const override {
1243 return OperandPredicateMatcher::isIdentical(B) &&
1244 Predicate.getOrigPatFragRecord() ==
1245 cast<OperandImmPredicateMatcher>(Val: &B)
1246 ->Predicate.getOrigPatFragRecord();
1247 }
1248
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.
1259class OperandLeafPredicateMatcher : public OperandPredicateMatcher {
1260protected:
1261 TreePredicateFn Predicate;
1262
1263public:
1264 OperandLeafPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
1265 const TreePredicateFn &Predicate)
1266 : OperandPredicateMatcher(OPM_LeafPredicate, InsnVarID, OpIdx),
1267 Predicate(Predicate) {}
1268
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.
1279class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1280protected:
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
1295public:
1296 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
1297 const std::string &SymbolicName,
1298 unsigned AllocatedTemporariesBaseID, bool IsVariadic = false)
1299 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1300 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID),
1301 IsVariadic(IsVariadic) {}
1302
1303 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1304 StringRef getSymbolicName() const { return SymbolicName; }
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>
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
1321 unsigned getOpIdx() const { return OpIdx; }
1322 unsigned getInsnVarID() const;
1323
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
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
1351 unsigned getAllocatedTemporariesBaseID() const {
1352 return AllocatedTemporariesBaseID;
1353 }
1354
1355 bool isSameAsAnotherOperand() {
1356 for (const auto &Predicate : predicates())
1357 if (isa<SameOperandMatcher>(Val: 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.
1368class InstructionPredicateMatcher : public PredicateMatcher {
1369public:
1370 InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
1371 : PredicateMatcher(Kind, InsnVarID) {}
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
1378 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
1379 return Kind < B.Kind;
1380 };
1381};
1382
1383template <>
1384inline std::string
1385PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
1386 return "No instruction predicates";
1387}
1388
1389/// Generates code to check the opcode of an instruction.
1390class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1391protected:
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
1402public:
1403 static void initOpcodeValuesMap(const CodeGenTarget &Target);
1404
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
1412 static bool classof(const PredicateMatcher *P) {
1413 return P->getKind() == IPM_Opcode;
1414 }
1415
1416 bool isIdentical(const PredicateMatcher &B) const override {
1417 return InstructionPredicateMatcher::isIdentical(B) &&
1418 Insts == cast<InstructionOpcodeMatcher>(Val: &B)->Insts;
1419 }
1420
1421 bool hasValue() const override {
1422 return Insts.size() == 1 && OpcodeValues.contains(Val: 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;
1442 ArrayRef<const CodeGenInstruction *> getAlternativeOpcodes() { return Insts; }
1443 bool isVariadicNumOperands() const;
1444 StringRef getOperandType(unsigned OpIdx) const;
1445};
1446
1447class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher {
1448public:
1449 enum class CheckKind { Eq, LE, GE };
1450
1451private:
1452 unsigned NumOperands = 0;
1453 CheckKind CK;
1454
1455public:
1456 InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands,
1457 CheckKind CK = CheckKind::Eq)
1458 : InstructionPredicateMatcher(IPM_NumOperands, InsnVarID),
1459 NumOperands(NumOperands), CK(CK) {}
1460
1461 static bool classof(const PredicateMatcher *P) {
1462 return P->getKind() == IPM_NumOperands;
1463 }
1464
1465 bool isIdentical(const PredicateMatcher &B) const override {
1466 if (!InstructionPredicateMatcher::isIdentical(B))
1467 return false;
1468 const auto &Other = *cast<InstructionNumOperandsMatcher>(Val: &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.
1503class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1504protected:
1505 TreePredicateFn Predicate;
1506
1507public:
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
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.
1525class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
1526public:
1527 enum AOComparator {
1528 AO_Exactly,
1529 AO_OrStronger,
1530 AO_WeakerThan,
1531 };
1532
1533protected:
1534 StringRef Order;
1535 AOComparator Comparator;
1536
1537public:
1538 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
1539 AOComparator Comparator = AO_Exactly)
1540 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
1541 Order(Order), Comparator(Comparator) {}
1542
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.
1554class MemorySizePredicateMatcher : public InstructionPredicateMatcher {
1555protected:
1556 unsigned MMOIdx;
1557 uint64_t Size;
1558
1559public:
1560 MemorySizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx, unsigned Size)
1561 : InstructionPredicateMatcher(IPM_MemoryLLTSize, InsnVarID),
1562 MMOIdx(MMOIdx), Size(Size) {}
1563
1564 static bool classof(const PredicateMatcher *P) {
1565 return P->getKind() == IPM_MemoryLLTSize;
1566 }
1567 bool isIdentical(const PredicateMatcher &B) const override {
1568 return InstructionPredicateMatcher::isIdentical(B) &&
1569 MMOIdx == cast<MemorySizePredicateMatcher>(Val: &B)->MMOIdx &&
1570 Size == cast<MemorySizePredicateMatcher>(Val: &B)->Size;
1571 }
1572
1573 void emitPredicateOpcodes(MatchTable &Table,
1574 RuleMatcher &Rule) const override;
1575};
1576
1577class MemoryAddressSpacePredicateMatcher : public InstructionPredicateMatcher {
1578protected:
1579 unsigned MMOIdx;
1580 SmallVector<unsigned, 4> AddrSpaces;
1581
1582public:
1583 MemoryAddressSpacePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1584 ArrayRef<unsigned> AddrSpaces)
1585 : InstructionPredicateMatcher(IPM_MemoryAddressSpace, InsnVarID),
1586 MMOIdx(MMOIdx), AddrSpaces(AddrSpaces) {}
1587
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
1598class MemoryAlignmentPredicateMatcher : public InstructionPredicateMatcher {
1599protected:
1600 unsigned MMOIdx;
1601 int MinAlign;
1602
1603public:
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
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.
1623class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher {
1624public:
1625 enum RelationKind {
1626 GreaterThan,
1627 EqualTo,
1628 LessThan,
1629 };
1630
1631protected:
1632 unsigned MMOIdx;
1633 RelationKind Relation;
1634 unsigned OpIdx;
1635
1636public:
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
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
1652class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher {
1653public:
1654 enum SplatKind { AllZeros, AllOnes };
1655
1656private:
1657 SplatKind Kind;
1658
1659public:
1660 VectorSplatImmPredicateMatcher(unsigned InsnVarID, SplatKind K)
1661 : InstructionPredicateMatcher(IPM_VectorSplatImm, InsnVarID), Kind(K) {}
1662
1663 static bool classof(const PredicateMatcher *P) {
1664 return P->getKind() == IPM_VectorSplatImm;
1665 }
1666
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.
1677class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
1678protected:
1679 std::string EnumVal;
1680
1681public:
1682 GenericInstructionPredicateMatcher(unsigned InsnVarID,
1683 TreePredicateFn Predicate);
1684
1685 GenericInstructionPredicateMatcher(unsigned InsnVarID,
1686 const std::string &EnumVal)
1687 : InstructionPredicateMatcher(IPM_GenericPredicate, InsnVarID),
1688 EnumVal(EnumVal) {}
1689
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
1698class MIFlagsInstructionPredicateMatcher : public InstructionPredicateMatcher {
1699 SmallVector<StringRef, 2> Flags;
1700 bool CheckNot; // false = GIM_MIFlags, true = GIM_MIFlagsNot
1701
1702public:
1703 MIFlagsInstructionPredicateMatcher(unsigned InsnVarID,
1704 ArrayRef<StringRef> FlagsToCheck,
1705 bool CheckNot = false)
1706 : InstructionPredicateMatcher(IPM_MIFlags, InsnVarID),
1707 Flags(FlagsToCheck), CheckNot(CheckNot) {
1708 sort(C&: Flags);
1709 }
1710
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.
1722class NoUsePredicateMatcher : public InstructionPredicateMatcher {
1723public:
1724 NoUsePredicateMatcher(unsigned InsnVarID)
1725 : InstructionPredicateMatcher(IPM_NoUse, InsnVarID) {}
1726
1727 static bool classof(const PredicateMatcher *P) {
1728 return P->getKind() == IPM_NoUse;
1729 }
1730
1731 bool isIdentical(const PredicateMatcher &B) const override {
1732 return InstructionPredicateMatcher::isIdentical(B);
1733 }
1734
1735 void emitPredicateOpcodes(MatchTable &Table,
1736 RuleMatcher &Rule) const override {
1737 Table << MatchTable::Opcode(Opcode: "GIM_CheckHasNoUse")
1738 << MatchTable::Comment(Comment: "MI") << MatchTable::ULEB128Value(IntValue: InsnVarID)
1739 << MatchTable::LineBreak;
1740 }
1741};
1742
1743/// Generates code to check that the first result has only one use.
1744class OneUsePredicateMatcher : public InstructionPredicateMatcher {
1745public:
1746 OneUsePredicateMatcher(unsigned InsnVarID)
1747 : InstructionPredicateMatcher(IPM_OneUse, InsnVarID) {}
1748
1749 static bool classof(const PredicateMatcher *P) {
1750 return P->getKind() == IPM_OneUse;
1751 }
1752
1753 bool isIdentical(const PredicateMatcher &B) const override {
1754 return InstructionPredicateMatcher::isIdentical(B);
1755 }
1756
1757 void emitPredicateOpcodes(MatchTable &Table,
1758 RuleMatcher &Rule) const override {
1759 Table << MatchTable::Opcode(Opcode: "GIM_CheckHasOneUse")
1760 << MatchTable::Comment(Comment: "MI") << MatchTable::ULEB128Value(IntValue: 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.
1771class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
1772protected:
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
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(Range: Predicates, P: [&](const auto &P) {
1791 return P->getKind() ==
1792 InstructionPredicateMatcher::IPM_NumOperands;
1793 });
1794 }
1795
1796public:
1797 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
1798 bool AllowNumOpsCheck = true)
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(Matcher&: *this);
1804 }
1805
1806 /// Construct a new instruction predicate and add it to the matcher.
1807 template <class Kind, class... 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
1814 RuleMatcher &getRuleMatcher() const { return Rule; }
1815
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
1826 StringRef getSymbolicName() const { return SymbolicName; }
1827
1828 unsigned getNumOperandMatchers() const { return Operands.size(); }
1829 bool hasVariadicMatcher() const {
1830 return !Operands.empty() && Operands.back()->isVariadic();
1831 }
1832
1833 OperandVec::iterator operands_begin() { return Operands.begin(); }
1834 OperandVec::iterator operands_end() { return Operands.end(); }
1835 iterator_range<OperandVec::iterator> operands() {
1836 return make_range(x: operands_begin(), y: operands_end());
1837 }
1838 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1839 OperandVec::const_iterator operands_end() const { return Operands.end(); }
1840 iterator_range<OperandVec::const_iterator> operands() const {
1841 return make_range(x: operands_begin(), y: operands_end());
1842 }
1843 bool operands_empty() const { return Operands.empty(); }
1844
1845 void pop_front() { Operands.erase(position: 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
1862 InstructionOpcodeMatcher &getOpcodeMatcher() {
1863 for (auto &P : predicates())
1864 if (auto *OpMatcher = dyn_cast<InstructionOpcodeMatcher>(Val: P.get()))
1865 return *OpMatcher;
1866 llvm_unreachable("Didn't find an opcode matcher");
1867 }
1868
1869 bool isConstantInstruction() {
1870 return getOpcodeMatcher().isConstantInstruction();
1871 }
1872
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.
1885class InstructionOperandMatcher : public OperandPredicateMatcher {
1886protected:
1887 std::unique_ptr<InstructionMatcher> InsnMatcher;
1888
1889 GISelFlags Flags;
1890
1891public:
1892 InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1893 RuleMatcher &Rule, StringRef SymbolicName,
1894 bool AllowNumOpsCheck = true)
1895 : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
1896 InsnMatcher(
1897 new InstructionMatcher(Rule, SymbolicName, AllowNumOpsCheck)),
1898 Flags(Rule.getGISelFlags()) {}
1899
1900 static bool classof(const PredicateMatcher *P) {
1901 return P->getKind() == OPM_Instruction;
1902 }
1903
1904 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1905
1906 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const;
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.
1917 unsigned countRendererFns() const override {
1918 return InsnMatcher->countRendererFns();
1919 }
1920};
1921
1922//===- Actions ------------------------------------------------------------===//
1923class OperandRenderer {
1924public:
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
1942protected:
1943 RendererKind Kind;
1944
1945public:
1946 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1947 virtual ~OperandRenderer();
1948
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.
1957class CopyRenderer : public OperandRenderer {
1958protected:
1959 unsigned NewInsnID;
1960 /// The name of the operand.
1961 const StringRef SymbolicName;
1962
1963public:
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
1970 static bool classof(const OperandRenderer *R) {
1971 return R->getKind() == OR_Copy;
1972 }
1973
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.
1986class CopyPhysRegRenderer : public OperandRenderer {
1987protected:
1988 unsigned NewInsnID;
1989 const Record *PhysReg;
1990
1991public:
1992 CopyPhysRegRenderer(unsigned NewInsnID, const Record *Reg)
1993 : OperandRenderer(OR_CopyPhysReg), NewInsnID(NewInsnID), PhysReg(Reg) {
1994 assert(PhysReg);
1995 }
1996
1997 static bool classof(const OperandRenderer *R) {
1998 return R->getKind() == OR_CopyPhysReg;
1999 }
2000
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.
2009class CopyOrAddZeroRegRenderer : public OperandRenderer {
2010protected:
2011 unsigned NewInsnID;
2012 /// The name of the operand.
2013 const StringRef SymbolicName;
2014 const Record *ZeroRegisterDef;
2015
2016public:
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
2024 static bool classof(const OperandRenderer *R) {
2025 return R->getKind() == OR_CopyOrAddZeroReg;
2026 }
2027
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.
2035class CopyConstantAsImmRenderer : public OperandRenderer {
2036protected:
2037 unsigned NewInsnID;
2038 /// The name of the operand.
2039 const std::string SymbolicName;
2040 bool Signed = true;
2041
2042public:
2043 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2044 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
2045 SymbolicName(SymbolicName) {}
2046
2047 static bool classof(const OperandRenderer *R) {
2048 return R->getKind() == OR_CopyConstantAsImm;
2049 }
2050
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.
2058class CopyFConstantAsFPImmRenderer : public OperandRenderer {
2059protected:
2060 unsigned NewInsnID;
2061 /// The name of the operand.
2062 const std::string SymbolicName;
2063
2064public:
2065 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2066 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
2067 SymbolicName(SymbolicName) {}
2068
2069 static bool classof(const OperandRenderer *R) {
2070 return R->getKind() == OR_CopyFConstantAsFPImm;
2071 }
2072
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.
2081class CopySubRegRenderer : public OperandRenderer {
2082protected:
2083 unsigned NewInsnID;
2084 /// The name of the operand.
2085 const StringRef SymbolicName;
2086 /// The subregister to extract.
2087 const CodeGenSubRegIndex *SubReg;
2088
2089public:
2090 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
2091 const CodeGenSubRegIndex *SubReg)
2092 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
2093 SymbolicName(SymbolicName), SubReg(SubReg) {}
2094
2095 static bool classof(const OperandRenderer *R) {
2096 return R->getKind() == OR_CopySubReg;
2097 }
2098
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.
2106class AddRegisterRenderer : public OperandRenderer {
2107protected:
2108 unsigned InsnID;
2109 const Record *RegisterDef;
2110 bool IsDef;
2111 bool IsDead;
2112 const CodeGenTarget &Target;
2113
2114public:
2115 AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
2116 const Record *RegisterDef, bool IsDef = false,
2117 bool IsDead = false)
2118 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef),
2119 IsDef(IsDef), IsDead(IsDead), Target(Target) {}
2120
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.
2131class TempRegRenderer : public OperandRenderer {
2132protected:
2133 unsigned InsnID;
2134 unsigned TempRegID;
2135 const CodeGenSubRegIndex *SubRegIdx;
2136 bool IsDef;
2137 bool IsDead;
2138
2139public:
2140 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false,
2141 const CodeGenSubRegIndex *SubReg = nullptr,
2142 bool IsDead = false)
2143 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
2144 SubRegIdx(SubReg), IsDef(IsDef), IsDead(IsDead) {}
2145
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.
2155class ImmRenderer : public OperandRenderer {
2156protected:
2157 unsigned InsnID;
2158 int64_t Imm;
2159 std::optional<LLTCodeGenOrTempType> CImmLLT;
2160
2161public:
2162 ImmRenderer(unsigned InsnID, int64_t Imm)
2163 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
2164
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(x: CImmLLT.getLLTCodeGen());
2169 }
2170
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.
2182class SubRegIndexRenderer : public OperandRenderer {
2183protected:
2184 unsigned InsnID;
2185 const CodeGenSubRegIndex *SubRegIdx;
2186
2187public:
2188 SubRegIndexRenderer(unsigned InsnID, const CodeGenSubRegIndex *SRI)
2189 : OperandRenderer(OR_SubRegIndex), InsnID(InsnID), SubRegIdx(SRI) {}
2190
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.
2200class RenderComplexPatternOperand : public OperandRenderer {
2201private:
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
2215 unsigned getNumOperands() const {
2216 return TheDef.getValueAsDag(FieldName: "Operands")->getNumArgs();
2217 }
2218
2219public:
2220 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
2221 StringRef SymbolicName, unsigned RendererID,
2222 std::optional<unsigned> SubOperand = std::nullopt,
2223 const CodeGenSubRegIndex *SubReg = nullptr)
2224 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
2225 SymbolicName(SymbolicName), RendererID(RendererID),
2226 SubOperand(SubOperand), SubReg(SubReg) {}
2227
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.
2236class IntrinsicIDRenderer : public OperandRenderer {
2237protected:
2238 unsigned InsnID;
2239 const CodeGenIntrinsic *II;
2240
2241public:
2242 IntrinsicIDRenderer(unsigned InsnID, const CodeGenIntrinsic *II)
2243 : OperandRenderer(OR_Intrinsic), InsnID(InsnID), II(II) {}
2244
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
2252class CustomRenderer : public OperandRenderer {
2253protected:
2254 unsigned InsnID;
2255 const Record &Renderer;
2256 /// The name of the operand.
2257 const std::string SymbolicName;
2258
2259public:
2260 CustomRenderer(unsigned InsnID, const Record &Renderer,
2261 StringRef SymbolicName)
2262 : OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer),
2263 SymbolicName(SymbolicName) {}
2264
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
2272class CustomOperandRenderer : public OperandRenderer {
2273protected:
2274 unsigned InsnID;
2275 const Record &Renderer;
2276 /// The name of the operand.
2277 const std::string SymbolicName;
2278
2279public:
2280 CustomOperandRenderer(unsigned InsnID, const Record &Renderer,
2281 StringRef SymbolicName)
2282 : OperandRenderer(OR_CustomOperand), InsnID(InsnID), Renderer(Renderer),
2283 SymbolicName(SymbolicName) {}
2284
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.
2297class MatchAction {
2298public:
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
2310 MatchAction(ActionKind K) : Kind(K) {}
2311
2312 ActionKind getKind() const { return Kind; }
2313
2314 virtual ~MatchAction() {}
2315
2316 // Some actions may need to add extra predicates to ensure they can run.
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.
2327 virtual bool emitActionOpcodesAndDone(MatchTable &Table,
2328 RuleMatcher &Rule) const {
2329 emitActionOpcodes(Table, Rule);
2330 return false;
2331 }
2332
2333private:
2334 ActionKind Kind;
2335};
2336
2337/// Generates a comment describing the matched rule being acted upon.
2338class DebugCommentAction : public MatchAction {
2339private:
2340 std::string S;
2341
2342public:
2343 DebugCommentAction(StringRef S) : MatchAction(AK_DebugComment), S(S.str()) {}
2344
2345 static bool classof(const MatchAction *A) {
2346 return A->getKind() == AK_DebugComment;
2347 }
2348
2349 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2350 Table << MatchTable::Comment(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.
2356class BuildMIAction : public MatchAction {
2357private:
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
2371public:
2372 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
2373 : MatchAction(AK_BuildMI), InsnID(InsnID), I(I) {}
2374
2375 static bool classof(const MatchAction *A) {
2376 return A->getKind() == AK_BuildMI;
2377 }
2378
2379 unsigned getInsnID() const { return InsnID; }
2380 const CodeGenInstruction *getCGI() const { return I; }
2381
2382 void addSetMIFlags(StringRef Flag) { SetFlags.push_back(x: Flag); }
2383 void addUnsetMIFlags(StringRef Flag) { UnsetFlags.push_back(x: Flag); }
2384 void addCopiedMIFlags(const InstructionMatcher &IM) {
2385 CopiedFlags.push_back(x: &IM);
2386 }
2387
2388 void chooseInsnToMutate(RuleMatcher &Rule);
2389
2390 void setDeadImplicitDef(const Record *R) { DeadImplicitDefs.insert(Ptr: R); }
2391
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.
2404class BuildConstantAction : public MatchAction {
2405 unsigned TempRegID;
2406 int64_t Val;
2407
2408public:
2409 BuildConstantAction(unsigned TempRegID, int64_t Val)
2410 : MatchAction(AK_BuildConstantMI), TempRegID(TempRegID), Val(Val) {}
2411
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
2419class EraseInstAction : public MatchAction {
2420 unsigned InsnID;
2421
2422public:
2423 EraseInstAction(unsigned InsnID)
2424 : MatchAction(AK_EraseInst), InsnID(InsnID) {}
2425
2426 unsigned getInsnID() const { return InsnID; }
2427
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
2437class ReplaceRegAction : public MatchAction {
2438 unsigned OldInsnID, OldOpIdx;
2439 unsigned NewInsnId = -1, NewOpIdx;
2440 unsigned TempRegID = -1;
2441
2442public:
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
2448 ReplaceRegAction(unsigned OldInsnID, unsigned OldOpIdx, unsigned TempRegID)
2449 : MatchAction(AK_ReplaceReg), OldInsnID(OldInsnID), OldOpIdx(OldOpIdx),
2450 TempRegID(TempRegID) {}
2451
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.
2463class ConstrainOperandsToDefinitionAction : public MatchAction {
2464 unsigned InsnID;
2465
2466public:
2467 ConstrainOperandsToDefinitionAction(unsigned InsnID)
2468 : MatchAction(AK_ConstraintOpsToDef), InsnID(InsnID) {}
2469
2470 static bool classof(const MatchAction *A) {
2471 return A->getKind() == AK_ConstraintOpsToDef;
2472 }
2473
2474 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2475 if (InsnID == 0) {
2476 Table << MatchTable::Opcode(Opcode: "GIR_RootConstrainSelectedInstOperands")
2477 << MatchTable::LineBreak;
2478 } else {
2479 Table << MatchTable::Opcode(Opcode: "GIR_ConstrainSelectedInstOperands")
2480 << MatchTable::Comment(Comment: "InsnID") << MatchTable::ULEB128Value(IntValue: 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.
2488class ConstrainOperandToRegClassAction : public MatchAction {
2489 unsigned InsnID;
2490 unsigned OpIdx;
2491 const CodeGenRegisterClass &RC;
2492
2493public:
2494 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
2495 const CodeGenRegisterClass &RC)
2496 : MatchAction(AK_ConstraintOpsToRC), InsnID(InsnID), OpIdx(OpIdx),
2497 RC(RC) {}
2498
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.
2508class MakeTempRegisterAction : public MatchAction {
2509private:
2510 LLTCodeGenOrTempType Ty;
2511 unsigned TempRegID;
2512
2513public:
2514 MakeTempRegisterAction(const LLTCodeGenOrTempType &Ty, unsigned TempRegID)
2515 : MatchAction(AK_MakeTempReg), Ty(Ty), TempRegID(TempRegID) {
2516 if (Ty.isLLTCodeGen())
2517 KnownTypes.insert(x: Ty.getLLTCodeGen());
2518 }
2519
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