[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / utils / TableGen / Common / GlobalISel / GlobalISelMatchTable.h
blob00fe073057c5c95e00f4d8b20b2bcf6e235447f7
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 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H
17 #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H
19 #include "Common/CodeGenDAGPatterns.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/CodeGenTypes/LowLevelType.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/SaveAndRestore.h"
28 #include <deque>
29 #include <list>
30 #include <map>
31 #include <memory>
32 #include <optional>
33 #include <set>
34 #include <string>
35 #include <vector>
37 namespace llvm {
39 class raw_ostream;
40 class Record;
41 class SMLoc;
42 class CodeGenRegisterClass;
44 // Use a namespace to avoid conflicts because there's some fairly generic names
45 // in there (e.g. Matcher).
46 namespace gi {
47 class MatchTable;
48 class Matcher;
49 class OperandMatcher;
50 class MatchAction;
51 class PredicateMatcher;
52 class InstructionMatcher;
54 enum {
55 GISF_IgnoreCopies = 0x1,
58 using GISelFlags = std::uint32_t;
60 //===- Helper functions ---------------------------------------------------===//
62 void emitEncodingMacrosDef(raw_ostream &OS);
63 void emitEncodingMacrosUndef(raw_ostream &OS);
65 std::string getNameForFeatureBitset(ArrayRef<const Record *> FeatureBitset,
66 int HwModeIdx);
68 /// Takes a sequence of \p Rules and group them based on the predicates
69 /// they share. \p MatcherStorage is used as a memory container
70 /// for the group that are created as part of this process.
71 ///
72 /// What this optimization does looks like if GroupT = GroupMatcher:
73 /// Output without optimization:
74 /// \verbatim
75 /// # R1
76 /// # predicate A
77 /// # predicate B
78 /// ...
79 /// # R2
80 /// # predicate A // <-- effectively this is going to be checked twice.
81 /// // Once in R1 and once in R2.
82 /// # predicate C
83 /// \endverbatim
84 /// Output with optimization:
85 /// \verbatim
86 /// # Group1_2
87 /// # predicate A // <-- Check is now shared.
88 /// # R1
89 /// # predicate B
90 /// # R2
91 /// # predicate C
92 /// \endverbatim
93 template <class GroupT>
94 std::vector<Matcher *>
95 optimizeRules(ArrayRef<Matcher *> Rules,
96 std::vector<std::unique_ptr<Matcher>> &MatcherStorage);
98 /// A record to be stored in a MatchTable.
99 ///
100 /// This class represents any and all output that may be required to emit the
101 /// MatchTable. Instances are most often configured to represent an opcode or
102 /// value that will be emitted to the table with some formatting but it can also
103 /// represent commas, comments, and other formatting instructions.
104 struct MatchTableRecord {
105 enum RecordFlagsBits {
106 MTRF_None = 0x0,
107 /// Causes EmitStr to be formatted as comment when emitted.
108 MTRF_Comment = 0x1,
109 /// Causes the record value to be followed by a comma when emitted.
110 MTRF_CommaFollows = 0x2,
111 /// Causes the record value to be followed by a line break when emitted.
112 MTRF_LineBreakFollows = 0x4,
113 /// Indicates that the record defines a label and causes an additional
114 /// comment to be emitted containing the index of the label.
115 MTRF_Label = 0x8,
116 /// Causes the record to be emitted as the index of the label specified by
117 /// LabelID along with a comment indicating where that label is.
118 MTRF_JumpTarget = 0x10,
119 /// Causes the formatter to add a level of indentation before emitting the
120 /// record.
121 MTRF_Indent = 0x20,
122 /// Causes the formatter to remove a level of indentation after emitting the
123 /// record.
124 MTRF_Outdent = 0x40,
125 /// Causes the formatter to not use encoding macros to emit this multi-byte
126 /// value.
127 MTRF_PreEncoded = 0x80,
130 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
131 /// reference or define.
132 unsigned LabelID;
133 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
134 /// value, a label name.
135 std::string EmitStr;
137 private:
138 /// The number of MatchTable elements described by this record. Comments are 0
139 /// while values are typically 1. Values >1 may occur when we need to emit
140 /// values that exceed the size of a MatchTable element.
141 unsigned NumElements;
143 public:
144 /// A bitfield of RecordFlagsBits flags.
145 unsigned Flags;
147 /// The actual run-time value, if known
148 int64_t RawValue;
150 MatchTableRecord(std::optional<unsigned> LabelID_, StringRef EmitStr,
151 unsigned NumElements, unsigned Flags,
152 int64_t RawValue = std::numeric_limits<int64_t>::min())
153 : LabelID(LabelID_.value_or(~0u)), EmitStr(EmitStr),
154 NumElements(NumElements), Flags(Flags), RawValue(RawValue) {
155 assert((!LabelID_ || LabelID != ~0u) &&
156 "This value is reserved for non-labels");
158 MatchTableRecord(const MatchTableRecord &Other) = default;
159 MatchTableRecord(MatchTableRecord &&Other) = default;
161 /// Useful if a Match Table Record gets optimized out
162 void turnIntoComment() {
163 Flags |= MTRF_Comment;
164 Flags &= ~MTRF_CommaFollows;
165 NumElements = 0;
168 /// For Jump Table generation purposes
169 bool operator<(const MatchTableRecord &Other) const {
170 return RawValue < Other.RawValue;
172 int64_t getRawValue() const { return RawValue; }
174 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
175 const MatchTable &Table) const;
176 unsigned size() const { return NumElements; }
179 /// Holds the contents of a generated MatchTable to enable formatting and the
180 /// necessary index tracking needed to support GIM_Try.
181 class MatchTable {
182 /// An unique identifier for the table. The generated table will be named
183 /// MatchTable${ID}.
184 unsigned ID;
185 /// The records that make up the table. Also includes comments describing the
186 /// values being emitted and line breaks to format it.
187 std::vector<MatchTableRecord> Contents;
188 /// The currently defined labels.
189 DenseMap<unsigned, unsigned> LabelMap;
190 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
191 unsigned CurrentSize = 0;
192 /// A unique identifier for a MatchTable label.
193 unsigned CurrentLabelID = 0;
194 /// Determines if the table should be instrumented for rule coverage tracking.
195 bool IsWithCoverage;
196 /// Whether this table is for the GISel combiner.
197 bool IsCombinerTable;
199 public:
200 static MatchTableRecord LineBreak;
201 static MatchTableRecord Comment(StringRef Comment);
202 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0);
203 static MatchTableRecord NamedValue(unsigned NumBytes, StringRef NamedValue);
204 static MatchTableRecord NamedValue(unsigned NumBytes, StringRef NamedValue,
205 int64_t RawValue);
206 static MatchTableRecord NamedValue(unsigned NumBytes, StringRef Namespace,
207 StringRef NamedValue);
208 static MatchTableRecord NamedValue(unsigned NumBytes, StringRef Namespace,
209 StringRef NamedValue, int64_t RawValue);
210 static MatchTableRecord IntValue(unsigned NumBytes, int64_t IntValue);
211 static MatchTableRecord ULEB128Value(uint64_t IntValue);
212 static MatchTableRecord Label(unsigned LabelID);
213 static MatchTableRecord JumpTarget(unsigned LabelID);
215 static MatchTable buildTable(ArrayRef<Matcher *> Rules, bool WithCoverage,
216 bool IsCombiner = false);
218 MatchTable(bool WithCoverage, bool IsCombinerTable, unsigned ID = 0)
219 : ID(ID), IsWithCoverage(WithCoverage), IsCombinerTable(IsCombinerTable) {
222 bool isWithCoverage() const { return IsWithCoverage; }
223 bool isCombiner() const { return IsCombinerTable; }
225 void push_back(const MatchTableRecord &Value) {
226 if (Value.Flags & MatchTableRecord::MTRF_Label)
227 defineLabel(Value.LabelID);
228 Contents.push_back(Value);
229 CurrentSize += Value.size();
232 unsigned allocateLabelID() { return CurrentLabelID++; }
234 void defineLabel(unsigned LabelID) {
235 LabelMap.insert(std::pair(LabelID, CurrentSize));
238 unsigned getLabelIndex(unsigned LabelID) const {
239 const auto I = LabelMap.find(LabelID);
240 assert(I != LabelMap.end() && "Use of undeclared label");
241 return I->second;
244 void emitUse(raw_ostream &OS) const;
245 void emitDeclaration(raw_ostream &OS) const;
248 inline MatchTable &operator<<(MatchTable &Table,
249 const MatchTableRecord &Value) {
250 Table.push_back(Value);
251 return Table;
254 /// This class stands in for LLT wherever we want to tablegen-erate an
255 /// equivalent at compiler run-time.
256 class LLTCodeGen {
257 private:
258 LLT Ty;
260 public:
261 LLTCodeGen() = default;
262 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
264 std::string getCxxEnumValue() const;
266 void emitCxxEnumValue(raw_ostream &OS) const;
267 void emitCxxConstructorCall(raw_ostream &OS) const;
269 const LLT &get() const { return Ty; }
271 /// This ordering is used for std::unique() and llvm::sort(). There's no
272 /// particular logic behind the order but either A < B or B < A must be
273 /// true if A != B.
274 bool operator<(const LLTCodeGen &Other) const;
275 bool operator==(const LLTCodeGen &B) const { return Ty == B.Ty; }
278 // Track all types that are used so we can emit the corresponding enum.
279 extern std::set<LLTCodeGen> KnownTypes;
281 /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
282 /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
283 std::optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT);
285 using TempTypeIdx = int64_t;
286 class LLTCodeGenOrTempType {
287 public:
288 LLTCodeGenOrTempType(const LLTCodeGen &LLT) : Data(LLT) {}
289 LLTCodeGenOrTempType(TempTypeIdx TempTy) : Data(TempTy) {}
291 bool isLLTCodeGen() const { return std::holds_alternative<LLTCodeGen>(Data); }
292 bool isTempTypeIdx() const {
293 return std::holds_alternative<TempTypeIdx>(Data);
296 const LLTCodeGen &getLLTCodeGen() const {
297 assert(isLLTCodeGen());
298 return std::get<LLTCodeGen>(Data);
301 TempTypeIdx getTempTypeIdx() const {
302 assert(isTempTypeIdx());
303 return std::get<TempTypeIdx>(Data);
306 private:
307 std::variant<LLTCodeGen, TempTypeIdx> Data;
310 inline MatchTable &operator<<(MatchTable &Table,
311 const LLTCodeGenOrTempType &Ty) {
312 if (Ty.isLLTCodeGen())
313 Table << MatchTable::NamedValue(1, Ty.getLLTCodeGen().getCxxEnumValue());
314 else
315 Table << MatchTable::IntValue(1, Ty.getTempTypeIdx());
316 return Table;
319 //===- Matchers -----------------------------------------------------------===//
320 class Matcher {
321 public:
322 virtual ~Matcher();
323 virtual void optimize();
324 virtual void emit(MatchTable &Table) = 0;
326 virtual bool hasFirstCondition() const = 0;
327 virtual const PredicateMatcher &getFirstCondition() const = 0;
328 virtual std::unique_ptr<PredicateMatcher> popFirstCondition() = 0;
331 class GroupMatcher final : public Matcher {
332 /// Conditions that form a common prefix of all the matchers contained.
333 SmallVector<std::unique_ptr<PredicateMatcher>, 1> Conditions;
335 /// All the nested matchers, sharing a common prefix.
336 std::vector<Matcher *> Matchers;
338 /// An owning collection for any auxiliary matchers created while optimizing
339 /// nested matchers contained.
340 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
342 public:
343 /// Add a matcher to the collection of nested matchers if it meets the
344 /// requirements, and return true. If it doesn't, do nothing and return false.
346 /// Expected to preserve its argument, so it could be moved out later on.
347 bool addMatcher(Matcher &Candidate);
349 /// Mark the matcher as fully-built and ensure any invariants expected by both
350 /// optimize() and emit(...) methods. Generally, both sequences of calls
351 /// are expected to lead to a sensible result:
353 /// addMatcher(...)*; finalize(); optimize(); emit(...); and
354 /// addMatcher(...)*; finalize(); emit(...);
356 /// or generally
358 /// addMatcher(...)*; finalize(); { optimize()*; emit(...); }*
360 /// Multiple calls to optimize() are expected to be handled gracefully, though
361 /// optimize() is not expected to be idempotent. Multiple calls to finalize()
362 /// aren't generally supported. emit(...) is expected to be non-mutating and
363 /// producing the exact same results upon repeated calls.
365 /// addMatcher() calls after the finalize() call are not supported.
367 /// finalize() and optimize() are both allowed to mutate the contained
368 /// matchers, so moving them out after finalize() is not supported.
369 void finalize();
370 void optimize() override;
371 void emit(MatchTable &Table) override;
373 /// Could be used to move out the matchers added previously, unless finalize()
374 /// has been already called. If any of the matchers are moved out, the group
375 /// becomes safe to destroy, but not safe to re-use for anything else.
376 iterator_range<std::vector<Matcher *>::iterator> matchers() {
377 return make_range(Matchers.begin(), Matchers.end());
379 size_t size() const { return Matchers.size(); }
380 bool empty() const { return Matchers.empty(); }
382 std::unique_ptr<PredicateMatcher> popFirstCondition() override {
383 assert(!Conditions.empty() &&
384 "Trying to pop a condition from a condition-less group");
385 std::unique_ptr<PredicateMatcher> P = std::move(Conditions.front());
386 Conditions.erase(Conditions.begin());
387 return P;
389 const PredicateMatcher &getFirstCondition() const override {
390 assert(!Conditions.empty() &&
391 "Trying to get a condition from a condition-less group");
392 return *Conditions.front();
394 bool hasFirstCondition() const override { return !Conditions.empty(); }
396 private:
397 /// See if a candidate matcher could be added to this group solely by
398 /// analyzing its first condition.
399 bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
402 class SwitchMatcher : public Matcher {
403 /// All the nested matchers, representing distinct switch-cases. The first
404 /// conditions (as Matcher::getFirstCondition() reports) of all the nested
405 /// matchers must share the same type and path to a value they check, in other
406 /// words, be isIdenticalDownToValue, but have different values they check
407 /// against.
408 std::vector<Matcher *> Matchers;
410 /// The representative condition, with a type and a path (InsnVarID and OpIdx
411 /// in most cases) shared by all the matchers contained.
412 std::unique_ptr<PredicateMatcher> Condition = nullptr;
414 /// Temporary set used to check that the case values don't repeat within the
415 /// same switch.
416 std::set<MatchTableRecord> Values;
418 /// An owning collection for any auxiliary matchers created while optimizing
419 /// nested matchers contained.
420 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
422 public:
423 bool addMatcher(Matcher &Candidate);
425 void finalize();
426 void emit(MatchTable &Table) override;
428 iterator_range<std::vector<Matcher *>::iterator> matchers() {
429 return make_range(Matchers.begin(), Matchers.end());
431 size_t size() const { return Matchers.size(); }
432 bool empty() const { return Matchers.empty(); }
434 std::unique_ptr<PredicateMatcher> popFirstCondition() override {
435 // SwitchMatcher doesn't have a common first condition for its cases, as all
436 // the cases only share a kind of a value (a type and a path to it) they
437 // match, but deliberately differ in the actual value they match.
438 llvm_unreachable("Trying to pop a condition from a condition-less group");
441 const PredicateMatcher &getFirstCondition() const override {
442 llvm_unreachable("Trying to pop a condition from a condition-less group");
445 bool hasFirstCondition() const override { return false; }
447 private:
448 /// See if the predicate type has a Switch-implementation for it.
449 static bool isSupportedPredicateType(const PredicateMatcher &Predicate);
451 bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
453 /// emit()-helper
454 static void emitPredicateSpecificOpcodes(const PredicateMatcher &P,
455 MatchTable &Table);
458 /// Generates code to check that a match rule matches.
459 class RuleMatcher : public Matcher {
460 public:
461 using ActionList = std::list<std::unique_ptr<MatchAction>>;
462 using action_iterator = ActionList::iterator;
464 protected:
465 /// A list of matchers that all need to succeed for the current rule to match.
466 /// FIXME: This currently supports a single match position but could be
467 /// extended to support multiple positions to support div/rem fusion or
468 /// load-multiple instructions.
469 using MatchersTy = std::vector<std::unique_ptr<InstructionMatcher>>;
470 MatchersTy Matchers;
472 /// A list of actions that need to be taken when all predicates in this rule
473 /// have succeeded.
474 ActionList Actions;
476 /// Combiners can sometimes just run C++ code to finish matching a rule &
477 /// mutate instructions instead of relying on MatchActions. Empty if unused.
478 std::string CustomCXXAction;
480 using DefinedInsnVariablesMap = std::map<InstructionMatcher *, unsigned>;
482 /// A map of instruction matchers to the local variables
483 DefinedInsnVariablesMap InsnVariableIDs;
485 using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
487 // The set of instruction matchers that have not yet been claimed for mutation
488 // by a BuildMI.
489 MutatableInsnSet MutatableInsns;
491 /// A map of named operands defined by the matchers that may be referenced by
492 /// the renderers.
493 StringMap<OperandMatcher *> DefinedOperands;
495 /// A map of anonymous physical register operands defined by the matchers that
496 /// may be referenced by the renderers.
497 DenseMap<const Record *, OperandMatcher *> PhysRegOperands;
499 /// ID for the next instruction variable defined with
500 /// implicitlyDefineInsnVar()
501 unsigned NextInsnVarID;
503 /// ID for the next output instruction allocated with allocateOutputInsnID()
504 unsigned NextOutputInsnID;
506 /// ID for the next temporary register ID allocated with allocateTempRegID()
507 unsigned NextTempRegID;
509 /// ID for the next recorded type. Starts at -1 and counts down.
510 TempTypeIdx NextTempTypeIdx = -1;
512 // HwMode predicate index for this rule. -1 if no HwMode.
513 int HwModeIdx = -1;
515 /// Current GISelFlags
516 GISelFlags Flags = 0;
518 std::vector<std::string> RequiredSimplePredicates;
519 std::vector<const Record *> RequiredFeatures;
520 std::vector<std::unique_ptr<PredicateMatcher>> EpilogueMatchers;
522 DenseSet<unsigned> ErasedInsnIDs;
524 ArrayRef<SMLoc> SrcLoc;
526 typedef std::tuple<const Record *, unsigned, unsigned>
527 DefinedComplexPatternSubOperand;
528 typedef StringMap<DefinedComplexPatternSubOperand>
529 DefinedComplexPatternSubOperandMap;
530 /// A map of Symbolic Names to ComplexPattern sub-operands.
531 DefinedComplexPatternSubOperandMap ComplexSubOperands;
532 /// A map used to for multiple referenced error check of ComplexSubOperand.
533 /// ComplexSubOperand can't be referenced multiple from different operands,
534 /// however multiple references from same operand are allowed since that is
535 /// how 'same operand checks' are generated.
536 StringMap<std::string> ComplexSubOperandsParentName;
538 uint64_t RuleID;
539 static uint64_t NextRuleID;
541 GISelFlags updateGISelFlag(GISelFlags CurFlags, const Record *R,
542 StringRef FlagName, GISelFlags FlagBit);
544 public:
545 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
546 : NextInsnVarID(0), NextOutputInsnID(0), NextTempRegID(0), SrcLoc(SrcLoc),
547 RuleID(NextRuleID++) {}
548 RuleMatcher(RuleMatcher &&Other) = default;
549 RuleMatcher &operator=(RuleMatcher &&Other) = default;
551 TempTypeIdx getNextTempTypeIdx() { return NextTempTypeIdx--; }
553 uint64_t getRuleID() const { return RuleID; }
555 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
556 void addRequiredFeature(const Record *Feature) {
557 RequiredFeatures.push_back(Feature);
559 ArrayRef<const Record *> getRequiredFeatures() const {
560 return RequiredFeatures;
563 void addHwModeIdx(unsigned Idx) { HwModeIdx = Idx; }
564 int getHwModeIdx() const { return HwModeIdx; }
566 void addRequiredSimplePredicate(StringRef PredName);
567 const std::vector<std::string> &getRequiredSimplePredicates();
569 /// Attempts to mark \p ID as erased (GIR_EraseFromParent called on it).
570 /// If \p ID has already been erased, returns false and GIR_EraseFromParent
571 /// should NOT be emitted.
572 bool tryEraseInsnID(unsigned ID) { return ErasedInsnIDs.insert(ID).second; }
574 void setCustomCXXAction(StringRef FnEnumName) {
575 CustomCXXAction = FnEnumName.str();
578 // Emplaces an action of the specified Kind at the end of the action list.
580 // Returns a reference to the newly created action.
582 // Like std::vector::emplace_back(), may invalidate all iterators if the new
583 // size exceeds the capacity. Otherwise, only invalidates the past-the-end
584 // iterator.
585 template <class Kind, class... Args> Kind &addAction(Args &&...args) {
586 Actions.emplace_back(std::make_unique<Kind>(std::forward<Args>(args)...));
587 return *static_cast<Kind *>(Actions.back().get());
590 // Emplaces an action of the specified Kind before the given insertion point.
592 // Returns an iterator pointing at the newly created instruction.
594 // Like std::vector::insert(), may invalidate all iterators if the new size
595 // exceeds the capacity. Otherwise, only invalidates the iterators from the
596 // insertion point onwards.
597 template <class Kind, class... Args>
598 action_iterator insertAction(action_iterator InsertPt, Args &&...args) {
599 return Actions.emplace(InsertPt,
600 std::make_unique<Kind>(std::forward<Args>(args)...));
603 void setPermanentGISelFlags(GISelFlags V) { Flags = V; }
605 // Update the active GISelFlags based on the GISelFlags Record R.
606 // A SaveAndRestore object is returned so the old GISelFlags are restored
607 // at the end of the scope.
608 SaveAndRestore<GISelFlags> setGISelFlags(const Record *R);
609 GISelFlags getGISelFlags() const { return Flags; }
611 /// Define an instruction without emitting any code to do so.
612 unsigned implicitlyDefineInsnVar(InstructionMatcher &Matcher);
614 unsigned getInsnVarID(InstructionMatcher &InsnMatcher) const;
615 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
616 return InsnVariableIDs.begin();
618 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
619 return InsnVariableIDs.end();
621 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
622 defined_insn_vars() const {
623 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
626 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
627 return MutatableInsns.begin();
629 MutatableInsnSet::const_iterator mutatable_insns_end() const {
630 return MutatableInsns.end();
632 iterator_range<typename MutatableInsnSet::const_iterator>
633 mutatable_insns() const {
634 return make_range(mutatable_insns_begin(), mutatable_insns_end());
636 void reserveInsnMatcherForMutation(InstructionMatcher *InsnMatcher) {
637 bool R = MutatableInsns.erase(InsnMatcher);
638 assert(R && "Reserving a mutatable insn that isn't available");
639 (void)R;
642 action_iterator actions_begin() { return Actions.begin(); }
643 action_iterator actions_end() { return Actions.end(); }
644 iterator_range<action_iterator> actions() {
645 return make_range(actions_begin(), actions_end());
648 bool hasOperand(StringRef SymbolicName) const {
649 return DefinedOperands.contains(SymbolicName);
652 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
654 void definePhysRegOperand(const Record *Reg, OperandMatcher &OM);
656 Error defineComplexSubOperand(StringRef SymbolicName,
657 const Record *ComplexPattern,
658 unsigned RendererID, unsigned SubOperandID,
659 StringRef ParentSymbolicName);
661 std::optional<DefinedComplexPatternSubOperand>
662 getComplexSubOperand(StringRef SymbolicName) const {
663 const auto &I = ComplexSubOperands.find(SymbolicName);
664 if (I == ComplexSubOperands.end())
665 return std::nullopt;
666 return I->second;
669 InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
670 OperandMatcher &getOperandMatcher(StringRef Name);
671 const OperandMatcher &getOperandMatcher(StringRef Name) const;
672 const OperandMatcher &getPhysRegOperandMatcher(const Record *) const;
674 void optimize() override;
675 void emit(MatchTable &Table) override;
677 /// Compare the priority of this object and B.
679 /// Returns true if this object is more important than B.
680 bool isHigherPriorityThan(const RuleMatcher &B) const;
682 /// Report the maximum number of temporary operands needed by the rule
683 /// matcher.
684 unsigned countRendererFns() const;
686 std::unique_ptr<PredicateMatcher> popFirstCondition() override;
687 const PredicateMatcher &getFirstCondition() const override;
688 LLTCodeGen getFirstConditionAsRootType();
689 bool hasFirstCondition() const override;
690 StringRef getOpcode() const;
692 // FIXME: Remove this as soon as possible
693 InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
695 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
696 unsigned allocateTempRegID() { return NextTempRegID++; }
698 iterator_range<MatchersTy::iterator> insnmatchers() {
699 return make_range(Matchers.begin(), Matchers.end());
701 bool insnmatchers_empty() const { return Matchers.empty(); }
702 void insnmatchers_pop_front() { Matchers.erase(Matchers.begin()); }
705 template <class PredicateTy> class PredicateListMatcher {
706 private:
707 /// Template instantiations should specialize this to return a string to use
708 /// for the comment emitted when there are no predicates.
709 std::string getNoPredicateComment() const;
711 protected:
712 using PredicatesTy = std::deque<std::unique_ptr<PredicateTy>>;
713 PredicatesTy Predicates;
715 /// Track if the list of predicates was manipulated by one of the optimization
716 /// methods.
717 bool Optimized = false;
719 public:
720 typename PredicatesTy::iterator predicates_begin() {
721 return Predicates.begin();
723 typename PredicatesTy::iterator predicates_end() { return Predicates.end(); }
724 iterator_range<typename PredicatesTy::iterator> predicates() {
725 return make_range(predicates_begin(), predicates_end());
727 typename PredicatesTy::size_type predicates_size() const {
728 return Predicates.size();
730 bool predicates_empty() const { return Predicates.empty(); }
732 template <typename Ty> bool contains() const {
733 return any_of(Predicates, [&](auto &P) { return isa<Ty>(P.get()); });
736 std::unique_ptr<PredicateTy> predicates_pop_front() {
737 std::unique_ptr<PredicateTy> Front = std::move(Predicates.front());
738 Predicates.pop_front();
739 Optimized = true;
740 return Front;
743 void prependPredicate(std::unique_ptr<PredicateTy> &&Predicate) {
744 Predicates.push_front(std::move(Predicate));
747 void eraseNullPredicates() {
748 const auto NewEnd =
749 std::stable_partition(Predicates.begin(), Predicates.end(),
750 std::logical_not<std::unique_ptr<PredicateTy>>());
751 if (NewEnd != Predicates.begin()) {
752 Predicates.erase(Predicates.begin(), NewEnd);
753 Optimized = true;
757 /// Emit MatchTable opcodes that tests whether all the predicates are met.
758 template <class... Args>
759 void emitPredicateListOpcodes(MatchTable &Table, Args &&...args) {
760 if (Predicates.empty() && !Optimized) {
761 Table << MatchTable::Comment(getNoPredicateComment())
762 << MatchTable::LineBreak;
763 return;
766 for (const auto &Predicate : predicates())
767 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
770 /// Provide a function to avoid emitting certain predicates. This is used to
771 /// defer some predicate checks until after others
772 using PredicateFilterFunc = std::function<bool(const PredicateTy &)>;
774 /// Emit MatchTable opcodes for predicates which satisfy \p
775 /// ShouldEmitPredicate. This should be called multiple times to ensure all
776 /// predicates are eventually added to the match table.
777 template <class... Args>
778 void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate,
779 MatchTable &Table, Args &&...args) {
780 if (Predicates.empty() && !Optimized) {
781 Table << MatchTable::Comment(getNoPredicateComment())
782 << MatchTable::LineBreak;
783 return;
786 for (const auto &Predicate : predicates()) {
787 if (ShouldEmitPredicate(*Predicate))
788 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
793 class PredicateMatcher {
794 public:
795 /// This enum is used for RTTI and also defines the priority that is given to
796 /// the predicate when generating the matcher code. Kinds with higher priority
797 /// must be tested first.
799 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
800 /// but OPM_Int must have priority over OPM_RegBank since constant integers
801 /// are represented by a virtual register defined by a G_CONSTANT instruction.
803 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
804 /// are currently not compared between each other.
805 enum PredicateKind {
806 IPM_Opcode,
807 IPM_NumOperands,
808 IPM_ImmPredicate,
809 IPM_Imm,
810 IPM_AtomicOrderingMMO,
811 IPM_MemoryLLTSize,
812 IPM_MemoryVsLLTSize,
813 IPM_MemoryAddressSpace,
814 IPM_MemoryAlignment,
815 IPM_VectorSplatImm,
816 IPM_NoUse,
817 IPM_OneUse,
818 IPM_GenericPredicate,
819 IPM_MIFlags,
820 OPM_SameOperand,
821 OPM_ComplexPattern,
822 OPM_IntrinsicID,
823 OPM_CmpPredicate,
824 OPM_Instruction,
825 OPM_Int,
826 OPM_LiteralInt,
827 OPM_LLT,
828 OPM_PointerToAny,
829 OPM_RegBank,
830 OPM_MBB,
831 OPM_RecordNamedOperand,
832 OPM_RecordRegType,
835 protected:
836 PredicateKind Kind;
837 unsigned InsnVarID;
838 unsigned OpIdx;
840 public:
841 PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
842 : Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
843 virtual ~PredicateMatcher();
845 unsigned getInsnVarID() const { return InsnVarID; }
846 unsigned getOpIdx() const { return OpIdx; }
848 /// Emit MatchTable opcodes that check the predicate for the given operand.
849 virtual void emitPredicateOpcodes(MatchTable &Table,
850 RuleMatcher &Rule) const = 0;
852 PredicateKind getKind() const { return Kind; }
854 bool dependsOnOperands() const {
855 // Custom predicates really depend on the context pattern of the
856 // instruction, not just the individual instruction. This therefore
857 // implicitly depends on all other pattern constraints.
858 return Kind == IPM_GenericPredicate;
861 virtual bool isIdentical(const PredicateMatcher &B) const {
862 return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
863 OpIdx == B.OpIdx;
866 virtual bool isIdenticalDownToValue(const PredicateMatcher &B) const {
867 return hasValue() && PredicateMatcher::isIdentical(B);
870 virtual MatchTableRecord getValue() const {
871 assert(hasValue() && "Can not get a value of a value-less predicate!");
872 llvm_unreachable("Not implemented yet");
874 virtual bool hasValue() const { return false; }
876 /// Report the maximum number of temporary operands needed by the predicate
877 /// matcher.
878 virtual unsigned countRendererFns() const { return 0; }
881 /// Generates code to check a predicate of an operand.
883 /// Typical predicates include:
884 /// * Operand is a particular register.
885 /// * Operand is assigned a particular register bank.
886 /// * Operand is an MBB.
887 class OperandPredicateMatcher : public PredicateMatcher {
888 public:
889 OperandPredicateMatcher(PredicateKind Kind, unsigned InsnVarID,
890 unsigned OpIdx)
891 : PredicateMatcher(Kind, InsnVarID, OpIdx) {}
892 virtual ~OperandPredicateMatcher();
894 /// Compare the priority of this object and B.
896 /// Returns true if this object is more important than B.
897 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
900 template <>
901 inline std::string
902 PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
903 return "No operand predicates";
906 /// Generates code to check that a register operand is defined by the same exact
907 /// one as another.
908 class SameOperandMatcher : public OperandPredicateMatcher {
909 std::string MatchingName;
910 unsigned OrigOpIdx;
912 GISelFlags Flags;
914 public:
915 SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName,
916 unsigned OrigOpIdx, GISelFlags Flags)
917 : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx),
918 MatchingName(MatchingName), OrigOpIdx(OrigOpIdx), Flags(Flags) {}
920 static bool classof(const PredicateMatcher *P) {
921 return P->getKind() == OPM_SameOperand;
924 void emitPredicateOpcodes(MatchTable &Table,
925 RuleMatcher &Rule) const override;
927 bool isIdentical(const PredicateMatcher &B) const override {
928 return OperandPredicateMatcher::isIdentical(B) &&
929 OrigOpIdx == cast<SameOperandMatcher>(&B)->OrigOpIdx &&
930 MatchingName == cast<SameOperandMatcher>(&B)->MatchingName;
934 /// Generates code to check that an operand is a particular LLT.
935 class LLTOperandMatcher : public OperandPredicateMatcher {
936 protected:
937 LLTCodeGen Ty;
939 public:
940 static std::map<LLTCodeGen, unsigned> TypeIDValues;
942 static void initTypeIDValuesMap() {
943 TypeIDValues.clear();
945 unsigned ID = 0;
946 for (const LLTCodeGen &LLTy : KnownTypes)
947 TypeIDValues[LLTy] = ID++;
950 LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty)
951 : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
952 KnownTypes.insert(Ty);
955 static bool classof(const PredicateMatcher *P) {
956 return P->getKind() == OPM_LLT;
959 bool isIdentical(const PredicateMatcher &B) const override {
960 return OperandPredicateMatcher::isIdentical(B) &&
961 Ty == cast<LLTOperandMatcher>(&B)->Ty;
964 MatchTableRecord getValue() const override;
965 bool hasValue() const override;
967 LLTCodeGen getTy() const { return Ty; }
969 void emitPredicateOpcodes(MatchTable &Table,
970 RuleMatcher &Rule) const override;
973 /// Generates code to check that an operand is a pointer to any address space.
975 /// In SelectionDAG, the types did not describe pointers or address spaces. As a
976 /// result, iN is used to describe a pointer of N bits to any address space and
977 /// PatFrag predicates are typically used to constrain the address space.
978 /// There's no reliable means to derive the missing type information from the
979 /// pattern so imported rules must test the components of a pointer separately.
981 /// If SizeInBits is zero, then the pointer size will be obtained from the
982 /// subtarget.
983 class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
984 protected:
985 unsigned SizeInBits;
987 public:
988 PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
989 unsigned SizeInBits)
990 : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
991 SizeInBits(SizeInBits) {}
993 static bool classof(const PredicateMatcher *P) {
994 return P->getKind() == OPM_PointerToAny;
997 bool isIdentical(const PredicateMatcher &B) const override {
998 return OperandPredicateMatcher::isIdentical(B) &&
999 SizeInBits == cast<PointerToAnyOperandMatcher>(&B)->SizeInBits;
1002 void emitPredicateOpcodes(MatchTable &Table,
1003 RuleMatcher &Rule) const override;
1006 /// Generates code to record named operand in RecordedOperands list at StoreIdx.
1007 /// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
1008 /// an argument to predicate's c++ code once all operands have been matched.
1009 class RecordNamedOperandMatcher : public OperandPredicateMatcher {
1010 protected:
1011 unsigned StoreIdx;
1012 std::string Name;
1014 public:
1015 RecordNamedOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1016 unsigned StoreIdx, StringRef Name)
1017 : OperandPredicateMatcher(OPM_RecordNamedOperand, InsnVarID, OpIdx),
1018 StoreIdx(StoreIdx), Name(Name) {}
1020 static bool classof(const PredicateMatcher *P) {
1021 return P->getKind() == OPM_RecordNamedOperand;
1024 bool isIdentical(const PredicateMatcher &B) const override {
1025 return OperandPredicateMatcher::isIdentical(B) &&
1026 StoreIdx == cast<RecordNamedOperandMatcher>(&B)->StoreIdx &&
1027 Name == cast<RecordNamedOperandMatcher>(&B)->Name;
1030 void emitPredicateOpcodes(MatchTable &Table,
1031 RuleMatcher &Rule) const override;
1034 /// Generates code to store a register operand's type into the set of temporary
1035 /// LLTs.
1036 class RecordRegisterType : public OperandPredicateMatcher {
1037 protected:
1038 TempTypeIdx Idx;
1040 public:
1041 RecordRegisterType(unsigned InsnVarID, unsigned OpIdx, TempTypeIdx Idx)
1042 : OperandPredicateMatcher(OPM_RecordRegType, InsnVarID, OpIdx), Idx(Idx) {
1045 static bool classof(const PredicateMatcher *P) {
1046 return P->getKind() == OPM_RecordRegType;
1049 bool isIdentical(const PredicateMatcher &B) const override {
1050 return OperandPredicateMatcher::isIdentical(B) &&
1051 Idx == cast<RecordRegisterType>(&B)->Idx;
1054 void emitPredicateOpcodes(MatchTable &Table,
1055 RuleMatcher &Rule) const override;
1058 /// Generates code to check that an operand is a particular target constant.
1059 class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
1060 protected:
1061 const OperandMatcher &Operand;
1062 const Record &TheDef;
1064 unsigned getAllocatedTemporariesBaseID() const;
1066 public:
1067 bool isIdentical(const PredicateMatcher &B) const override { return false; }
1069 ComplexPatternOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1070 const OperandMatcher &Operand,
1071 const Record &TheDef)
1072 : OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx),
1073 Operand(Operand), TheDef(TheDef) {}
1075 static bool classof(const PredicateMatcher *P) {
1076 return P->getKind() == OPM_ComplexPattern;
1079 void emitPredicateOpcodes(MatchTable &Table,
1080 RuleMatcher &Rule) const override;
1081 unsigned countRendererFns() const override { return 1; }
1084 /// Generates code to check that an operand is in a particular register bank.
1085 class RegisterBankOperandMatcher : public OperandPredicateMatcher {
1086 protected:
1087 const CodeGenRegisterClass &RC;
1089 public:
1090 RegisterBankOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1091 const CodeGenRegisterClass &RC)
1092 : OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {}
1094 bool isIdentical(const PredicateMatcher &B) const override;
1096 static bool classof(const PredicateMatcher *P) {
1097 return P->getKind() == OPM_RegBank;
1100 void emitPredicateOpcodes(MatchTable &Table,
1101 RuleMatcher &Rule) const override;
1104 /// Generates code to check that an operand is a basic block.
1105 class MBBOperandMatcher : public OperandPredicateMatcher {
1106 public:
1107 MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1108 : OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
1110 static bool classof(const PredicateMatcher *P) {
1111 return P->getKind() == OPM_MBB;
1114 void emitPredicateOpcodes(MatchTable &Table,
1115 RuleMatcher &Rule) const override;
1118 class ImmOperandMatcher : public OperandPredicateMatcher {
1119 public:
1120 ImmOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1121 : OperandPredicateMatcher(IPM_Imm, InsnVarID, OpIdx) {}
1123 static bool classof(const PredicateMatcher *P) {
1124 return P->getKind() == IPM_Imm;
1127 void emitPredicateOpcodes(MatchTable &Table,
1128 RuleMatcher &Rule) const override;
1131 /// Generates code to check that an operand is a G_CONSTANT with a particular
1132 /// int.
1133 class ConstantIntOperandMatcher : public OperandPredicateMatcher {
1134 protected:
1135 int64_t Value;
1137 public:
1138 ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1139 : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {}
1141 bool isIdentical(const PredicateMatcher &B) const override {
1142 return OperandPredicateMatcher::isIdentical(B) &&
1143 Value == cast<ConstantIntOperandMatcher>(&B)->Value;
1146 static bool classof(const PredicateMatcher *P) {
1147 return P->getKind() == OPM_Int;
1150 void emitPredicateOpcodes(MatchTable &Table,
1151 RuleMatcher &Rule) const override;
1154 /// Generates code to check that an operand is a raw int (where MO.isImm() or
1155 /// MO.isCImm() is true).
1156 class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1157 protected:
1158 int64_t Value;
1160 public:
1161 LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
1162 : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
1163 Value(Value) {}
1165 bool isIdentical(const PredicateMatcher &B) const override {
1166 return OperandPredicateMatcher::isIdentical(B) &&
1167 Value == cast<LiteralIntOperandMatcher>(&B)->Value;
1170 static bool classof(const PredicateMatcher *P) {
1171 return P->getKind() == OPM_LiteralInt;
1174 void emitPredicateOpcodes(MatchTable &Table,
1175 RuleMatcher &Rule) const override;
1178 /// Generates code to check that an operand is an CmpInst predicate
1179 class CmpPredicateOperandMatcher : public OperandPredicateMatcher {
1180 protected:
1181 std::string PredName;
1183 public:
1184 CmpPredicateOperandMatcher(unsigned InsnVarID, unsigned OpIdx, std::string P)
1185 : OperandPredicateMatcher(OPM_CmpPredicate, InsnVarID, OpIdx),
1186 PredName(std::move(P)) {}
1188 bool isIdentical(const PredicateMatcher &B) const override {
1189 return OperandPredicateMatcher::isIdentical(B) &&
1190 PredName == cast<CmpPredicateOperandMatcher>(&B)->PredName;
1193 static bool classof(const PredicateMatcher *P) {
1194 return P->getKind() == OPM_CmpPredicate;
1197 void emitPredicateOpcodes(MatchTable &Table,
1198 RuleMatcher &Rule) const override;
1201 /// Generates code to check that an operand is an intrinsic ID.
1202 class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1203 protected:
1204 const CodeGenIntrinsic *II;
1206 public:
1207 IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1208 const CodeGenIntrinsic *II)
1209 : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
1211 bool isIdentical(const PredicateMatcher &B) const override {
1212 return OperandPredicateMatcher::isIdentical(B) &&
1213 II == cast<IntrinsicIDOperandMatcher>(&B)->II;
1216 static bool classof(const PredicateMatcher *P) {
1217 return P->getKind() == OPM_IntrinsicID;
1220 void emitPredicateOpcodes(MatchTable &Table,
1221 RuleMatcher &Rule) const override;
1224 /// Generates code to check that this operand is an immediate whose value meets
1225 /// an immediate predicate.
1226 class OperandImmPredicateMatcher : public OperandPredicateMatcher {
1227 protected:
1228 TreePredicateFn Predicate;
1230 public:
1231 OperandImmPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
1232 const TreePredicateFn &Predicate)
1233 : OperandPredicateMatcher(IPM_ImmPredicate, InsnVarID, OpIdx),
1234 Predicate(Predicate) {}
1236 bool isIdentical(const PredicateMatcher &B) const override {
1237 return OperandPredicateMatcher::isIdentical(B) &&
1238 Predicate.getOrigPatFragRecord() ==
1239 cast<OperandImmPredicateMatcher>(&B)
1240 ->Predicate.getOrigPatFragRecord();
1243 static bool classof(const PredicateMatcher *P) {
1244 return P->getKind() == IPM_ImmPredicate;
1247 void emitPredicateOpcodes(MatchTable &Table,
1248 RuleMatcher &Rule) const override;
1251 /// Generates code to check that a set of predicates match for a particular
1252 /// operand.
1253 class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1254 protected:
1255 InstructionMatcher &Insn;
1256 unsigned OpIdx;
1257 std::string SymbolicName;
1259 /// The index of the first temporary variable allocated to this operand. The
1260 /// number of allocated temporaries can be found with
1261 /// countRendererFns().
1262 unsigned AllocatedTemporariesBaseID;
1264 TempTypeIdx TTIdx = 0;
1266 // TODO: has many implications, figure them all out
1267 bool IsVariadic = false;
1269 public:
1270 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
1271 const std::string &SymbolicName,
1272 unsigned AllocatedTemporariesBaseID, bool IsVariadic = false)
1273 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1274 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID),
1275 IsVariadic(IsVariadic) {}
1277 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1278 StringRef getSymbolicName() const { return SymbolicName; }
1279 void setSymbolicName(StringRef Name) {
1280 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1281 SymbolicName = std::string(Name);
1284 /// Construct a new operand predicate and add it to the matcher.
1285 template <class Kind, class... Args>
1286 std::optional<Kind *> addPredicate(Args &&...args) {
1287 // TODO: Should variadic ops support predicates?
1288 if (isSameAsAnotherOperand() || IsVariadic)
1289 return std::nullopt;
1290 Predicates.emplace_back(std::make_unique<Kind>(
1291 getInsnVarID(), getOpIdx(), std::forward<Args>(args)...));
1292 return static_cast<Kind *>(Predicates.back().get());
1295 unsigned getOpIdx() const { return OpIdx; }
1296 unsigned getInsnVarID() const;
1298 bool isVariadic() const { return IsVariadic; }
1300 /// If this OperandMatcher has not been assigned a TempTypeIdx yet, assigns it
1301 /// one and adds a `RecordRegisterType` predicate to this matcher. If one has
1302 /// already been assigned, simply returns it.
1303 TempTypeIdx getTempTypeIdx(RuleMatcher &Rule);
1305 std::string getOperandExpr(unsigned InsnVarID) const;
1307 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1309 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1310 bool OperandIsAPointer);
1312 /// Emit MatchTable opcodes that test whether the instruction named in
1313 /// InsnVarID matches all the predicates and all the operands.
1314 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule);
1316 /// Compare the priority of this object and B.
1318 /// Returns true if this object is more important than B.
1319 bool isHigherPriorityThan(OperandMatcher &B);
1321 /// Report the maximum number of temporary operands needed by the operand
1322 /// matcher.
1323 unsigned countRendererFns();
1325 unsigned getAllocatedTemporariesBaseID() const {
1326 return AllocatedTemporariesBaseID;
1329 bool isSameAsAnotherOperand() {
1330 for (const auto &Predicate : predicates())
1331 if (isa<SameOperandMatcher>(Predicate))
1332 return true;
1333 return false;
1337 /// Generates code to check a predicate on an instruction.
1339 /// Typical predicates include:
1340 /// * The opcode of the instruction is a particular value.
1341 /// * The nsw/nuw flag is/isn't set.
1342 class InstructionPredicateMatcher : public PredicateMatcher {
1343 public:
1344 InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
1345 : PredicateMatcher(Kind, InsnVarID) {}
1346 virtual ~InstructionPredicateMatcher() {}
1348 /// Compare the priority of this object and B.
1350 /// Returns true if this object is more important than B.
1351 virtual bool
1352 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
1353 return Kind < B.Kind;
1357 template <>
1358 inline std::string
1359 PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
1360 return "No instruction predicates";
1363 /// Generates code to check the opcode of an instruction.
1364 class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1365 protected:
1366 // Allow matching one to several, similar opcodes that share properties. This
1367 // is to handle patterns where one SelectionDAG operation maps to multiple
1368 // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
1369 // is treated as the canonical opcode.
1370 SmallVector<const CodeGenInstruction *, 2> Insts;
1372 static DenseMap<const CodeGenInstruction *, unsigned> OpcodeValues;
1374 MatchTableRecord getInstValue(const CodeGenInstruction *I) const;
1376 public:
1377 static void initOpcodeValuesMap(const CodeGenTarget &Target);
1379 InstructionOpcodeMatcher(unsigned InsnVarID,
1380 ArrayRef<const CodeGenInstruction *> I)
1381 : InstructionPredicateMatcher(IPM_Opcode, InsnVarID), Insts(I) {
1382 assert((Insts.size() == 1 || Insts.size() == 2) &&
1383 "unexpected number of opcode alternatives");
1386 static bool classof(const PredicateMatcher *P) {
1387 return P->getKind() == IPM_Opcode;
1390 bool isIdentical(const PredicateMatcher &B) const override {
1391 return InstructionPredicateMatcher::isIdentical(B) &&
1392 Insts == cast<InstructionOpcodeMatcher>(&B)->Insts;
1395 bool hasValue() const override {
1396 return Insts.size() == 1 && OpcodeValues.count(Insts[0]);
1399 // TODO: This is used for the SwitchMatcher optimization. We should be able to
1400 // return a list of the opcodes to match.
1401 MatchTableRecord getValue() const override;
1403 void emitPredicateOpcodes(MatchTable &Table,
1404 RuleMatcher &Rule) const override;
1406 /// Compare the priority of this object and B.
1408 /// Returns true if this object is more important than B.
1409 bool
1410 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override;
1412 bool isConstantInstruction() const;
1414 // The first opcode is the canonical opcode, and later are alternatives.
1415 StringRef getOpcode() const;
1416 ArrayRef<const CodeGenInstruction *> getAlternativeOpcodes() { return Insts; }
1417 bool isVariadicNumOperands() const;
1418 StringRef getOperandType(unsigned OpIdx) const;
1421 class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher {
1422 public:
1423 enum class CheckKind { Eq, LE, GE };
1425 private:
1426 unsigned NumOperands = 0;
1427 CheckKind CK;
1429 public:
1430 InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands,
1431 CheckKind CK = CheckKind::Eq)
1432 : InstructionPredicateMatcher(IPM_NumOperands, InsnVarID),
1433 NumOperands(NumOperands), CK(CK) {}
1435 static bool classof(const PredicateMatcher *P) {
1436 return P->getKind() == IPM_NumOperands;
1439 bool isIdentical(const PredicateMatcher &B) const override {
1440 if (!InstructionPredicateMatcher::isIdentical(B))
1441 return false;
1442 const auto &Other = *cast<InstructionNumOperandsMatcher>(&B);
1443 return NumOperands == Other.NumOperands && CK == Other.CK;
1446 void emitPredicateOpcodes(MatchTable &Table,
1447 RuleMatcher &Rule) const override;
1450 /// Generates code to check that this instruction is a constant whose value
1451 /// meets an immediate predicate.
1453 /// Immediates are slightly odd since they are typically used like an operand
1454 /// but are represented as an operator internally. We typically write simm8:$src
1455 /// in a tablegen pattern, but this is just syntactic sugar for
1456 /// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1457 /// that will be matched and the predicate (which is attached to the imm
1458 /// operator) that will be tested. In SelectionDAG this describes a
1459 /// ConstantSDNode whose internal value will be tested using the simm8
1460 /// predicate.
1462 /// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1463 /// this representation, the immediate could be tested with an
1464 /// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1465 /// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1466 /// there are two implementation issues with producing that matcher
1467 /// configuration from the SelectionDAG pattern:
1468 /// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1469 /// were we to sink the immediate predicate to the operand we would have to
1470 /// have two partial implementations of PatFrag support, one for immediates
1471 /// and one for non-immediates.
1472 /// * At the point we handle the predicate, the OperandMatcher hasn't been
1473 /// created yet. If we were to sink the predicate to the OperandMatcher we
1474 /// would also have to complicate (or duplicate) the code that descends and
1475 /// creates matchers for the subtree.
1476 /// Overall, it's simpler to handle it in the place it was found.
1477 class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1478 protected:
1479 TreePredicateFn Predicate;
1481 public:
1482 InstructionImmPredicateMatcher(unsigned InsnVarID,
1483 const TreePredicateFn &Predicate)
1484 : InstructionPredicateMatcher(IPM_ImmPredicate, InsnVarID),
1485 Predicate(Predicate) {}
1487 bool isIdentical(const PredicateMatcher &B) const override;
1489 static bool classof(const PredicateMatcher *P) {
1490 return P->getKind() == IPM_ImmPredicate;
1493 void emitPredicateOpcodes(MatchTable &Table,
1494 RuleMatcher &Rule) const override;
1497 /// Generates code to check that a memory instruction has a atomic ordering
1498 /// MachineMemoryOperand.
1499 class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
1500 public:
1501 enum AOComparator {
1502 AO_Exactly,
1503 AO_OrStronger,
1504 AO_WeakerThan,
1507 protected:
1508 StringRef Order;
1509 AOComparator Comparator;
1511 public:
1512 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
1513 AOComparator Comparator = AO_Exactly)
1514 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
1515 Order(Order), Comparator(Comparator) {}
1517 static bool classof(const PredicateMatcher *P) {
1518 return P->getKind() == IPM_AtomicOrderingMMO;
1521 bool isIdentical(const PredicateMatcher &B) const override;
1523 void emitPredicateOpcodes(MatchTable &Table,
1524 RuleMatcher &Rule) const override;
1527 /// Generates code to check that the size of an MMO is exactly N bytes.
1528 class MemorySizePredicateMatcher : public InstructionPredicateMatcher {
1529 protected:
1530 unsigned MMOIdx;
1531 uint64_t Size;
1533 public:
1534 MemorySizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx, unsigned Size)
1535 : InstructionPredicateMatcher(IPM_MemoryLLTSize, InsnVarID),
1536 MMOIdx(MMOIdx), Size(Size) {}
1538 static bool classof(const PredicateMatcher *P) {
1539 return P->getKind() == IPM_MemoryLLTSize;
1541 bool isIdentical(const PredicateMatcher &B) const override {
1542 return InstructionPredicateMatcher::isIdentical(B) &&
1543 MMOIdx == cast<MemorySizePredicateMatcher>(&B)->MMOIdx &&
1544 Size == cast<MemorySizePredicateMatcher>(&B)->Size;
1547 void emitPredicateOpcodes(MatchTable &Table,
1548 RuleMatcher &Rule) const override;
1551 class MemoryAddressSpacePredicateMatcher : public InstructionPredicateMatcher {
1552 protected:
1553 unsigned MMOIdx;
1554 SmallVector<unsigned, 4> AddrSpaces;
1556 public:
1557 MemoryAddressSpacePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1558 ArrayRef<unsigned> AddrSpaces)
1559 : InstructionPredicateMatcher(IPM_MemoryAddressSpace, InsnVarID),
1560 MMOIdx(MMOIdx), AddrSpaces(AddrSpaces) {}
1562 static bool classof(const PredicateMatcher *P) {
1563 return P->getKind() == IPM_MemoryAddressSpace;
1566 bool isIdentical(const PredicateMatcher &B) const override;
1568 void emitPredicateOpcodes(MatchTable &Table,
1569 RuleMatcher &Rule) const override;
1572 class MemoryAlignmentPredicateMatcher : public InstructionPredicateMatcher {
1573 protected:
1574 unsigned MMOIdx;
1575 int MinAlign;
1577 public:
1578 MemoryAlignmentPredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1579 int MinAlign)
1580 : InstructionPredicateMatcher(IPM_MemoryAlignment, InsnVarID),
1581 MMOIdx(MMOIdx), MinAlign(MinAlign) {
1582 assert(MinAlign > 0);
1585 static bool classof(const PredicateMatcher *P) {
1586 return P->getKind() == IPM_MemoryAlignment;
1589 bool isIdentical(const PredicateMatcher &B) const override;
1591 void emitPredicateOpcodes(MatchTable &Table,
1592 RuleMatcher &Rule) const override;
1595 /// Generates code to check that the size of an MMO is less-than, equal-to, or
1596 /// greater than a given LLT.
1597 class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher {
1598 public:
1599 enum RelationKind {
1600 GreaterThan,
1601 EqualTo,
1602 LessThan,
1605 protected:
1606 unsigned MMOIdx;
1607 RelationKind Relation;
1608 unsigned OpIdx;
1610 public:
1611 MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1612 enum RelationKind Relation, unsigned OpIdx)
1613 : InstructionPredicateMatcher(IPM_MemoryVsLLTSize, InsnVarID),
1614 MMOIdx(MMOIdx), Relation(Relation), OpIdx(OpIdx) {}
1616 static bool classof(const PredicateMatcher *P) {
1617 return P->getKind() == IPM_MemoryVsLLTSize;
1619 bool isIdentical(const PredicateMatcher &B) const override;
1621 void emitPredicateOpcodes(MatchTable &Table,
1622 RuleMatcher &Rule) const override;
1625 // Matcher for immAllOnesV/immAllZerosV
1626 class VectorSplatImmPredicateMatcher : public InstructionPredicateMatcher {
1627 public:
1628 enum SplatKind { AllZeros, AllOnes };
1630 private:
1631 SplatKind Kind;
1633 public:
1634 VectorSplatImmPredicateMatcher(unsigned InsnVarID, SplatKind K)
1635 : InstructionPredicateMatcher(IPM_VectorSplatImm, InsnVarID), Kind(K) {}
1637 static bool classof(const PredicateMatcher *P) {
1638 return P->getKind() == IPM_VectorSplatImm;
1641 bool isIdentical(const PredicateMatcher &B) const override {
1642 return InstructionPredicateMatcher::isIdentical(B) &&
1643 Kind == static_cast<const VectorSplatImmPredicateMatcher &>(B).Kind;
1646 void emitPredicateOpcodes(MatchTable &Table,
1647 RuleMatcher &Rule) const override;
1650 /// Generates code to check an arbitrary C++ instruction predicate.
1651 class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
1652 protected:
1653 std::string EnumVal;
1655 public:
1656 GenericInstructionPredicateMatcher(unsigned InsnVarID,
1657 TreePredicateFn Predicate);
1659 GenericInstructionPredicateMatcher(unsigned InsnVarID,
1660 const std::string &EnumVal)
1661 : InstructionPredicateMatcher(IPM_GenericPredicate, InsnVarID),
1662 EnumVal(EnumVal) {}
1664 static bool classof(const InstructionPredicateMatcher *P) {
1665 return P->getKind() == IPM_GenericPredicate;
1667 bool isIdentical(const PredicateMatcher &B) const override;
1668 void emitPredicateOpcodes(MatchTable &Table,
1669 RuleMatcher &Rule) const override;
1672 class MIFlagsInstructionPredicateMatcher : public InstructionPredicateMatcher {
1673 SmallVector<StringRef, 2> Flags;
1674 bool CheckNot; // false = GIM_MIFlags, true = GIM_MIFlagsNot
1676 public:
1677 MIFlagsInstructionPredicateMatcher(unsigned InsnVarID,
1678 ArrayRef<StringRef> FlagsToCheck,
1679 bool CheckNot = false)
1680 : InstructionPredicateMatcher(IPM_MIFlags, InsnVarID),
1681 Flags(FlagsToCheck), CheckNot(CheckNot) {
1682 sort(Flags);
1685 static bool classof(const InstructionPredicateMatcher *P) {
1686 return P->getKind() == IPM_MIFlags;
1689 bool isIdentical(const PredicateMatcher &B) const override;
1690 void emitPredicateOpcodes(MatchTable &Table,
1691 RuleMatcher &Rule) const override;
1694 /// Generates code to check for the absence of use of the result.
1695 // TODO? Generalize this to support checking for one use.
1696 class NoUsePredicateMatcher : public InstructionPredicateMatcher {
1697 public:
1698 NoUsePredicateMatcher(unsigned InsnVarID)
1699 : InstructionPredicateMatcher(IPM_NoUse, InsnVarID) {}
1701 static bool classof(const PredicateMatcher *P) {
1702 return P->getKind() == IPM_NoUse;
1705 bool isIdentical(const PredicateMatcher &B) const override {
1706 return InstructionPredicateMatcher::isIdentical(B);
1709 void emitPredicateOpcodes(MatchTable &Table,
1710 RuleMatcher &Rule) const override {
1711 Table << MatchTable::Opcode("GIM_CheckHasNoUse")
1712 << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
1713 << MatchTable::LineBreak;
1717 /// Generates code to check that the first result has only one use.
1718 class OneUsePredicateMatcher : public InstructionPredicateMatcher {
1719 public:
1720 OneUsePredicateMatcher(unsigned InsnVarID)
1721 : InstructionPredicateMatcher(IPM_OneUse, InsnVarID) {}
1723 static bool classof(const PredicateMatcher *P) {
1724 return P->getKind() == IPM_OneUse;
1727 bool isIdentical(const PredicateMatcher &B) const override {
1728 return InstructionPredicateMatcher::isIdentical(B);
1731 void emitPredicateOpcodes(MatchTable &Table,
1732 RuleMatcher &Rule) const override {
1733 Table << MatchTable::Opcode("GIM_CheckHasOneUse")
1734 << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
1735 << MatchTable::LineBreak;
1739 /// Generates code to check that a set of predicates and operands match for a
1740 /// particular instruction.
1742 /// Typical predicates include:
1743 /// * Has a specific opcode.
1744 /// * Has an nsw/nuw flag or doesn't.
1745 class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
1746 protected:
1747 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
1749 RuleMatcher &Rule;
1751 /// The operands to match. All rendered operands must be present even if the
1752 /// condition is always true.
1753 OperandVec Operands;
1755 std::string SymbolicName;
1756 unsigned InsnVarID;
1757 bool AllowNumOpsCheck;
1759 /// PhysRegInputs - List list has an entry for each explicitly specified
1760 /// physreg input to the pattern. The first elt is the Register node, the
1761 /// second is the recorded slot number the input pattern match saved it in.
1762 SmallVector<std::pair<const Record *, unsigned>, 2> PhysRegInputs;
1764 bool canAddNumOperandsCheck() const {
1765 // Add if it's allowed, and:
1766 // - We don't have a variadic operand
1767 // - We don't already have such a check.
1768 return AllowNumOpsCheck && !hasVariadicMatcher() &&
1769 none_of(Predicates, [&](const auto &P) {
1770 return P->getKind() ==
1771 InstructionPredicateMatcher::IPM_NumOperands;
1775 public:
1776 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName,
1777 bool AllowNumOpsCheck = true)
1778 : Rule(Rule), SymbolicName(SymbolicName),
1779 AllowNumOpsCheck(AllowNumOpsCheck) {
1780 // We create a new instruction matcher.
1781 // Get a new ID for that instruction.
1782 InsnVarID = Rule.implicitlyDefineInsnVar(*this);
1785 /// Construct a new instruction predicate and add it to the matcher.
1786 template <class Kind, class... Args>
1787 std::optional<Kind *> addPredicate(Args &&...args) {
1788 Predicates.emplace_back(
1789 std::make_unique<Kind>(getInsnVarID(), std::forward<Args>(args)...));
1790 return static_cast<Kind *>(Predicates.back().get());
1793 RuleMatcher &getRuleMatcher() const { return Rule; }
1795 unsigned getInsnVarID() const { return InsnVarID; }
1797 /// Add an operand to the matcher.
1798 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1799 unsigned AllocatedTemporariesBaseID,
1800 bool IsVariadic = false);
1801 OperandMatcher &getOperand(unsigned OpIdx);
1802 OperandMatcher &addPhysRegInput(const Record *Reg, unsigned OpIdx,
1803 unsigned TempOpIdx);
1805 ArrayRef<std::pair<const Record *, unsigned>> getPhysRegInputs() const {
1806 return PhysRegInputs;
1809 StringRef getSymbolicName() const { return SymbolicName; }
1811 unsigned getNumOperandMatchers() const { return Operands.size(); }
1812 bool hasVariadicMatcher() const {
1813 return !Operands.empty() && Operands.back()->isVariadic();
1816 OperandVec::iterator operands_begin() { return Operands.begin(); }
1817 OperandVec::iterator operands_end() { return Operands.end(); }
1818 iterator_range<OperandVec::iterator> operands() {
1819 return make_range(operands_begin(), operands_end());
1821 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1822 OperandVec::const_iterator operands_end() const { return Operands.end(); }
1823 iterator_range<OperandVec::const_iterator> operands() const {
1824 return make_range(operands_begin(), operands_end());
1826 bool operands_empty() const { return Operands.empty(); }
1828 void pop_front() { Operands.erase(Operands.begin()); }
1830 void optimize();
1832 /// Emit MatchTable opcodes that test whether the instruction named in
1833 /// InsnVarName matches all the predicates and all the operands.
1834 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule);
1836 /// Compare the priority of this object and B.
1838 /// Returns true if this object is more important than B.
1839 bool isHigherPriorityThan(InstructionMatcher &B);
1841 /// Report the maximum number of temporary operands needed by the instruction
1842 /// matcher.
1843 unsigned countRendererFns();
1845 InstructionOpcodeMatcher &getOpcodeMatcher() {
1846 for (auto &P : predicates())
1847 if (auto *OpMatcher = dyn_cast<InstructionOpcodeMatcher>(P.get()))
1848 return *OpMatcher;
1849 llvm_unreachable("Didn't find an opcode matcher");
1852 bool isConstantInstruction() {
1853 return getOpcodeMatcher().isConstantInstruction();
1856 StringRef getOpcode() { return getOpcodeMatcher().getOpcode(); }
1859 /// Generates code to check that the operand is a register defined by an
1860 /// instruction that matches the given instruction matcher.
1862 /// For example, the pattern:
1863 /// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1864 /// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1865 /// the:
1866 /// (G_ADD $src1, $src2)
1867 /// subpattern.
1868 class InstructionOperandMatcher : public OperandPredicateMatcher {
1869 protected:
1870 std::unique_ptr<InstructionMatcher> InsnMatcher;
1872 GISelFlags Flags;
1874 public:
1875 InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1876 RuleMatcher &Rule, StringRef SymbolicName,
1877 bool AllowNumOpsCheck = true)
1878 : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
1879 InsnMatcher(
1880 new InstructionMatcher(Rule, SymbolicName, AllowNumOpsCheck)),
1881 Flags(Rule.getGISelFlags()) {}
1883 static bool classof(const PredicateMatcher *P) {
1884 return P->getKind() == OPM_Instruction;
1887 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1889 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const;
1890 void emitPredicateOpcodes(MatchTable &Table,
1891 RuleMatcher &Rule) const override {
1892 emitCaptureOpcodes(Table, Rule);
1893 InsnMatcher->emitPredicateOpcodes(Table, Rule);
1896 bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override;
1898 /// Report the maximum number of temporary operands needed by the predicate
1899 /// matcher.
1900 unsigned countRendererFns() const override {
1901 return InsnMatcher->countRendererFns();
1905 //===- Actions ------------------------------------------------------------===//
1906 class OperandRenderer {
1907 public:
1908 enum RendererKind {
1909 OR_Copy,
1910 OR_CopyOrAddZeroReg,
1911 OR_CopySubReg,
1912 OR_CopyPhysReg,
1913 OR_CopyConstantAsImm,
1914 OR_CopyFConstantAsFPImm,
1915 OR_Imm,
1916 OR_SubRegIndex,
1917 OR_Register,
1918 OR_TempRegister,
1919 OR_ComplexPattern,
1920 OR_Intrinsic,
1921 OR_Custom,
1922 OR_CustomOperand
1925 protected:
1926 RendererKind Kind;
1928 public:
1929 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1930 virtual ~OperandRenderer();
1932 RendererKind getKind() const { return Kind; }
1934 virtual void emitRenderOpcodes(MatchTable &Table,
1935 RuleMatcher &Rule) const = 0;
1938 /// A CopyRenderer emits code to copy a single operand from an existing
1939 /// instruction to the one being built.
1940 class CopyRenderer : public OperandRenderer {
1941 protected:
1942 unsigned NewInsnID;
1943 /// The name of the operand.
1944 const StringRef SymbolicName;
1946 public:
1947 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1948 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
1949 SymbolicName(SymbolicName) {
1950 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1953 static bool classof(const OperandRenderer *R) {
1954 return R->getKind() == OR_Copy;
1957 StringRef getSymbolicName() const { return SymbolicName; }
1959 static void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule,
1960 unsigned NewInsnID, unsigned OldInsnID,
1961 unsigned OpIdx, StringRef Name,
1962 bool ForVariadic = false);
1964 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1967 /// A CopyRenderer emits code to copy a virtual register to a specific physical
1968 /// register.
1969 class CopyPhysRegRenderer : public OperandRenderer {
1970 protected:
1971 unsigned NewInsnID;
1972 const Record *PhysReg;
1974 public:
1975 CopyPhysRegRenderer(unsigned NewInsnID, const Record *Reg)
1976 : OperandRenderer(OR_CopyPhysReg), NewInsnID(NewInsnID), PhysReg(Reg) {
1977 assert(PhysReg);
1980 static bool classof(const OperandRenderer *R) {
1981 return R->getKind() == OR_CopyPhysReg;
1984 const Record *getPhysReg() const { return PhysReg; }
1986 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
1989 /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1990 /// existing instruction to the one being built. If the operand turns out to be
1991 /// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1992 class CopyOrAddZeroRegRenderer : public OperandRenderer {
1993 protected:
1994 unsigned NewInsnID;
1995 /// The name of the operand.
1996 const StringRef SymbolicName;
1997 const Record *ZeroRegisterDef;
1999 public:
2000 CopyOrAddZeroRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
2001 const Record *ZeroRegisterDef)
2002 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
2003 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
2004 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
2007 static bool classof(const OperandRenderer *R) {
2008 return R->getKind() == OR_CopyOrAddZeroReg;
2011 StringRef getSymbolicName() const { return SymbolicName; }
2013 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2016 /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
2017 /// an extended immediate operand.
2018 class CopyConstantAsImmRenderer : public OperandRenderer {
2019 protected:
2020 unsigned NewInsnID;
2021 /// The name of the operand.
2022 const std::string SymbolicName;
2023 bool Signed;
2025 public:
2026 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2027 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
2028 SymbolicName(SymbolicName), Signed(true) {}
2030 static bool classof(const OperandRenderer *R) {
2031 return R->getKind() == OR_CopyConstantAsImm;
2034 StringRef getSymbolicName() const { return SymbolicName; }
2036 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2039 /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
2040 /// instruction to an extended immediate operand.
2041 class CopyFConstantAsFPImmRenderer : public OperandRenderer {
2042 protected:
2043 unsigned NewInsnID;
2044 /// The name of the operand.
2045 const std::string SymbolicName;
2047 public:
2048 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2049 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
2050 SymbolicName(SymbolicName) {}
2052 static bool classof(const OperandRenderer *R) {
2053 return R->getKind() == OR_CopyFConstantAsFPImm;
2056 StringRef getSymbolicName() const { return SymbolicName; }
2058 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2061 /// A CopySubRegRenderer emits code to copy a single register operand from an
2062 /// existing instruction to the one being built and indicate that only a
2063 /// subregister should be copied.
2064 class CopySubRegRenderer : public OperandRenderer {
2065 protected:
2066 unsigned NewInsnID;
2067 /// The name of the operand.
2068 const StringRef SymbolicName;
2069 /// The subregister to extract.
2070 const CodeGenSubRegIndex *SubReg;
2072 public:
2073 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
2074 const CodeGenSubRegIndex *SubReg)
2075 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
2076 SymbolicName(SymbolicName), SubReg(SubReg) {}
2078 static bool classof(const OperandRenderer *R) {
2079 return R->getKind() == OR_CopySubReg;
2082 StringRef getSymbolicName() const { return SymbolicName; }
2084 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2087 /// Adds a specific physical register to the instruction being built.
2088 /// This is typically useful for WZR/XZR on AArch64.
2089 class AddRegisterRenderer : public OperandRenderer {
2090 protected:
2091 unsigned InsnID;
2092 const Record *RegisterDef;
2093 bool IsDef;
2094 const CodeGenTarget &Target;
2096 public:
2097 AddRegisterRenderer(unsigned InsnID, const CodeGenTarget &Target,
2098 const Record *RegisterDef, bool IsDef = false)
2099 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef),
2100 IsDef(IsDef), Target(Target) {}
2102 static bool classof(const OperandRenderer *R) {
2103 return R->getKind() == OR_Register;
2106 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2109 /// Adds a specific temporary virtual register to the instruction being built.
2110 /// This is used to chain instructions together when emitting multiple
2111 /// instructions.
2112 class TempRegRenderer : public OperandRenderer {
2113 protected:
2114 unsigned InsnID;
2115 unsigned TempRegID;
2116 const CodeGenSubRegIndex *SubRegIdx;
2117 bool IsDef;
2118 bool IsDead;
2120 public:
2121 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false,
2122 const CodeGenSubRegIndex *SubReg = nullptr,
2123 bool IsDead = false)
2124 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
2125 SubRegIdx(SubReg), IsDef(IsDef), IsDead(IsDead) {}
2127 static bool classof(const OperandRenderer *R) {
2128 return R->getKind() == OR_TempRegister;
2131 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2134 /// Adds a specific immediate to the instruction being built.
2135 /// If a LLT is passed, a ConstantInt immediate is created instead.
2136 class ImmRenderer : public OperandRenderer {
2137 protected:
2138 unsigned InsnID;
2139 int64_t Imm;
2140 std::optional<LLTCodeGenOrTempType> CImmLLT;
2142 public:
2143 ImmRenderer(unsigned InsnID, int64_t Imm)
2144 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
2146 ImmRenderer(unsigned InsnID, int64_t Imm, const LLTCodeGenOrTempType &CImmLLT)
2147 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm), CImmLLT(CImmLLT) {
2148 if (CImmLLT.isLLTCodeGen())
2149 KnownTypes.insert(CImmLLT.getLLTCodeGen());
2152 static bool classof(const OperandRenderer *R) {
2153 return R->getKind() == OR_Imm;
2156 static void emitAddImm(MatchTable &Table, RuleMatcher &RM, unsigned InsnID,
2157 int64_t Imm, StringRef ImmName = "Imm");
2159 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2162 /// Adds an enum value for a subreg index to the instruction being built.
2163 class SubRegIndexRenderer : public OperandRenderer {
2164 protected:
2165 unsigned InsnID;
2166 const CodeGenSubRegIndex *SubRegIdx;
2168 public:
2169 SubRegIndexRenderer(unsigned InsnID, const CodeGenSubRegIndex *SRI)
2170 : OperandRenderer(OR_SubRegIndex), InsnID(InsnID), SubRegIdx(SRI) {}
2172 static bool classof(const OperandRenderer *R) {
2173 return R->getKind() == OR_SubRegIndex;
2176 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2179 /// Adds operands by calling a renderer function supplied by the ComplexPattern
2180 /// matcher function.
2181 class RenderComplexPatternOperand : public OperandRenderer {
2182 private:
2183 unsigned InsnID;
2184 const Record &TheDef;
2185 /// The name of the operand.
2186 const StringRef SymbolicName;
2187 /// The renderer number. This must be unique within a rule since it's used to
2188 /// identify a temporary variable to hold the renderer function.
2189 unsigned RendererID;
2190 /// When provided, this is the suboperand of the ComplexPattern operand to
2191 /// render. Otherwise all the suboperands will be rendered.
2192 std::optional<unsigned> SubOperand;
2193 /// The subregister to extract. Render the whole register if not specified.
2194 const CodeGenSubRegIndex *SubReg;
2196 unsigned getNumOperands() const {
2197 return TheDef.getValueAsDag("Operands")->getNumArgs();
2200 public:
2201 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
2202 StringRef SymbolicName, unsigned RendererID,
2203 std::optional<unsigned> SubOperand = std::nullopt,
2204 const CodeGenSubRegIndex *SubReg = nullptr)
2205 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
2206 SymbolicName(SymbolicName), RendererID(RendererID),
2207 SubOperand(SubOperand), SubReg(SubReg) {}
2209 static bool classof(const OperandRenderer *R) {
2210 return R->getKind() == OR_ComplexPattern;
2213 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2216 /// Adds an intrinsic ID operand to the instruction being built.
2217 class IntrinsicIDRenderer : public OperandRenderer {
2218 protected:
2219 unsigned InsnID;
2220 const CodeGenIntrinsic *II;
2222 public:
2223 IntrinsicIDRenderer(unsigned InsnID, const CodeGenIntrinsic *II)
2224 : OperandRenderer(OR_Intrinsic), InsnID(InsnID), II(II) {}
2226 static bool classof(const OperandRenderer *R) {
2227 return R->getKind() == OR_Intrinsic;
2230 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2233 class CustomRenderer : public OperandRenderer {
2234 protected:
2235 unsigned InsnID;
2236 const Record &Renderer;
2237 /// The name of the operand.
2238 const std::string SymbolicName;
2240 public:
2241 CustomRenderer(unsigned InsnID, const Record &Renderer,
2242 StringRef SymbolicName)
2243 : OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer),
2244 SymbolicName(SymbolicName) {}
2246 static bool classof(const OperandRenderer *R) {
2247 return R->getKind() == OR_Custom;
2250 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2253 class CustomOperandRenderer : public OperandRenderer {
2254 protected:
2255 unsigned InsnID;
2256 const Record &Renderer;
2257 /// The name of the operand.
2258 const std::string SymbolicName;
2260 public:
2261 CustomOperandRenderer(unsigned InsnID, const Record &Renderer,
2262 StringRef SymbolicName)
2263 : OperandRenderer(OR_CustomOperand), InsnID(InsnID), Renderer(Renderer),
2264 SymbolicName(SymbolicName) {}
2266 static bool classof(const OperandRenderer *R) {
2267 return R->getKind() == OR_CustomOperand;
2270 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2273 /// An action taken when all Matcher predicates succeeded for a parent rule.
2275 /// Typical actions include:
2276 /// * Changing the opcode of an instruction.
2277 /// * Adding an operand to an instruction.
2278 class MatchAction {
2279 public:
2280 enum ActionKind {
2281 AK_DebugComment,
2282 AK_BuildMI,
2283 AK_BuildConstantMI,
2284 AK_EraseInst,
2285 AK_ReplaceReg,
2286 AK_ConstraintOpsToDef,
2287 AK_ConstraintOpsToRC,
2288 AK_MakeTempReg,
2291 MatchAction(ActionKind K) : Kind(K) {}
2293 ActionKind getKind() const { return Kind; }
2295 virtual ~MatchAction() {}
2297 // Some actions may need to add extra predicates to ensure they can run.
2298 virtual void emitAdditionalPredicates(MatchTable &Table,
2299 RuleMatcher &Rule) const {}
2301 /// Emit the MatchTable opcodes to implement the action.
2302 virtual void emitActionOpcodes(MatchTable &Table,
2303 RuleMatcher &Rule) const = 0;
2305 /// If this opcode has an overload that can call GIR_Done directly, emit that
2306 /// instead of the usual opcode and return "true". Return "false" if GIR_Done
2307 /// still needs to be emitted.
2308 virtual bool emitActionOpcodesAndDone(MatchTable &Table,
2309 RuleMatcher &Rule) const {
2310 emitActionOpcodes(Table, Rule);
2311 return false;
2314 private:
2315 ActionKind Kind;
2318 /// Generates a comment describing the matched rule being acted upon.
2319 class DebugCommentAction : public MatchAction {
2320 private:
2321 std::string S;
2323 public:
2324 DebugCommentAction(StringRef S)
2325 : MatchAction(AK_DebugComment), S(std::string(S)) {}
2327 static bool classof(const MatchAction *A) {
2328 return A->getKind() == AK_DebugComment;
2331 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2332 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
2336 /// Generates code to build an instruction or mutate an existing instruction
2337 /// into the desired instruction when this is possible.
2338 class BuildMIAction : public MatchAction {
2339 private:
2340 unsigned InsnID;
2341 const CodeGenInstruction *I;
2342 InstructionMatcher *Matched;
2343 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
2344 SmallPtrSet<const Record *, 4> DeadImplicitDefs;
2346 std::vector<const InstructionMatcher *> CopiedFlags;
2347 std::vector<StringRef> SetFlags;
2348 std::vector<StringRef> UnsetFlags;
2350 /// True if the instruction can be built solely by mutating the opcode.
2351 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const;
2353 public:
2354 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
2355 : MatchAction(AK_BuildMI), InsnID(InsnID), I(I), Matched(nullptr) {}
2357 static bool classof(const MatchAction *A) {
2358 return A->getKind() == AK_BuildMI;
2361 unsigned getInsnID() const { return InsnID; }
2362 const CodeGenInstruction *getCGI() const { return I; }
2364 void addSetMIFlags(StringRef Flag) { SetFlags.push_back(Flag); }
2365 void addUnsetMIFlags(StringRef Flag) { UnsetFlags.push_back(Flag); }
2366 void addCopiedMIFlags(const InstructionMatcher &IM) {
2367 CopiedFlags.push_back(&IM);
2370 void chooseInsnToMutate(RuleMatcher &Rule);
2372 void setDeadImplicitDef(const Record *R) { DeadImplicitDefs.insert(R); }
2374 template <class Kind, class... Args> Kind &addRenderer(Args &&...args) {
2375 OperandRenderers.emplace_back(
2376 std::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
2377 return *static_cast<Kind *>(OperandRenderers.back().get());
2380 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2383 /// Generates code to create a constant that defines a TempReg.
2384 /// The instruction created is usually a G_CONSTANT but it could also be a
2385 /// G_BUILD_VECTOR for vector types.
2386 class BuildConstantAction : public MatchAction {
2387 unsigned TempRegID;
2388 int64_t Val;
2390 public:
2391 BuildConstantAction(unsigned TempRegID, int64_t Val)
2392 : MatchAction(AK_BuildConstantMI), TempRegID(TempRegID), Val(Val) {}
2394 static bool classof(const MatchAction *A) {
2395 return A->getKind() == AK_BuildConstantMI;
2398 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2401 class EraseInstAction : public MatchAction {
2402 unsigned InsnID;
2404 public:
2405 EraseInstAction(unsigned InsnID)
2406 : MatchAction(AK_EraseInst), InsnID(InsnID) {}
2408 unsigned getInsnID() const { return InsnID; }
2410 static bool classof(const MatchAction *A) {
2411 return A->getKind() == AK_EraseInst;
2414 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2415 bool emitActionOpcodesAndDone(MatchTable &Table,
2416 RuleMatcher &Rule) const override;
2419 class ReplaceRegAction : public MatchAction {
2420 unsigned OldInsnID, OldOpIdx;
2421 unsigned NewInsnId = -1, NewOpIdx;
2422 unsigned TempRegID = -1;
2424 public:
2425 ReplaceRegAction(unsigned OldInsnID, unsigned OldOpIdx, unsigned NewInsnId,
2426 unsigned NewOpIdx)
2427 : MatchAction(AK_ReplaceReg), OldInsnID(OldInsnID), OldOpIdx(OldOpIdx),
2428 NewInsnId(NewInsnId), NewOpIdx(NewOpIdx) {}
2430 ReplaceRegAction(unsigned OldInsnID, unsigned OldOpIdx, unsigned TempRegID)
2431 : MatchAction(AK_ReplaceReg), OldInsnID(OldInsnID), OldOpIdx(OldOpIdx),
2432 TempRegID(TempRegID) {}
2434 static bool classof(const MatchAction *A) {
2435 return A->getKind() == AK_ReplaceReg;
2438 void emitAdditionalPredicates(MatchTable &Table,
2439 RuleMatcher &Rule) const override;
2440 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2443 /// Generates code to constrain the operands of an output instruction to the
2444 /// register classes specified by the definition of that instruction.
2445 class ConstrainOperandsToDefinitionAction : public MatchAction {
2446 unsigned InsnID;
2448 public:
2449 ConstrainOperandsToDefinitionAction(unsigned InsnID)
2450 : MatchAction(AK_ConstraintOpsToDef), InsnID(InsnID) {}
2452 static bool classof(const MatchAction *A) {
2453 return A->getKind() == AK_ConstraintOpsToDef;
2456 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2457 if (InsnID == 0) {
2458 Table << MatchTable::Opcode("GIR_RootConstrainSelectedInstOperands")
2459 << MatchTable::LineBreak;
2460 } else {
2461 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2462 << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID)
2463 << MatchTable::LineBreak;
2468 /// Generates code to constrain the specified operand of an output instruction
2469 /// to the specified register class.
2470 class ConstrainOperandToRegClassAction : public MatchAction {
2471 unsigned InsnID;
2472 unsigned OpIdx;
2473 const CodeGenRegisterClass &RC;
2475 public:
2476 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
2477 const CodeGenRegisterClass &RC)
2478 : MatchAction(AK_ConstraintOpsToRC), InsnID(InsnID), OpIdx(OpIdx),
2479 RC(RC) {}
2481 static bool classof(const MatchAction *A) {
2482 return A->getKind() == AK_ConstraintOpsToRC;
2485 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2488 /// Generates code to create a temporary register which can be used to chain
2489 /// instructions together.
2490 class MakeTempRegisterAction : public MatchAction {
2491 private:
2492 LLTCodeGenOrTempType Ty;
2493 unsigned TempRegID;
2495 public:
2496 MakeTempRegisterAction(const LLTCodeGenOrTempType &Ty, unsigned TempRegID)
2497 : MatchAction(AK_MakeTempReg), Ty(Ty), TempRegID(TempRegID) {
2498 if (Ty.isLLTCodeGen())
2499 KnownTypes.insert(Ty.getLLTCodeGen());
2502 static bool classof(const MatchAction *A) {
2503 return A->getKind() == AK_MakeTempReg;
2506 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override;
2509 } // namespace gi
2510 } // namespace llvm
2512 #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H