1 //===- GlobalISelMatchTable.h ---------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLE_H
17 #define LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLE_H
19 #include "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/CodeGen/LowLevelType.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/SaveAndRestore.h"
42 class CodeGenRegisterClass
;
44 // Use a namespace to avoid conflicts because there's some fairly generic names
45 // in there (e.g. Matcher).
51 class PredicateMatcher
;
52 class InstructionMatcher
;
55 GISF_IgnoreCopies
= 0x1,
58 using GISelFlags
= std::uint16_t;
60 //===- Helper functions ---------------------------------------------------===//
62 std::string
getNameForFeatureBitset(const std::vector
<Record
*> &FeatureBitset
,
65 /// Takes a sequence of \p Rules and group them based on the predicates
66 /// they share. \p MatcherStorage is used as a memory container
67 /// for the group that are created as part of this process.
69 /// What this optimization does looks like if GroupT = GroupMatcher:
70 /// Output without optimization:
77 /// # predicate A // <-- effectively this is going to be checked twice.
78 /// // Once in R1 and once in R2.
81 /// Output with optimization:
84 /// # predicate A // <-- Check is now shared.
90 template <class GroupT
>
91 std::vector
<Matcher
*>
92 optimizeRules(ArrayRef
<Matcher
*> Rules
,
93 std::vector
<std::unique_ptr
<Matcher
>> &MatcherStorage
);
95 /// A record to be stored in a MatchTable.
97 /// This class represents any and all output that may be required to emit the
98 /// MatchTable. Instances are most often configured to represent an opcode or
99 /// value that will be emitted to the table with some formatting but it can also
100 /// represent commas, comments, and other formatting instructions.
101 struct MatchTableRecord
{
102 enum RecordFlagsBits
{
104 /// Causes EmitStr to be formatted as comment when emitted.
106 /// Causes the record value to be followed by a comma when emitted.
107 MTRF_CommaFollows
= 0x2,
108 /// Causes the record value to be followed by a line break when emitted.
109 MTRF_LineBreakFollows
= 0x4,
110 /// Indicates that the record defines a label and causes an additional
111 /// comment to be emitted containing the index of the label.
113 /// Causes the record to be emitted as the index of the label specified by
114 /// LabelID along with a comment indicating where that label is.
115 MTRF_JumpTarget
= 0x10,
116 /// Causes the formatter to add a level of indentation before emitting the
119 /// Causes the formatter to remove a level of indentation after emitting the
124 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
125 /// reference or define.
127 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
128 /// value, a label name.
132 /// The number of MatchTable elements described by this record. Comments are 0
133 /// while values are typically 1. Values >1 may occur when we need to emit
134 /// values that exceed the size of a MatchTable element.
135 unsigned NumElements
;
138 /// A bitfield of RecordFlagsBits flags.
141 /// The actual run-time value, if known
144 MatchTableRecord(std::optional
<unsigned> LabelID_
, StringRef EmitStr
,
145 unsigned NumElements
, unsigned Flags
,
146 int64_t RawValue
= std::numeric_limits
<int64_t>::min())
147 : LabelID(LabelID_
.value_or(~0u)), EmitStr(EmitStr
),
148 NumElements(NumElements
), Flags(Flags
), RawValue(RawValue
) {
149 assert((!LabelID_
|| LabelID
!= ~0u) &&
150 "This value is reserved for non-labels");
152 MatchTableRecord(const MatchTableRecord
&Other
) = default;
153 MatchTableRecord(MatchTableRecord
&&Other
) = default;
155 /// Useful if a Match Table Record gets optimized out
156 void turnIntoComment() {
157 Flags
|= MTRF_Comment
;
158 Flags
&= ~MTRF_CommaFollows
;
162 /// For Jump Table generation purposes
163 bool operator<(const MatchTableRecord
&Other
) const {
164 return RawValue
< Other
.RawValue
;
166 int64_t getRawValue() const { return RawValue
; }
168 void emit(raw_ostream
&OS
, bool LineBreakNextAfterThis
,
169 const MatchTable
&Table
) const;
170 unsigned size() const { return NumElements
; }
173 /// Holds the contents of a generated MatchTable to enable formatting and the
174 /// necessary index tracking needed to support GIM_Try.
176 /// An unique identifier for the table. The generated table will be named
179 /// The records that make up the table. Also includes comments describing the
180 /// values being emitted and line breaks to format it.
181 std::vector
<MatchTableRecord
> Contents
;
182 /// The currently defined labels.
183 DenseMap
<unsigned, unsigned> LabelMap
;
184 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
185 unsigned CurrentSize
= 0;
186 /// A unique identifier for a MatchTable label.
187 unsigned CurrentLabelID
= 0;
188 /// Determines if the table should be instrumented for rule coverage tracking.
190 /// Whether this table is for the GISel combiner.
191 bool IsCombinerTable
;
194 static MatchTableRecord LineBreak
;
195 static MatchTableRecord
Comment(StringRef Comment
);
196 static MatchTableRecord
Opcode(StringRef Opcode
, int IndentAdjust
= 0);
197 static MatchTableRecord
NamedValue(StringRef NamedValue
);
198 static MatchTableRecord
NamedValue(StringRef NamedValue
, int64_t RawValue
);
199 static MatchTableRecord
NamedValue(StringRef Namespace
, StringRef NamedValue
);
200 static MatchTableRecord
NamedValue(StringRef Namespace
, StringRef NamedValue
,
202 static MatchTableRecord
IntValue(int64_t IntValue
);
203 static MatchTableRecord
Label(unsigned LabelID
);
204 static MatchTableRecord
JumpTarget(unsigned LabelID
);
206 static MatchTable
buildTable(ArrayRef
<Matcher
*> Rules
, bool WithCoverage
,
207 bool IsCombiner
= false);
209 MatchTable(bool WithCoverage
, bool IsCombinerTable
, unsigned ID
= 0)
210 : ID(ID
), IsWithCoverage(WithCoverage
), IsCombinerTable(IsCombinerTable
) {
213 bool isWithCoverage() const { return IsWithCoverage
; }
214 bool isCombiner() const { return IsCombinerTable
; }
216 void push_back(const MatchTableRecord
&Value
) {
217 if (Value
.Flags
& MatchTableRecord::MTRF_Label
)
218 defineLabel(Value
.LabelID
);
219 Contents
.push_back(Value
);
220 CurrentSize
+= Value
.size();
223 unsigned allocateLabelID() { return CurrentLabelID
++; }
225 void defineLabel(unsigned LabelID
) {
226 LabelMap
.insert(std::make_pair(LabelID
, CurrentSize
));
229 unsigned getLabelIndex(unsigned LabelID
) const {
230 const auto I
= LabelMap
.find(LabelID
);
231 assert(I
!= LabelMap
.end() && "Use of undeclared label");
235 void emitUse(raw_ostream
&OS
) const;
236 void emitDeclaration(raw_ostream
&OS
) const;
239 inline MatchTable
&operator<<(MatchTable
&Table
,
240 const MatchTableRecord
&Value
) {
241 Table
.push_back(Value
);
245 /// This class stands in for LLT wherever we want to tablegen-erate an
246 /// equivalent at compiler run-time.
252 LLTCodeGen() = default;
253 LLTCodeGen(const LLT
&Ty
) : Ty(Ty
) {}
255 std::string
getCxxEnumValue() const;
257 void emitCxxEnumValue(raw_ostream
&OS
) const;
258 void emitCxxConstructorCall(raw_ostream
&OS
) const;
260 const LLT
&get() const { return Ty
; }
262 /// This ordering is used for std::unique() and llvm::sort(). There's no
263 /// particular logic behind the order but either A < B or B < A must be
265 bool operator<(const LLTCodeGen
&Other
) const;
266 bool operator==(const LLTCodeGen
&B
) const { return Ty
== B
.Ty
; }
269 // Track all types that are used so we can emit the corresponding enum.
270 extern std::set
<LLTCodeGen
> KnownTypes
;
272 /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
273 /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
274 std::optional
<LLTCodeGen
> MVTToLLT(MVT::SimpleValueType SVT
);
276 using TempTypeIdx
= int64_t;
277 class LLTCodeGenOrTempType
{
279 LLTCodeGenOrTempType(const LLTCodeGen
&LLT
) : Data(LLT
) {}
280 LLTCodeGenOrTempType(TempTypeIdx TempTy
) : Data(TempTy
) {}
282 bool isLLTCodeGen() const { return std::holds_alternative
<LLTCodeGen
>(Data
); }
283 bool isTempTypeIdx() const {
284 return std::holds_alternative
<TempTypeIdx
>(Data
);
287 const LLTCodeGen
&getLLTCodeGen() const {
288 assert(isLLTCodeGen());
289 return std::get
<LLTCodeGen
>(Data
);
292 TempTypeIdx
getTempTypeIdx() const {
293 assert(isTempTypeIdx());
294 return std::get
<TempTypeIdx
>(Data
);
298 std::variant
<LLTCodeGen
, TempTypeIdx
> Data
;
301 inline MatchTable
&operator<<(MatchTable
&Table
,
302 const LLTCodeGenOrTempType
&Ty
) {
303 if (Ty
.isLLTCodeGen())
304 Table
<< MatchTable::NamedValue(Ty
.getLLTCodeGen().getCxxEnumValue());
306 Table
<< MatchTable::IntValue(Ty
.getTempTypeIdx());
310 //===- Matchers -----------------------------------------------------------===//
314 virtual void optimize();
315 virtual void emit(MatchTable
&Table
) = 0;
317 virtual bool hasFirstCondition() const = 0;
318 virtual const PredicateMatcher
&getFirstCondition() const = 0;
319 virtual std::unique_ptr
<PredicateMatcher
> popFirstCondition() = 0;
322 class GroupMatcher final
: public Matcher
{
323 /// Conditions that form a common prefix of all the matchers contained.
324 SmallVector
<std::unique_ptr
<PredicateMatcher
>, 1> Conditions
;
326 /// All the nested matchers, sharing a common prefix.
327 std::vector
<Matcher
*> Matchers
;
329 /// An owning collection for any auxiliary matchers created while optimizing
330 /// nested matchers contained.
331 std::vector
<std::unique_ptr
<Matcher
>> MatcherStorage
;
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.
337 /// Expected to preserve its argument, so it could be moved out later on.
338 bool addMatcher(Matcher
&Candidate
);
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:
344 /// addMatcher(...)*; finalize(); optimize(); emit(...); and
345 /// addMatcher(...)*; finalize(); emit(...);
349 /// addMatcher(...)*; finalize(); { optimize()*; emit(...); }*
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.
356 /// addMatcher() calls after the finalize() call are not supported.
358 /// finalize() and optimize() are both allowed to mutate the contained
359 /// matchers, so moving them out after finalize() is not supported.
361 void optimize() override
;
362 void emit(MatchTable
&Table
) override
;
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 make_range(Matchers
.begin(), Matchers
.end());
370 size_t size() const { return Matchers
.size(); }
371 bool empty() const { return Matchers
.empty(); }
373 std::unique_ptr
<PredicateMatcher
> popFirstCondition() override
{
374 assert(!Conditions
.empty() &&
375 "Trying to pop a condition from a condition-less group");
376 std::unique_ptr
<PredicateMatcher
> P
= std::move(Conditions
.front());
377 Conditions
.erase(Conditions
.begin());
380 const PredicateMatcher
&getFirstCondition() const override
{
381 assert(!Conditions
.empty() &&
382 "Trying to get a condition from a condition-less group");
383 return *Conditions
.front();
385 bool hasFirstCondition() const override
{ return !Conditions
.empty(); }
388 /// See if a candidate matcher could be added to this group solely by
389 /// analyzing its first condition.
390 bool candidateConditionMatches(const PredicateMatcher
&Predicate
) const;
393 class SwitchMatcher
: public Matcher
{
394 /// All the nested matchers, representing distinct switch-cases. The first
395 /// conditions (as Matcher::getFirstCondition() reports) of all the nested
396 /// matchers must share the same type and path to a value they check, in other
397 /// words, be isIdenticalDownToValue, but have different values they check
399 std::vector
<Matcher
*> Matchers
;
401 /// The representative condition, with a type and a path (InsnVarID and OpIdx
402 /// in most cases) shared by all the matchers contained.
403 std::unique_ptr
<PredicateMatcher
> Condition
= nullptr;
405 /// Temporary set used to check that the case values don't repeat within the
407 std::set
<MatchTableRecord
> Values
;
409 /// An owning collection for any auxiliary matchers created while optimizing
410 /// nested matchers contained.
411 std::vector
<std::unique_ptr
<Matcher
>> MatcherStorage
;
414 bool addMatcher(Matcher
&Candidate
);
417 void emit(MatchTable
&Table
) override
;
419 iterator_range
<std::vector
<Matcher
*>::iterator
> matchers() {
420 return make_range(Matchers
.begin(), Matchers
.end());
422 size_t size() const { return Matchers
.size(); }
423 bool empty() const { return Matchers
.empty(); }
425 std::unique_ptr
<PredicateMatcher
> popFirstCondition() override
{
426 // SwitchMatcher doesn't have a common first condition for its cases, as all
427 // the cases only share a kind of a value (a type and a path to it) they
428 // match, but deliberately differ in the actual value they match.
429 llvm_unreachable("Trying to pop a condition from a condition-less group");
432 const PredicateMatcher
&getFirstCondition() const override
{
433 llvm_unreachable("Trying to pop a condition from a condition-less group");
436 bool hasFirstCondition() const override
{ return false; }
439 /// See if the predicate type has a Switch-implementation for it.
440 static bool isSupportedPredicateType(const PredicateMatcher
&Predicate
);
442 bool candidateConditionMatches(const PredicateMatcher
&Predicate
) const;
445 static void emitPredicateSpecificOpcodes(const PredicateMatcher
&P
,
449 /// Generates code to check that a match rule matches.
450 class RuleMatcher
: public Matcher
{
452 using ActionList
= std::list
<std::unique_ptr
<MatchAction
>>;
453 using action_iterator
= ActionList::iterator
;
456 /// A list of matchers that all need to succeed for the current rule to match.
457 /// FIXME: This currently supports a single match position but could be
458 /// extended to support multiple positions to support div/rem fusion or
459 /// load-multiple instructions.
460 using MatchersTy
= std::vector
<std::unique_ptr
<InstructionMatcher
>>;
463 /// A list of actions that need to be taken when all predicates in this rule
467 using DefinedInsnVariablesMap
= std::map
<InstructionMatcher
*, unsigned>;
469 /// A map of instruction matchers to the local variables
470 DefinedInsnVariablesMap InsnVariableIDs
;
472 using MutatableInsnSet
= SmallPtrSet
<InstructionMatcher
*, 4>;
474 // The set of instruction matchers that have not yet been claimed for mutation
476 MutatableInsnSet MutatableInsns
;
478 /// A map of named operands defined by the matchers that may be referenced by
480 StringMap
<OperandMatcher
*> DefinedOperands
;
482 /// A map of anonymous physical register operands defined by the matchers that
483 /// may be referenced by the renderers.
484 DenseMap
<Record
*, OperandMatcher
*> PhysRegOperands
;
486 /// ID for the next instruction variable defined with
487 /// implicitlyDefineInsnVar()
488 unsigned NextInsnVarID
;
490 /// ID for the next output instruction allocated with allocateOutputInsnID()
491 unsigned NextOutputInsnID
;
493 /// ID for the next temporary register ID allocated with allocateTempRegID()
494 unsigned NextTempRegID
;
496 /// ID for the next recorded type. Starts at -1 and counts down.
497 TempTypeIdx NextTempTypeIdx
= -1;
499 // HwMode predicate index for this rule. -1 if no HwMode.
502 /// Current GISelFlags
503 GISelFlags Flags
= 0;
505 std::vector
<std::string
> RequiredSimplePredicates
;
506 std::vector
<Record
*> RequiredFeatures
;
507 std::vector
<std::unique_ptr
<PredicateMatcher
>> EpilogueMatchers
;
509 DenseSet
<unsigned> ErasedInsnIDs
;
511 ArrayRef
<SMLoc
> SrcLoc
;
513 typedef std::tuple
<Record
*, unsigned, unsigned>
514 DefinedComplexPatternSubOperand
;
515 typedef StringMap
<DefinedComplexPatternSubOperand
>
516 DefinedComplexPatternSubOperandMap
;
517 /// A map of Symbolic Names to ComplexPattern sub-operands.
518 DefinedComplexPatternSubOperandMap ComplexSubOperands
;
519 /// A map used to for multiple referenced error check of ComplexSubOperand.
520 /// ComplexSubOperand can't be referenced multiple from different operands,
521 /// however multiple references from same operand are allowed since that is
522 /// how 'same operand checks' are generated.
523 StringMap
<std::string
> ComplexSubOperandsParentName
;
526 static uint64_t NextRuleID
;
528 GISelFlags
updateGISelFlag(GISelFlags CurFlags
, const Record
*R
,
529 StringRef FlagName
, GISelFlags FlagBit
);
532 RuleMatcher(ArrayRef
<SMLoc
> SrcLoc
)
533 : NextInsnVarID(0), NextOutputInsnID(0), NextTempRegID(0), SrcLoc(SrcLoc
),
534 RuleID(NextRuleID
++) {}
535 RuleMatcher(RuleMatcher
&&Other
) = default;
536 RuleMatcher
&operator=(RuleMatcher
&&Other
) = default;
538 TempTypeIdx
getNextTempTypeIdx() { return NextTempTypeIdx
--; }
540 uint64_t getRuleID() const { return RuleID
; }
542 InstructionMatcher
&addInstructionMatcher(StringRef SymbolicName
);
543 void addRequiredFeature(Record
*Feature
);
544 const std::vector
<Record
*> &getRequiredFeatures() const;
546 void addHwModeIdx(unsigned Idx
) { HwModeIdx
= Idx
; }
547 int getHwModeIdx() const { return HwModeIdx
; }
549 void addRequiredSimplePredicate(StringRef PredName
);
550 const std::vector
<std::string
> &getRequiredSimplePredicates();
552 /// Attempts to mark \p ID as erased (GIR_EraseFromParent called on it).
553 /// If \p ID has already been erased, returns false and GIR_EraseFromParent
554 /// should NOT be emitted.
555 bool tryEraseInsnID(unsigned ID
) { return ErasedInsnIDs
.insert(ID
).second
; }
557 // Emplaces an action of the specified Kind at the end of the action list.
559 // Returns a reference to the newly created action.
561 // Like std::vector::emplace_back(), may invalidate all iterators if the new
562 // size exceeds the capacity. Otherwise, only invalidates the past-the-end
564 template <class Kind
, class... Args
> Kind
&addAction(Args
&&...args
) {
565 Actions
.emplace_back(std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
566 return *static_cast<Kind
*>(Actions
.back().get());
569 // Emplaces an action of the specified Kind before the given insertion point.
571 // Returns an iterator pointing at the newly created instruction.
573 // Like std::vector::insert(), may invalidate all iterators if the new size
574 // exceeds the capacity. Otherwise, only invalidates the iterators from the
575 // insertion point onwards.
576 template <class Kind
, class... Args
>
577 action_iterator
insertAction(action_iterator InsertPt
, Args
&&...args
) {
578 return Actions
.emplace(InsertPt
,
579 std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
582 void setPermanentGISelFlags(GISelFlags V
) { Flags
= V
; }
584 // Update the active GISelFlags based on the GISelFlags Record R.
585 // A SaveAndRestore object is returned so the old GISelFlags are restored
586 // at the end of the scope.
587 SaveAndRestore
<GISelFlags
> setGISelFlags(const Record
*R
);
588 GISelFlags
getGISelFlags() const { return Flags
; }
590 /// Define an instruction without emitting any code to do so.
591 unsigned implicitlyDefineInsnVar(InstructionMatcher
&Matcher
);
593 unsigned getInsnVarID(InstructionMatcher
&InsnMatcher
) const;
594 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_begin() const {
595 return InsnVariableIDs
.begin();
597 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_end() const {
598 return InsnVariableIDs
.end();
600 iterator_range
<typename
DefinedInsnVariablesMap::const_iterator
>
601 defined_insn_vars() const {
602 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
605 MutatableInsnSet::const_iterator
mutatable_insns_begin() const {
606 return MutatableInsns
.begin();
608 MutatableInsnSet::const_iterator
mutatable_insns_end() const {
609 return MutatableInsns
.end();
611 iterator_range
<typename
MutatableInsnSet::const_iterator
>
612 mutatable_insns() const {
613 return make_range(mutatable_insns_begin(), mutatable_insns_end());
615 void reserveInsnMatcherForMutation(InstructionMatcher
*InsnMatcher
) {
616 bool R
= MutatableInsns
.erase(InsnMatcher
);
617 assert(R
&& "Reserving a mutatable insn that isn't available");
621 action_iterator
actions_begin() { return Actions
.begin(); }
622 action_iterator
actions_end() { return Actions
.end(); }
623 iterator_range
<action_iterator
> actions() {
624 return make_range(actions_begin(), actions_end());
627 void defineOperand(StringRef SymbolicName
, OperandMatcher
&OM
);
629 void definePhysRegOperand(Record
*Reg
, OperandMatcher
&OM
);
631 Error
defineComplexSubOperand(StringRef SymbolicName
, Record
*ComplexPattern
,
632 unsigned RendererID
, unsigned SubOperandID
,
633 StringRef ParentSymbolicName
);
635 std::optional
<DefinedComplexPatternSubOperand
>
636 getComplexSubOperand(StringRef SymbolicName
) const {
637 const auto &I
= ComplexSubOperands
.find(SymbolicName
);
638 if (I
== ComplexSubOperands
.end())
643 InstructionMatcher
&getInstructionMatcher(StringRef SymbolicName
) const;
644 OperandMatcher
&getOperandMatcher(StringRef Name
);
645 const OperandMatcher
&getOperandMatcher(StringRef Name
) const;
646 const OperandMatcher
&getPhysRegOperandMatcher(Record
*) const;
648 void optimize() override
;
649 void emit(MatchTable
&Table
) override
;
651 /// Compare the priority of this object and B.
653 /// Returns true if this object is more important than B.
654 bool isHigherPriorityThan(const RuleMatcher
&B
) const;
656 /// Report the maximum number of temporary operands needed by the rule
658 unsigned countRendererFns() const;
660 std::unique_ptr
<PredicateMatcher
> popFirstCondition() override
;
661 const PredicateMatcher
&getFirstCondition() const override
;
662 LLTCodeGen
getFirstConditionAsRootType();
663 bool hasFirstCondition() const override
;
664 unsigned getNumOperands() const;
665 StringRef
getOpcode() const;
667 // FIXME: Remove this as soon as possible
668 InstructionMatcher
&insnmatchers_front() const { return *Matchers
.front(); }
670 unsigned allocateOutputInsnID() { return NextOutputInsnID
++; }
671 unsigned allocateTempRegID() { return NextTempRegID
++; }
673 iterator_range
<MatchersTy::iterator
> insnmatchers() {
674 return make_range(Matchers
.begin(), Matchers
.end());
676 bool insnmatchers_empty() const { return Matchers
.empty(); }
677 void insnmatchers_pop_front() { Matchers
.erase(Matchers
.begin()); }
680 template <class PredicateTy
> class PredicateListMatcher
{
682 /// Template instantiations should specialize this to return a string to use
683 /// for the comment emitted when there are no predicates.
684 std::string
getNoPredicateComment() const;
687 using PredicatesTy
= std::deque
<std::unique_ptr
<PredicateTy
>>;
688 PredicatesTy Predicates
;
690 /// Track if the list of predicates was manipulated by one of the optimization
692 bool Optimized
= false;
695 typename
PredicatesTy::iterator
predicates_begin() {
696 return Predicates
.begin();
698 typename
PredicatesTy::iterator
predicates_end() { return Predicates
.end(); }
699 iterator_range
<typename
PredicatesTy::iterator
> predicates() {
700 return make_range(predicates_begin(), predicates_end());
702 typename
PredicatesTy::size_type
predicates_size() const {
703 return Predicates
.size();
705 bool predicates_empty() const { return Predicates
.empty(); }
707 template <typename Ty
> bool contains() const {
708 return any_of(Predicates
, [&](auto &P
) { return isa
<Ty
>(P
.get()); });
711 std::unique_ptr
<PredicateTy
> predicates_pop_front() {
712 std::unique_ptr
<PredicateTy
> Front
= std::move(Predicates
.front());
713 Predicates
.pop_front();
718 void prependPredicate(std::unique_ptr
<PredicateTy
> &&Predicate
) {
719 Predicates
.push_front(std::move(Predicate
));
722 void eraseNullPredicates() {
724 std::stable_partition(Predicates
.begin(), Predicates
.end(),
725 std::logical_not
<std::unique_ptr
<PredicateTy
>>());
726 if (NewEnd
!= Predicates
.begin()) {
727 Predicates
.erase(Predicates
.begin(), NewEnd
);
732 /// Emit MatchTable opcodes that tests whether all the predicates are met.
733 template <class... Args
>
734 void emitPredicateListOpcodes(MatchTable
&Table
, Args
&&...args
) {
735 if (Predicates
.empty() && !Optimized
) {
736 Table
<< MatchTable::Comment(getNoPredicateComment())
737 << MatchTable::LineBreak
;
741 for (const auto &Predicate
: predicates())
742 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
745 /// Provide a function to avoid emitting certain predicates. This is used to
746 /// defer some predicate checks until after others
747 using PredicateFilterFunc
= std::function
<bool(const PredicateTy
&)>;
749 /// Emit MatchTable opcodes for predicates which satisfy \p
750 /// ShouldEmitPredicate. This should be called multiple times to ensure all
751 /// predicates are eventually added to the match table.
752 template <class... Args
>
753 void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate
,
754 MatchTable
&Table
, Args
&&...args
) {
755 if (Predicates
.empty() && !Optimized
) {
756 Table
<< MatchTable::Comment(getNoPredicateComment())
757 << MatchTable::LineBreak
;
761 for (const auto &Predicate
: predicates()) {
762 if (ShouldEmitPredicate(*Predicate
))
763 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
768 class PredicateMatcher
{
770 /// This enum is used for RTTI and also defines the priority that is given to
771 /// the predicate when generating the matcher code. Kinds with higher priority
772 /// must be tested first.
774 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
775 /// but OPM_Int must have priority over OPM_RegBank since constant integers
776 /// are represented by a virtual register defined by a G_CONSTANT instruction.
778 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
779 /// are currently not compared between each other.
785 IPM_AtomicOrderingMMO
,
788 IPM_MemoryAddressSpace
,
792 IPM_GenericPredicate
,
804 OPM_RecordNamedOperand
,
814 PredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
, unsigned OpIdx
= ~0)
815 : Kind(Kind
), InsnVarID(InsnVarID
), OpIdx(OpIdx
) {}
816 virtual ~PredicateMatcher();
818 unsigned getInsnVarID() const { return InsnVarID
; }
819 unsigned getOpIdx() const { return OpIdx
; }
821 /// Emit MatchTable opcodes that check the predicate for the given operand.
822 virtual void emitPredicateOpcodes(MatchTable
&Table
,
823 RuleMatcher
&Rule
) const = 0;
825 PredicateKind
getKind() const { return Kind
; }
827 bool dependsOnOperands() const {
828 // Custom predicates really depend on the context pattern of the
829 // instruction, not just the individual instruction. This therefore
830 // implicitly depends on all other pattern constraints.
831 return Kind
== IPM_GenericPredicate
;
834 virtual bool isIdentical(const PredicateMatcher
&B
) const {
835 return B
.getKind() == getKind() && InsnVarID
== B
.InsnVarID
&&
839 virtual bool isIdenticalDownToValue(const PredicateMatcher
&B
) const {
840 return hasValue() && PredicateMatcher::isIdentical(B
);
843 virtual MatchTableRecord
getValue() const {
844 assert(hasValue() && "Can not get a value of a value-less predicate!");
845 llvm_unreachable("Not implemented yet");
847 virtual bool hasValue() const { return false; }
849 /// Report the maximum number of temporary operands needed by the predicate
851 virtual unsigned countRendererFns() const { return 0; }
854 /// Generates code to check a predicate of an operand.
856 /// Typical predicates include:
857 /// * Operand is a particular register.
858 /// * Operand is assigned a particular register bank.
859 /// * Operand is an MBB.
860 class OperandPredicateMatcher
: public PredicateMatcher
{
862 OperandPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
,
864 : PredicateMatcher(Kind
, InsnVarID
, OpIdx
) {}
865 virtual ~OperandPredicateMatcher();
867 /// Compare the priority of this object and B.
869 /// Returns true if this object is more important than B.
870 virtual bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const;
875 PredicateListMatcher
<OperandPredicateMatcher
>::getNoPredicateComment() const {
876 return "No operand predicates";
879 /// Generates code to check that a register operand is defined by the same exact
881 class SameOperandMatcher
: public OperandPredicateMatcher
{
882 std::string MatchingName
;
888 SameOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, StringRef MatchingName
,
889 unsigned OrigOpIdx
, GISelFlags Flags
)
890 : OperandPredicateMatcher(OPM_SameOperand
, InsnVarID
, OpIdx
),
891 MatchingName(MatchingName
), OrigOpIdx(OrigOpIdx
), Flags(Flags
) {}
893 static bool classof(const PredicateMatcher
*P
) {
894 return P
->getKind() == OPM_SameOperand
;
897 void emitPredicateOpcodes(MatchTable
&Table
,
898 RuleMatcher
&Rule
) const override
;
900 bool isIdentical(const PredicateMatcher
&B
) const override
{
901 return OperandPredicateMatcher::isIdentical(B
) &&
902 OrigOpIdx
== cast
<SameOperandMatcher
>(&B
)->OrigOpIdx
&&
903 MatchingName
== cast
<SameOperandMatcher
>(&B
)->MatchingName
;
907 /// Generates code to check that an operand is a particular LLT.
908 class LLTOperandMatcher
: public OperandPredicateMatcher
{
913 static std::map
<LLTCodeGen
, unsigned> TypeIDValues
;
915 static void initTypeIDValuesMap() {
916 TypeIDValues
.clear();
919 for (const LLTCodeGen
&LLTy
: KnownTypes
)
920 TypeIDValues
[LLTy
] = ID
++;
923 LLTOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, const LLTCodeGen
&Ty
)
924 : OperandPredicateMatcher(OPM_LLT
, InsnVarID
, OpIdx
), Ty(Ty
) {
925 KnownTypes
.insert(Ty
);
928 static bool classof(const PredicateMatcher
*P
) {
929 return P
->getKind() == OPM_LLT
;
932 bool isIdentical(const PredicateMatcher
&B
) const override
{
933 return OperandPredicateMatcher::isIdentical(B
) &&
934 Ty
== cast
<LLTOperandMatcher
>(&B
)->Ty
;
937 MatchTableRecord
getValue() const override
;
938 bool hasValue() const override
;
940 LLTCodeGen
getTy() const { return Ty
; }
942 void emitPredicateOpcodes(MatchTable
&Table
,
943 RuleMatcher
&Rule
) const override
;
946 /// Generates code to check that an operand is a pointer to any address space.
948 /// In SelectionDAG, the types did not describe pointers or address spaces. As a
949 /// result, iN is used to describe a pointer of N bits to any address space and
950 /// PatFrag predicates are typically used to constrain the address space.
951 /// There's no reliable means to derive the missing type information from the
952 /// pattern so imported rules must test the components of a pointer separately.
954 /// If SizeInBits is zero, then the pointer size will be obtained from the
956 class PointerToAnyOperandMatcher
: public OperandPredicateMatcher
{
961 PointerToAnyOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
963 : OperandPredicateMatcher(OPM_PointerToAny
, InsnVarID
, OpIdx
),
964 SizeInBits(SizeInBits
) {}
966 static bool classof(const PredicateMatcher
*P
) {
967 return P
->getKind() == OPM_PointerToAny
;
970 bool isIdentical(const PredicateMatcher
&B
) const override
{
971 return OperandPredicateMatcher::isIdentical(B
) &&
972 SizeInBits
== cast
<PointerToAnyOperandMatcher
>(&B
)->SizeInBits
;
975 void emitPredicateOpcodes(MatchTable
&Table
,
976 RuleMatcher
&Rule
) const override
;
979 /// Generates code to record named operand in RecordedOperands list at StoreIdx.
980 /// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
981 /// an argument to predicate's c++ code once all operands have been matched.
982 class RecordNamedOperandMatcher
: public OperandPredicateMatcher
{
988 RecordNamedOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
989 unsigned StoreIdx
, StringRef Name
)
990 : OperandPredicateMatcher(OPM_RecordNamedOperand
, InsnVarID
, OpIdx
),
991 StoreIdx(StoreIdx
), Name(Name
) {}
993 static bool classof(const PredicateMatcher
*P
) {
994 return P
->getKind() == OPM_RecordNamedOperand
;
997 bool isIdentical(const PredicateMatcher
&B
) const override
{
998 return OperandPredicateMatcher::isIdentical(B
) &&
999 StoreIdx
== cast
<RecordNamedOperandMatcher
>(&B
)->StoreIdx
&&
1000 Name
== cast
<RecordNamedOperandMatcher
>(&B
)->Name
;
1003 void emitPredicateOpcodes(MatchTable
&Table
,
1004 RuleMatcher
&Rule
) const override
;
1007 /// Generates code to store a register operand's type into the set of temporary
1009 class RecordRegisterType
: public OperandPredicateMatcher
{
1014 RecordRegisterType(unsigned InsnVarID
, unsigned OpIdx
, TempTypeIdx Idx
)
1015 : OperandPredicateMatcher(OPM_RecordRegType
, InsnVarID
, OpIdx
), Idx(Idx
) {
1018 static bool classof(const PredicateMatcher
*P
) {
1019 return P
->getKind() == OPM_RecordRegType
;
1022 bool isIdentical(const PredicateMatcher
&B
) const override
{
1023 return OperandPredicateMatcher::isIdentical(B
) &&
1024 Idx
== cast
<RecordRegisterType
>(&B
)->Idx
;
1027 void emitPredicateOpcodes(MatchTable
&Table
,
1028 RuleMatcher
&Rule
) const override
;
1031 /// Generates code to check that an operand is a particular target constant.
1032 class ComplexPatternOperandMatcher
: public OperandPredicateMatcher
{
1034 const OperandMatcher
&Operand
;
1035 const Record
&TheDef
;
1037 unsigned getAllocatedTemporariesBaseID() const;
1040 bool isIdentical(const PredicateMatcher
&B
) const override
{ return false; }
1042 ComplexPatternOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1043 const OperandMatcher
&Operand
,
1044 const Record
&TheDef
)
1045 : OperandPredicateMatcher(OPM_ComplexPattern
, InsnVarID
, OpIdx
),
1046 Operand(Operand
), TheDef(TheDef
) {}
1048 static bool classof(const PredicateMatcher
*P
) {
1049 return P
->getKind() == OPM_ComplexPattern
;
1052 void emitPredicateOpcodes(MatchTable
&Table
,
1053 RuleMatcher
&Rule
) const override
;
1054 unsigned countRendererFns() const override
{ return 1; }
1057 /// Generates code to check that an operand is in a particular register bank.
1058 class RegisterBankOperandMatcher
: public OperandPredicateMatcher
{
1060 const CodeGenRegisterClass
&RC
;
1063 RegisterBankOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1064 const CodeGenRegisterClass
&RC
)
1065 : OperandPredicateMatcher(OPM_RegBank
, InsnVarID
, OpIdx
), RC(RC
) {}
1067 bool isIdentical(const PredicateMatcher
&B
) const override
;
1069 static bool classof(const PredicateMatcher
*P
) {
1070 return P
->getKind() == OPM_RegBank
;
1073 void emitPredicateOpcodes(MatchTable
&Table
,
1074 RuleMatcher
&Rule
) const override
;
1077 /// Generates code to check that an operand is a basic block.
1078 class MBBOperandMatcher
: public OperandPredicateMatcher
{
1080 MBBOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1081 : OperandPredicateMatcher(OPM_MBB
, InsnVarID
, OpIdx
) {}
1083 static bool classof(const PredicateMatcher
*P
) {
1084 return P
->getKind() == OPM_MBB
;
1087 void emitPredicateOpcodes(MatchTable
&Table
,
1088 RuleMatcher
&Rule
) const override
;
1091 class ImmOperandMatcher
: public OperandPredicateMatcher
{
1093 ImmOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1094 : OperandPredicateMatcher(IPM_Imm
, InsnVarID
, OpIdx
) {}
1096 static bool classof(const PredicateMatcher
*P
) {
1097 return P
->getKind() == IPM_Imm
;
1100 void emitPredicateOpcodes(MatchTable
&Table
,
1101 RuleMatcher
&Rule
) const override
;
1104 /// Generates code to check that an operand is a G_CONSTANT with a particular
1106 class ConstantIntOperandMatcher
: public OperandPredicateMatcher
{
1111 ConstantIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1112 : OperandPredicateMatcher(OPM_Int
, InsnVarID
, OpIdx
), Value(Value
) {}
1114 bool isIdentical(const PredicateMatcher
&B
) const override
{
1115 return OperandPredicateMatcher::isIdentical(B
) &&
1116 Value
== cast
<ConstantIntOperandMatcher
>(&B
)->Value
;
1119 static bool classof(const PredicateMatcher
*P
) {
1120 return P
->getKind() == OPM_Int
;
1123 void emitPredicateOpcodes(MatchTable
&Table
,
1124 RuleMatcher
&Rule
) const override
;
1127 /// Generates code to check that an operand is a raw int (where MO.isImm() or
1128 /// MO.isCImm() is true).
1129 class LiteralIntOperandMatcher
: public OperandPredicateMatcher
{
1134 LiteralIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1135 : OperandPredicateMatcher(OPM_LiteralInt
, InsnVarID
, OpIdx
),
1138 bool isIdentical(const PredicateMatcher
&B
) const override
{
1139 return OperandPredicateMatcher::isIdentical(B
) &&
1140 Value
== cast
<LiteralIntOperandMatcher
>(&B
)->Value
;
1143 static bool classof(const PredicateMatcher
*P
) {
1144 return P
->getKind() == OPM_LiteralInt
;
1147 void emitPredicateOpcodes(MatchTable
&Table
,
1148 RuleMatcher
&Rule
) const override
;
1151 /// Generates code to check that an operand is an CmpInst predicate
1152 class CmpPredicateOperandMatcher
: public OperandPredicateMatcher
{
1154 std::string PredName
;
1157 CmpPredicateOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, std::string P
)
1158 : OperandPredicateMatcher(OPM_CmpPredicate
, InsnVarID
, OpIdx
),
1161 bool isIdentical(const PredicateMatcher
&B
) const override
{
1162 return OperandPredicateMatcher::isIdentical(B
) &&
1163 PredName
== cast
<CmpPredicateOperandMatcher
>(&B
)->PredName
;
1166 static bool classof(const PredicateMatcher
*P
) {
1167 return P
->getKind() == OPM_CmpPredicate
;
1170 void emitPredicateOpcodes(MatchTable
&Table
,
1171 RuleMatcher
&Rule
) const override
;
1174 /// Generates code to check that an operand is an intrinsic ID.
1175 class IntrinsicIDOperandMatcher
: public OperandPredicateMatcher
{
1177 const CodeGenIntrinsic
*II
;
1180 IntrinsicIDOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1181 const CodeGenIntrinsic
*II
)
1182 : OperandPredicateMatcher(OPM_IntrinsicID
, InsnVarID
, OpIdx
), II(II
) {}
1184 bool isIdentical(const PredicateMatcher
&B
) const override
{
1185 return OperandPredicateMatcher::isIdentical(B
) &&
1186 II
== cast
<IntrinsicIDOperandMatcher
>(&B
)->II
;
1189 static bool classof(const PredicateMatcher
*P
) {
1190 return P
->getKind() == OPM_IntrinsicID
;
1193 void emitPredicateOpcodes(MatchTable
&Table
,
1194 RuleMatcher
&Rule
) const override
;
1197 /// Generates code to check that this operand is an immediate whose value meets
1198 /// an immediate predicate.
1199 class OperandImmPredicateMatcher
: public OperandPredicateMatcher
{
1201 TreePredicateFn Predicate
;
1204 OperandImmPredicateMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1205 const TreePredicateFn
&Predicate
)
1206 : OperandPredicateMatcher(IPM_ImmPredicate
, InsnVarID
, OpIdx
),
1207 Predicate(Predicate
) {}
1209 bool isIdentical(const PredicateMatcher
&B
) const override
{
1210 return OperandPredicateMatcher::isIdentical(B
) &&
1211 Predicate
.getOrigPatFragRecord() ==
1212 cast
<OperandImmPredicateMatcher
>(&B
)
1213 ->Predicate
.getOrigPatFragRecord();
1216 static bool classof(const PredicateMatcher
*P
) {
1217 return P
->getKind() == IPM_ImmPredicate
;
1220 void emitPredicateOpcodes(MatchTable
&Table
,
1221 RuleMatcher
&Rule
) const override
;
1224 /// Generates code to check that a set of predicates match for a particular
1226 class OperandMatcher
: public PredicateListMatcher
<OperandPredicateMatcher
> {
1228 InstructionMatcher
&Insn
;
1230 std::string SymbolicName
;
1232 /// The index of the first temporary variable allocated to this operand. The
1233 /// number of allocated temporaries can be found with
1234 /// countRendererFns().
1235 unsigned AllocatedTemporariesBaseID
;
1237 TempTypeIdx TTIdx
= 0;
1240 OperandMatcher(InstructionMatcher
&Insn
, unsigned OpIdx
,
1241 const std::string
&SymbolicName
,
1242 unsigned AllocatedTemporariesBaseID
)
1243 : Insn(Insn
), OpIdx(OpIdx
), SymbolicName(SymbolicName
),
1244 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID
) {}
1246 bool hasSymbolicName() const { return !SymbolicName
.empty(); }
1247 StringRef
getSymbolicName() const { return SymbolicName
; }
1248 void setSymbolicName(StringRef Name
) {
1249 assert(SymbolicName
.empty() && "Operand already has a symbolic name");
1250 SymbolicName
= std::string(Name
);
1253 /// Construct a new operand predicate and add it to the matcher.
1254 template <class Kind
, class... Args
>
1255 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1256 if (isSameAsAnotherOperand())
1257 return std::nullopt
;
1258 Predicates
.emplace_back(std::make_unique
<Kind
>(
1259 getInsnVarID(), getOpIdx(), std::forward
<Args
>(args
)...));
1260 return static_cast<Kind
*>(Predicates
.back().get());
1263 unsigned getOpIdx() const { return OpIdx
; }
1264 unsigned getInsnVarID() const;
1266 /// If this OperandMatcher has not been assigned a TempTypeIdx yet, assigns it
1267 /// one and adds a `RecordRegisterType` predicate to this matcher. If one has
1268 /// already been assigned, simply returns it.
1269 TempTypeIdx
getTempTypeIdx(RuleMatcher
&Rule
);
1271 std::string
getOperandExpr(unsigned InsnVarID
) const;
1273 InstructionMatcher
&getInstructionMatcher() const { return Insn
; }
1275 Error
addTypeCheckPredicate(const TypeSetByHwMode
&VTy
,
1276 bool OperandIsAPointer
);
1278 /// Emit MatchTable opcodes that test whether the instruction named in
1279 /// InsnVarID matches all the predicates and all the operands.
1280 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1282 /// Compare the priority of this object and B.
1284 /// Returns true if this object is more important than B.
1285 bool isHigherPriorityThan(OperandMatcher
&B
);
1287 /// Report the maximum number of temporary operands needed by the operand
1289 unsigned countRendererFns();
1291 unsigned getAllocatedTemporariesBaseID() const {
1292 return AllocatedTemporariesBaseID
;
1295 bool isSameAsAnotherOperand() {
1296 for (const auto &Predicate
: predicates())
1297 if (isa
<SameOperandMatcher
>(Predicate
))
1303 /// Generates code to check a predicate on an instruction.
1305 /// Typical predicates include:
1306 /// * The opcode of the instruction is a particular value.
1307 /// * The nsw/nuw flag is/isn't set.
1308 class InstructionPredicateMatcher
: public PredicateMatcher
{
1310 InstructionPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
)
1311 : PredicateMatcher(Kind
, InsnVarID
) {}
1312 virtual ~InstructionPredicateMatcher() {}
1314 /// Compare the priority of this object and B.
1316 /// Returns true if this object is more important than B.
1318 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const {
1319 return Kind
< B
.Kind
;
1325 PredicateListMatcher
<PredicateMatcher
>::getNoPredicateComment() const {
1326 return "No instruction predicates";
1329 /// Generates code to check the opcode of an instruction.
1330 class InstructionOpcodeMatcher
: public InstructionPredicateMatcher
{
1332 // Allow matching one to several, similar opcodes that share properties. This
1333 // is to handle patterns where one SelectionDAG operation maps to multiple
1334 // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
1335 // is treated as the canonical opcode.
1336 SmallVector
<const CodeGenInstruction
*, 2> Insts
;
1338 static DenseMap
<const CodeGenInstruction
*, unsigned> OpcodeValues
;
1340 MatchTableRecord
getInstValue(const CodeGenInstruction
*I
) const;
1343 static void initOpcodeValuesMap(const CodeGenTarget
&Target
);
1345 InstructionOpcodeMatcher(unsigned InsnVarID
,
1346 ArrayRef
<const CodeGenInstruction
*> I
)
1347 : InstructionPredicateMatcher(IPM_Opcode
, InsnVarID
),
1348 Insts(I
.begin(), I
.end()) {
1349 assert((Insts
.size() == 1 || Insts
.size() == 2) &&
1350 "unexpected number of opcode alternatives");
1353 static bool classof(const PredicateMatcher
*P
) {
1354 return P
->getKind() == IPM_Opcode
;
1357 bool isIdentical(const PredicateMatcher
&B
) const override
{
1358 return InstructionPredicateMatcher::isIdentical(B
) &&
1359 Insts
== cast
<InstructionOpcodeMatcher
>(&B
)->Insts
;
1362 bool hasValue() const override
{
1363 return Insts
.size() == 1 && OpcodeValues
.count(Insts
[0]);
1366 // TODO: This is used for the SwitchMatcher optimization. We should be able to
1367 // return a list of the opcodes to match.
1368 MatchTableRecord
getValue() const override
;
1370 void emitPredicateOpcodes(MatchTable
&Table
,
1371 RuleMatcher
&Rule
) const override
;
1373 /// Compare the priority of this object and B.
1375 /// Returns true if this object is more important than B.
1377 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const override
;
1379 bool isConstantInstruction() const;
1381 // The first opcode is the canonical opcode, and later are alternatives.
1382 StringRef
getOpcode() const;
1383 ArrayRef
<const CodeGenInstruction
*> getAlternativeOpcodes() { return Insts
; }
1384 bool isVariadicNumOperands() const;
1385 StringRef
getOperandType(unsigned OpIdx
) const;
1388 class InstructionNumOperandsMatcher final
: public InstructionPredicateMatcher
{
1389 unsigned NumOperands
= 0;
1392 InstructionNumOperandsMatcher(unsigned InsnVarID
, unsigned NumOperands
)
1393 : InstructionPredicateMatcher(IPM_NumOperands
, InsnVarID
),
1394 NumOperands(NumOperands
) {}
1396 static bool classof(const PredicateMatcher
*P
) {
1397 return P
->getKind() == IPM_NumOperands
;
1400 bool isIdentical(const PredicateMatcher
&B
) const override
{
1401 return InstructionPredicateMatcher::isIdentical(B
) &&
1402 NumOperands
== cast
<InstructionNumOperandsMatcher
>(&B
)->NumOperands
;
1405 void emitPredicateOpcodes(MatchTable
&Table
,
1406 RuleMatcher
&Rule
) const override
;
1409 /// Generates code to check that this instruction is a constant whose value
1410 /// meets an immediate predicate.
1412 /// Immediates are slightly odd since they are typically used like an operand
1413 /// but are represented as an operator internally. We typically write simm8:$src
1414 /// in a tablegen pattern, but this is just syntactic sugar for
1415 /// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1416 /// that will be matched and the predicate (which is attached to the imm
1417 /// operator) that will be tested. In SelectionDAG this describes a
1418 /// ConstantSDNode whose internal value will be tested using the simm8
1421 /// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1422 /// this representation, the immediate could be tested with an
1423 /// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1424 /// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1425 /// there are two implementation issues with producing that matcher
1426 /// configuration from the SelectionDAG pattern:
1427 /// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1428 /// were we to sink the immediate predicate to the operand we would have to
1429 /// have two partial implementations of PatFrag support, one for immediates
1430 /// and one for non-immediates.
1431 /// * At the point we handle the predicate, the OperandMatcher hasn't been
1432 /// created yet. If we were to sink the predicate to the OperandMatcher we
1433 /// would also have to complicate (or duplicate) the code that descends and
1434 /// creates matchers for the subtree.
1435 /// Overall, it's simpler to handle it in the place it was found.
1436 class InstructionImmPredicateMatcher
: public InstructionPredicateMatcher
{
1438 TreePredicateFn Predicate
;
1441 InstructionImmPredicateMatcher(unsigned InsnVarID
,
1442 const TreePredicateFn
&Predicate
)
1443 : InstructionPredicateMatcher(IPM_ImmPredicate
, InsnVarID
),
1444 Predicate(Predicate
) {}
1446 bool isIdentical(const PredicateMatcher
&B
) const override
;
1448 static bool classof(const PredicateMatcher
*P
) {
1449 return P
->getKind() == IPM_ImmPredicate
;
1452 void emitPredicateOpcodes(MatchTable
&Table
,
1453 RuleMatcher
&Rule
) const override
;
1456 /// Generates code to check that a memory instruction has a atomic ordering
1457 /// MachineMemoryOperand.
1458 class AtomicOrderingMMOPredicateMatcher
: public InstructionPredicateMatcher
{
1468 AOComparator Comparator
;
1471 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID
, StringRef Order
,
1472 AOComparator Comparator
= AO_Exactly
)
1473 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO
, InsnVarID
),
1474 Order(Order
), Comparator(Comparator
) {}
1476 static bool classof(const PredicateMatcher
*P
) {
1477 return P
->getKind() == IPM_AtomicOrderingMMO
;
1480 bool isIdentical(const PredicateMatcher
&B
) const override
;
1482 void emitPredicateOpcodes(MatchTable
&Table
,
1483 RuleMatcher
&Rule
) const override
;
1486 /// Generates code to check that the size of an MMO is exactly N bytes.
1487 class MemorySizePredicateMatcher
: public InstructionPredicateMatcher
{
1493 MemorySizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
, unsigned Size
)
1494 : InstructionPredicateMatcher(IPM_MemoryLLTSize
, InsnVarID
),
1495 MMOIdx(MMOIdx
), Size(Size
) {}
1497 static bool classof(const PredicateMatcher
*P
) {
1498 return P
->getKind() == IPM_MemoryLLTSize
;
1500 bool isIdentical(const PredicateMatcher
&B
) const override
{
1501 return InstructionPredicateMatcher::isIdentical(B
) &&
1502 MMOIdx
== cast
<MemorySizePredicateMatcher
>(&B
)->MMOIdx
&&
1503 Size
== cast
<MemorySizePredicateMatcher
>(&B
)->Size
;
1506 void emitPredicateOpcodes(MatchTable
&Table
,
1507 RuleMatcher
&Rule
) const override
;
1510 class MemoryAddressSpacePredicateMatcher
: public InstructionPredicateMatcher
{
1513 SmallVector
<unsigned, 4> AddrSpaces
;
1516 MemoryAddressSpacePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1517 ArrayRef
<unsigned> AddrSpaces
)
1518 : InstructionPredicateMatcher(IPM_MemoryAddressSpace
, InsnVarID
),
1519 MMOIdx(MMOIdx
), AddrSpaces(AddrSpaces
.begin(), AddrSpaces
.end()) {}
1521 static bool classof(const PredicateMatcher
*P
) {
1522 return P
->getKind() == IPM_MemoryAddressSpace
;
1525 bool isIdentical(const PredicateMatcher
&B
) const override
;
1527 void emitPredicateOpcodes(MatchTable
&Table
,
1528 RuleMatcher
&Rule
) const override
;
1531 class MemoryAlignmentPredicateMatcher
: public InstructionPredicateMatcher
{
1537 MemoryAlignmentPredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1539 : InstructionPredicateMatcher(IPM_MemoryAlignment
, InsnVarID
),
1540 MMOIdx(MMOIdx
), MinAlign(MinAlign
) {
1541 assert(MinAlign
> 0);
1544 static bool classof(const PredicateMatcher
*P
) {
1545 return P
->getKind() == IPM_MemoryAlignment
;
1548 bool isIdentical(const PredicateMatcher
&B
) const override
;
1550 void emitPredicateOpcodes(MatchTable
&Table
,
1551 RuleMatcher
&Rule
) const override
;
1554 /// Generates code to check that the size of an MMO is less-than, equal-to, or
1555 /// greater than a given LLT.
1556 class MemoryVsLLTSizePredicateMatcher
: public InstructionPredicateMatcher
{
1566 RelationKind Relation
;
1570 MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1571 enum RelationKind Relation
, unsigned OpIdx
)
1572 : InstructionPredicateMatcher(IPM_MemoryVsLLTSize
, InsnVarID
),
1573 MMOIdx(MMOIdx
), Relation(Relation
), OpIdx(OpIdx
) {}
1575 static bool classof(const PredicateMatcher
*P
) {
1576 return P
->getKind() == IPM_MemoryVsLLTSize
;
1578 bool isIdentical(const PredicateMatcher
&B
) const override
;
1580 void emitPredicateOpcodes(MatchTable
&Table
,
1581 RuleMatcher
&Rule
) const override
;
1584 // Matcher for immAllOnesV/immAllZerosV
1585 class VectorSplatImmPredicateMatcher
: public InstructionPredicateMatcher
{
1587 enum SplatKind
{ AllZeros
, AllOnes
};
1593 VectorSplatImmPredicateMatcher(unsigned InsnVarID
, SplatKind K
)
1594 : InstructionPredicateMatcher(IPM_VectorSplatImm
, InsnVarID
), Kind(K
) {}
1596 static bool classof(const PredicateMatcher
*P
) {
1597 return P
->getKind() == IPM_VectorSplatImm
;
1600 bool isIdentical(const PredicateMatcher
&B
) const override
{
1601 return InstructionPredicateMatcher::isIdentical(B
) &&
1602 Kind
== static_cast<const VectorSplatImmPredicateMatcher
&>(B
).Kind
;
1605 void emitPredicateOpcodes(MatchTable
&Table
,
1606 RuleMatcher
&Rule
) const override
;
1609 /// Generates code to check an arbitrary C++ instruction predicate.
1610 class GenericInstructionPredicateMatcher
: public InstructionPredicateMatcher
{
1612 std::string EnumVal
;
1615 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1616 TreePredicateFn Predicate
);
1618 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1619 const std::string
&EnumVal
)
1620 : InstructionPredicateMatcher(IPM_GenericPredicate
, InsnVarID
),
1623 static bool classof(const InstructionPredicateMatcher
*P
) {
1624 return P
->getKind() == IPM_GenericPredicate
;
1626 bool isIdentical(const PredicateMatcher
&B
) const override
;
1627 void emitPredicateOpcodes(MatchTable
&Table
,
1628 RuleMatcher
&Rule
) const override
;
1631 /// Generates code to check for the absence of use of the result.
1632 // TODO? Generalize this to support checking for one use.
1633 class NoUsePredicateMatcher
: public InstructionPredicateMatcher
{
1635 NoUsePredicateMatcher(unsigned InsnVarID
)
1636 : InstructionPredicateMatcher(IPM_NoUse
, InsnVarID
) {}
1638 static bool classof(const PredicateMatcher
*P
) {
1639 return P
->getKind() == IPM_NoUse
;
1642 bool isIdentical(const PredicateMatcher
&B
) const override
{
1643 return InstructionPredicateMatcher::isIdentical(B
);
1646 void emitPredicateOpcodes(MatchTable
&Table
,
1647 RuleMatcher
&Rule
) const override
{
1648 Table
<< MatchTable::Opcode("GIM_CheckHasNoUse")
1649 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID
)
1650 << MatchTable::LineBreak
;
1654 /// Generates code to check that a set of predicates and operands match for a
1655 /// particular instruction.
1657 /// Typical predicates include:
1658 /// * Has a specific opcode.
1659 /// * Has an nsw/nuw flag or doesn't.
1660 class InstructionMatcher final
: public PredicateListMatcher
<PredicateMatcher
> {
1662 typedef std::vector
<std::unique_ptr
<OperandMatcher
>> OperandVec
;
1666 /// The operands to match. All rendered operands must be present even if the
1667 /// condition is always true.
1668 OperandVec Operands
;
1669 bool NumOperandsCheck
= true;
1671 std::string SymbolicName
;
1674 /// PhysRegInputs - List list has an entry for each explicitly specified
1675 /// physreg input to the pattern. The first elt is the Register node, the
1676 /// second is the recorded slot number the input pattern match saved it in.
1677 SmallVector
<std::pair
<Record
*, unsigned>, 2> PhysRegInputs
;
1680 InstructionMatcher(RuleMatcher
&Rule
, StringRef SymbolicName
,
1681 bool NumOpsCheck
= true)
1682 : Rule(Rule
), NumOperandsCheck(NumOpsCheck
), SymbolicName(SymbolicName
) {
1683 // We create a new instruction matcher.
1684 // Get a new ID for that instruction.
1685 InsnVarID
= Rule
.implicitlyDefineInsnVar(*this);
1688 /// Construct a new instruction predicate and add it to the matcher.
1689 template <class Kind
, class... Args
>
1690 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1691 Predicates
.emplace_back(
1692 std::make_unique
<Kind
>(getInsnVarID(), std::forward
<Args
>(args
)...));
1693 return static_cast<Kind
*>(Predicates
.back().get());
1696 RuleMatcher
&getRuleMatcher() const { return Rule
; }
1698 unsigned getInsnVarID() const { return InsnVarID
; }
1700 /// Add an operand to the matcher.
1701 OperandMatcher
&addOperand(unsigned OpIdx
, const std::string
&SymbolicName
,
1702 unsigned AllocatedTemporariesBaseID
);
1703 OperandMatcher
&getOperand(unsigned OpIdx
);
1704 OperandMatcher
&addPhysRegInput(Record
*Reg
, unsigned OpIdx
,
1705 unsigned TempOpIdx
);
1707 ArrayRef
<std::pair
<Record
*, unsigned>> getPhysRegInputs() const {
1708 return PhysRegInputs
;
1711 StringRef
getSymbolicName() const { return SymbolicName
; }
1712 unsigned getNumOperands() const { return Operands
.size(); }
1713 OperandVec::iterator
operands_begin() { return Operands
.begin(); }
1714 OperandVec::iterator
operands_end() { return Operands
.end(); }
1715 iterator_range
<OperandVec::iterator
> operands() {
1716 return make_range(operands_begin(), operands_end());
1718 OperandVec::const_iterator
operands_begin() const { return Operands
.begin(); }
1719 OperandVec::const_iterator
operands_end() const { return Operands
.end(); }
1720 iterator_range
<OperandVec::const_iterator
> operands() const {
1721 return make_range(operands_begin(), operands_end());
1723 bool operands_empty() const { return Operands
.empty(); }
1725 void pop_front() { Operands
.erase(Operands
.begin()); }
1729 /// Emit MatchTable opcodes that test whether the instruction named in
1730 /// InsnVarName matches all the predicates and all the operands.
1731 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1733 /// Compare the priority of this object and B.
1735 /// Returns true if this object is more important than B.
1736 bool isHigherPriorityThan(InstructionMatcher
&B
);
1738 /// Report the maximum number of temporary operands needed by the instruction
1740 unsigned countRendererFns();
1742 InstructionOpcodeMatcher
&getOpcodeMatcher() {
1743 for (auto &P
: predicates())
1744 if (auto *OpMatcher
= dyn_cast
<InstructionOpcodeMatcher
>(P
.get()))
1746 llvm_unreachable("Didn't find an opcode matcher");
1749 bool isConstantInstruction() {
1750 return getOpcodeMatcher().isConstantInstruction();
1753 StringRef
getOpcode() { return getOpcodeMatcher().getOpcode(); }
1756 /// Generates code to check that the operand is a register defined by an
1757 /// instruction that matches the given instruction matcher.
1759 /// For example, the pattern:
1760 /// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1761 /// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1763 /// (G_ADD $src1, $src2)
1765 class InstructionOperandMatcher
: public OperandPredicateMatcher
{
1767 std::unique_ptr
<InstructionMatcher
> InsnMatcher
;
1772 InstructionOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1773 RuleMatcher
&Rule
, StringRef SymbolicName
,
1774 bool NumOpsCheck
= true)
1775 : OperandPredicateMatcher(OPM_Instruction
, InsnVarID
, OpIdx
),
1776 InsnMatcher(new InstructionMatcher(Rule
, SymbolicName
, NumOpsCheck
)),
1777 Flags(Rule
.getGISelFlags()) {}
1779 static bool classof(const PredicateMatcher
*P
) {
1780 return P
->getKind() == OPM_Instruction
;
1783 InstructionMatcher
&getInsnMatcher() const { return *InsnMatcher
; }
1785 void emitCaptureOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const;
1786 void emitPredicateOpcodes(MatchTable
&Table
,
1787 RuleMatcher
&Rule
) const override
{
1788 emitCaptureOpcodes(Table
, Rule
);
1789 InsnMatcher
->emitPredicateOpcodes(Table
, Rule
);
1792 bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const override
;
1794 /// Report the maximum number of temporary operands needed by the predicate
1796 unsigned countRendererFns() const override
{
1797 return InsnMatcher
->countRendererFns();
1801 //===- Actions ------------------------------------------------------------===//
1802 class OperandRenderer
{
1806 OR_CopyOrAddZeroReg
,
1809 OR_CopyConstantAsImm
,
1810 OR_CopyFConstantAsFPImm
,
1824 OperandRenderer(RendererKind Kind
) : Kind(Kind
) {}
1825 virtual ~OperandRenderer();
1827 RendererKind
getKind() const { return Kind
; }
1829 virtual void emitRenderOpcodes(MatchTable
&Table
,
1830 RuleMatcher
&Rule
) const = 0;
1833 /// A CopyRenderer emits code to copy a single operand from an existing
1834 /// instruction to the one being built.
1835 class CopyRenderer
: public OperandRenderer
{
1838 /// The name of the operand.
1839 const StringRef SymbolicName
;
1842 CopyRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1843 : OperandRenderer(OR_Copy
), NewInsnID(NewInsnID
),
1844 SymbolicName(SymbolicName
) {
1845 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
1848 static bool classof(const OperandRenderer
*R
) {
1849 return R
->getKind() == OR_Copy
;
1852 StringRef
getSymbolicName() const { return SymbolicName
; }
1854 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1857 /// A CopyRenderer emits code to copy a virtual register to a specific physical
1859 class CopyPhysRegRenderer
: public OperandRenderer
{
1865 CopyPhysRegRenderer(unsigned NewInsnID
, Record
*Reg
)
1866 : OperandRenderer(OR_CopyPhysReg
), NewInsnID(NewInsnID
), PhysReg(Reg
) {
1870 static bool classof(const OperandRenderer
*R
) {
1871 return R
->getKind() == OR_CopyPhysReg
;
1874 Record
*getPhysReg() const { return PhysReg
; }
1876 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1879 /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1880 /// existing instruction to the one being built. If the operand turns out to be
1881 /// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1882 class CopyOrAddZeroRegRenderer
: public OperandRenderer
{
1885 /// The name of the operand.
1886 const StringRef SymbolicName
;
1887 const Record
*ZeroRegisterDef
;
1890 CopyOrAddZeroRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
1891 Record
*ZeroRegisterDef
)
1892 : OperandRenderer(OR_CopyOrAddZeroReg
), NewInsnID(NewInsnID
),
1893 SymbolicName(SymbolicName
), ZeroRegisterDef(ZeroRegisterDef
) {
1894 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
1897 static bool classof(const OperandRenderer
*R
) {
1898 return R
->getKind() == OR_CopyOrAddZeroReg
;
1901 StringRef
getSymbolicName() const { return SymbolicName
; }
1903 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1906 /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1907 /// an extended immediate operand.
1908 class CopyConstantAsImmRenderer
: public OperandRenderer
{
1911 /// The name of the operand.
1912 const std::string SymbolicName
;
1916 CopyConstantAsImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1917 : OperandRenderer(OR_CopyConstantAsImm
), NewInsnID(NewInsnID
),
1918 SymbolicName(SymbolicName
), Signed(true) {}
1920 static bool classof(const OperandRenderer
*R
) {
1921 return R
->getKind() == OR_CopyConstantAsImm
;
1924 StringRef
getSymbolicName() const { return SymbolicName
; }
1926 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1929 /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1930 /// instruction to an extended immediate operand.
1931 class CopyFConstantAsFPImmRenderer
: public OperandRenderer
{
1934 /// The name of the operand.
1935 const std::string SymbolicName
;
1938 CopyFConstantAsFPImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1939 : OperandRenderer(OR_CopyFConstantAsFPImm
), NewInsnID(NewInsnID
),
1940 SymbolicName(SymbolicName
) {}
1942 static bool classof(const OperandRenderer
*R
) {
1943 return R
->getKind() == OR_CopyFConstantAsFPImm
;
1946 StringRef
getSymbolicName() const { return SymbolicName
; }
1948 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1951 /// A CopySubRegRenderer emits code to copy a single register operand from an
1952 /// existing instruction to the one being built and indicate that only a
1953 /// subregister should be copied.
1954 class CopySubRegRenderer
: public OperandRenderer
{
1957 /// The name of the operand.
1958 const StringRef SymbolicName
;
1959 /// The subregister to extract.
1960 const CodeGenSubRegIndex
*SubReg
;
1963 CopySubRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
1964 const CodeGenSubRegIndex
*SubReg
)
1965 : OperandRenderer(OR_CopySubReg
), NewInsnID(NewInsnID
),
1966 SymbolicName(SymbolicName
), SubReg(SubReg
) {}
1968 static bool classof(const OperandRenderer
*R
) {
1969 return R
->getKind() == OR_CopySubReg
;
1972 StringRef
getSymbolicName() const { return SymbolicName
; }
1974 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1977 /// Adds a specific physical register to the instruction being built.
1978 /// This is typically useful for WZR/XZR on AArch64.
1979 class AddRegisterRenderer
: public OperandRenderer
{
1982 const Record
*RegisterDef
;
1984 const CodeGenTarget
&Target
;
1987 AddRegisterRenderer(unsigned InsnID
, const CodeGenTarget
&Target
,
1988 const Record
*RegisterDef
, bool IsDef
= false)
1989 : OperandRenderer(OR_Register
), InsnID(InsnID
), RegisterDef(RegisterDef
),
1990 IsDef(IsDef
), Target(Target
) {}
1992 static bool classof(const OperandRenderer
*R
) {
1993 return R
->getKind() == OR_Register
;
1996 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1999 /// Adds a specific temporary virtual register to the instruction being built.
2000 /// This is used to chain instructions together when emitting multiple
2002 class TempRegRenderer
: public OperandRenderer
{
2006 const CodeGenSubRegIndex
*SubRegIdx
;
2011 TempRegRenderer(unsigned InsnID
, unsigned TempRegID
, bool IsDef
= false,
2012 const CodeGenSubRegIndex
*SubReg
= nullptr,
2013 bool IsDead
= false)
2014 : OperandRenderer(OR_Register
), InsnID(InsnID
), TempRegID(TempRegID
),
2015 SubRegIdx(SubReg
), IsDef(IsDef
), IsDead(IsDead
) {}
2017 static bool classof(const OperandRenderer
*R
) {
2018 return R
->getKind() == OR_TempRegister
;
2021 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2024 /// Adds a specific immediate to the instruction being built.
2025 /// If a LLT is passed, a ConstantInt immediate is created instead.
2026 class ImmRenderer
: public OperandRenderer
{
2030 std::optional
<LLTCodeGenOrTempType
> CImmLLT
;
2033 ImmRenderer(unsigned InsnID
, int64_t Imm
)
2034 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
) {}
2036 ImmRenderer(unsigned InsnID
, int64_t Imm
, const LLTCodeGenOrTempType
&CImmLLT
)
2037 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
), CImmLLT(CImmLLT
) {
2038 if (CImmLLT
.isLLTCodeGen())
2039 KnownTypes
.insert(CImmLLT
.getLLTCodeGen());
2042 static bool classof(const OperandRenderer
*R
) {
2043 return R
->getKind() == OR_Imm
;
2046 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2048 assert(Table
.isCombiner() &&
2049 "ConstantInt immediate are only for combiners!");
2050 Table
<< MatchTable::Opcode("GIR_AddCImm")
2051 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID
)
2052 << MatchTable::Comment("Type") << *CImmLLT
2053 << MatchTable::Comment("Imm") << MatchTable::IntValue(Imm
)
2054 << MatchTable::LineBreak
;
2056 Table
<< MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
2057 << MatchTable::IntValue(InsnID
) << MatchTable::Comment("Imm")
2058 << MatchTable::IntValue(Imm
) << MatchTable::LineBreak
;
2063 /// Adds an enum value for a subreg index to the instruction being built.
2064 class SubRegIndexRenderer
: public OperandRenderer
{
2067 const CodeGenSubRegIndex
*SubRegIdx
;
2070 SubRegIndexRenderer(unsigned InsnID
, const CodeGenSubRegIndex
*SRI
)
2071 : OperandRenderer(OR_SubRegIndex
), InsnID(InsnID
), SubRegIdx(SRI
) {}
2073 static bool classof(const OperandRenderer
*R
) {
2074 return R
->getKind() == OR_SubRegIndex
;
2077 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2080 /// Adds operands by calling a renderer function supplied by the ComplexPattern
2081 /// matcher function.
2082 class RenderComplexPatternOperand
: public OperandRenderer
{
2085 const Record
&TheDef
;
2086 /// The name of the operand.
2087 const StringRef SymbolicName
;
2088 /// The renderer number. This must be unique within a rule since it's used to
2089 /// identify a temporary variable to hold the renderer function.
2090 unsigned RendererID
;
2091 /// When provided, this is the suboperand of the ComplexPattern operand to
2092 /// render. Otherwise all the suboperands will be rendered.
2093 std::optional
<unsigned> SubOperand
;
2094 /// The subregister to extract. Render the whole register if not specified.
2095 const CodeGenSubRegIndex
*SubReg
;
2097 unsigned getNumOperands() const {
2098 return TheDef
.getValueAsDag("Operands")->getNumArgs();
2102 RenderComplexPatternOperand(unsigned InsnID
, const Record
&TheDef
,
2103 StringRef SymbolicName
, unsigned RendererID
,
2104 std::optional
<unsigned> SubOperand
= std::nullopt
,
2105 const CodeGenSubRegIndex
*SubReg
= nullptr)
2106 : OperandRenderer(OR_ComplexPattern
), InsnID(InsnID
), TheDef(TheDef
),
2107 SymbolicName(SymbolicName
), RendererID(RendererID
),
2108 SubOperand(SubOperand
), SubReg(SubReg
) {}
2110 static bool classof(const OperandRenderer
*R
) {
2111 return R
->getKind() == OR_ComplexPattern
;
2114 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2117 class CustomRenderer
: public OperandRenderer
{
2120 const Record
&Renderer
;
2121 /// The name of the operand.
2122 const std::string SymbolicName
;
2125 CustomRenderer(unsigned InsnID
, const Record
&Renderer
,
2126 StringRef SymbolicName
)
2127 : OperandRenderer(OR_Custom
), InsnID(InsnID
), Renderer(Renderer
),
2128 SymbolicName(SymbolicName
) {}
2130 static bool classof(const OperandRenderer
*R
) {
2131 return R
->getKind() == OR_Custom
;
2134 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2137 class CustomOperandRenderer
: public OperandRenderer
{
2140 const Record
&Renderer
;
2141 /// The name of the operand.
2142 const std::string SymbolicName
;
2145 CustomOperandRenderer(unsigned InsnID
, const Record
&Renderer
,
2146 StringRef SymbolicName
)
2147 : OperandRenderer(OR_CustomOperand
), InsnID(InsnID
), Renderer(Renderer
),
2148 SymbolicName(SymbolicName
) {}
2150 static bool classof(const OperandRenderer
*R
) {
2151 return R
->getKind() == OR_CustomOperand
;
2154 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2157 /// An action taken when all Matcher predicates succeeded for a parent rule.
2159 /// Typical actions include:
2160 /// * Changing the opcode of an instruction.
2161 /// * Adding an operand to an instruction.
2171 AK_ConstraintOpsToDef
,
2172 AK_ConstraintOpsToRC
,
2176 MatchAction(ActionKind K
) : Kind(K
) {}
2178 ActionKind
getKind() const { return Kind
; }
2180 virtual ~MatchAction() {}
2182 // Some actions may need to add extra predicates to ensure they can run.
2183 virtual void emitAdditionalPredicates(MatchTable
&Table
,
2184 RuleMatcher
&Rule
) const {}
2186 /// Emit the MatchTable opcodes to implement the action.
2187 virtual void emitActionOpcodes(MatchTable
&Table
,
2188 RuleMatcher
&Rule
) const = 0;
2194 /// Generates a comment describing the matched rule being acted upon.
2195 class DebugCommentAction
: public MatchAction
{
2200 DebugCommentAction(StringRef S
)
2201 : MatchAction(AK_DebugComment
), S(std::string(S
)) {}
2203 static bool classof(const MatchAction
*A
) {
2204 return A
->getKind() == AK_DebugComment
;
2207 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2208 Table
<< MatchTable::Comment(S
) << MatchTable::LineBreak
;
2212 class CustomCXXAction
: public MatchAction
{
2213 std::string FnEnumName
;
2216 CustomCXXAction(StringRef FnEnumName
)
2217 : MatchAction(AK_CustomCXX
), FnEnumName(FnEnumName
.str()) {}
2219 static bool classof(const MatchAction
*A
) {
2220 return A
->getKind() == AK_CustomCXX
;
2223 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2226 /// Generates code to build an instruction or mutate an existing instruction
2227 /// into the desired instruction when this is possible.
2228 class BuildMIAction
: public MatchAction
{
2231 const CodeGenInstruction
*I
;
2232 InstructionMatcher
*Matched
;
2233 std::vector
<std::unique_ptr
<OperandRenderer
>> OperandRenderers
;
2234 SmallPtrSet
<Record
*, 4> DeadImplicitDefs
;
2236 /// True if the instruction can be built solely by mutating the opcode.
2237 bool canMutate(RuleMatcher
&Rule
, const InstructionMatcher
*Insn
) const;
2240 BuildMIAction(unsigned InsnID
, const CodeGenInstruction
*I
)
2241 : MatchAction(AK_BuildMI
), InsnID(InsnID
), I(I
), Matched(nullptr) {}
2243 static bool classof(const MatchAction
*A
) {
2244 return A
->getKind() == AK_BuildMI
;
2247 unsigned getInsnID() const { return InsnID
; }
2248 const CodeGenInstruction
*getCGI() const { return I
; }
2250 void chooseInsnToMutate(RuleMatcher
&Rule
);
2252 void setDeadImplicitDef(Record
*R
) { DeadImplicitDefs
.insert(R
); }
2254 template <class Kind
, class... Args
> Kind
&addRenderer(Args
&&...args
) {
2255 OperandRenderers
.emplace_back(
2256 std::make_unique
<Kind
>(InsnID
, std::forward
<Args
>(args
)...));
2257 return *static_cast<Kind
*>(OperandRenderers
.back().get());
2260 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2263 /// Generates code to create a constant that defines a TempReg.
2264 /// The instruction created is usually a G_CONSTANT but it could also be a
2265 /// G_BUILD_VECTOR for vector types.
2266 class BuildConstantAction
: public MatchAction
{
2271 BuildConstantAction(unsigned TempRegID
, int64_t Val
)
2272 : MatchAction(AK_BuildConstantMI
), TempRegID(TempRegID
), Val(Val
) {}
2274 static bool classof(const MatchAction
*A
) {
2275 return A
->getKind() == AK_BuildConstantMI
;
2278 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2281 class EraseInstAction
: public MatchAction
{
2285 EraseInstAction(unsigned InsnID
)
2286 : MatchAction(AK_EraseInst
), InsnID(InsnID
) {}
2288 static bool classof(const MatchAction
*A
) {
2289 return A
->getKind() == AK_EraseInst
;
2292 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2293 static void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
,
2297 class ReplaceRegAction
: public MatchAction
{
2298 unsigned OldInsnID
, OldOpIdx
;
2299 unsigned NewInsnId
= -1, NewOpIdx
;
2300 unsigned TempRegID
= -1;
2303 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned NewInsnId
,
2305 : MatchAction(AK_EraseInst
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2306 NewInsnId(NewInsnId
), NewOpIdx(NewOpIdx
) {}
2308 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned TempRegID
)
2309 : MatchAction(AK_EraseInst
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2310 TempRegID(TempRegID
) {}
2312 static bool classof(const MatchAction
*A
) {
2313 return A
->getKind() == AK_ReplaceReg
;
2316 void emitAdditionalPredicates(MatchTable
&Table
,
2317 RuleMatcher
&Rule
) const override
;
2318 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2321 /// Generates code to constrain the operands of an output instruction to the
2322 /// register classes specified by the definition of that instruction.
2323 class ConstrainOperandsToDefinitionAction
: public MatchAction
{
2327 ConstrainOperandsToDefinitionAction(unsigned InsnID
)
2328 : MatchAction(AK_ConstraintOpsToDef
), InsnID(InsnID
) {}
2330 static bool classof(const MatchAction
*A
) {
2331 return A
->getKind() == AK_ConstraintOpsToDef
;
2334 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2335 Table
<< MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2336 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID
)
2337 << MatchTable::LineBreak
;
2341 /// Generates code to constrain the specified operand of an output instruction
2342 /// to the specified register class.
2343 class ConstrainOperandToRegClassAction
: public MatchAction
{
2346 const CodeGenRegisterClass
&RC
;
2349 ConstrainOperandToRegClassAction(unsigned InsnID
, unsigned OpIdx
,
2350 const CodeGenRegisterClass
&RC
)
2351 : MatchAction(AK_ConstraintOpsToRC
), InsnID(InsnID
), OpIdx(OpIdx
),
2354 static bool classof(const MatchAction
*A
) {
2355 return A
->getKind() == AK_ConstraintOpsToRC
;
2358 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2361 /// Generates code to create a temporary register which can be used to chain
2362 /// instructions together.
2363 class MakeTempRegisterAction
: public MatchAction
{
2365 LLTCodeGenOrTempType Ty
;
2369 MakeTempRegisterAction(const LLTCodeGenOrTempType
&Ty
, unsigned TempRegID
)
2370 : MatchAction(AK_MakeTempReg
), Ty(Ty
), TempRegID(TempRegID
) {
2371 if (Ty
.isLLTCodeGen())
2372 KnownTypes
.insert(Ty
.getLLTCodeGen());
2375 static bool classof(const MatchAction
*A
) {
2376 return A
->getKind() == AK_MakeTempReg
;
2379 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;