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