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 void emitEncodingMacrosDef(raw_ostream
&OS
);
63 void emitEncodingMacrosUndef(raw_ostream
&OS
);
65 std::string
getNameForFeatureBitset(const std::vector
<Record
*> &FeatureBitset
,
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.
72 /// What this optimization does looks like if GroupT = GroupMatcher:
73 /// Output without optimization:
80 /// # predicate A // <-- effectively this is going to be checked twice.
81 /// // Once in R1 and once in R2.
84 /// Output with optimization:
87 /// # predicate A // <-- Check is now shared.
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.
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
{
107 /// Causes EmitStr to be formatted as comment when emitted.
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.
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
122 /// Causes the formatter to remove a level of indentation after emitting the
125 /// Causes the formatter to not use encoding macros to emit this multi-byte
127 MTRF_PreEncoded
= 0x80,
130 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
131 /// reference or define.
133 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
134 /// value, a label name.
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
;
144 /// A bitfield of RecordFlagsBits flags.
147 /// The actual run-time value, if known
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
;
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.
182 /// An unique identifier for the table. The generated table will be named
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.
196 /// Whether this table is for the GISel combiner.
197 bool IsCombinerTable
;
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
,
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::make_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");
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
);
254 /// This class stands in for LLT wherever we want to tablegen-erate an
255 /// equivalent at compiler run-time.
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
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
{
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
);
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());
315 Table
<< MatchTable::IntValue(1, Ty
.getTempTypeIdx());
319 //===- Matchers -----------------------------------------------------------===//
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
;
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(...);
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.
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());
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(); }
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
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
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
;
423 bool addMatcher(Matcher
&Candidate
);
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; }
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;
454 static void emitPredicateSpecificOpcodes(const PredicateMatcher
&P
,
458 /// Generates code to check that a match rule matches.
459 class RuleMatcher
: public Matcher
{
461 using ActionList
= std::list
<std::unique_ptr
<MatchAction
>>;
462 using action_iterator
= ActionList::iterator
;
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
>>;
472 /// A list of actions that need to be taken when all predicates in this rule
476 using DefinedInsnVariablesMap
= std::map
<InstructionMatcher
*, unsigned>;
478 /// A map of instruction matchers to the local variables
479 DefinedInsnVariablesMap InsnVariableIDs
;
481 using MutatableInsnSet
= SmallPtrSet
<InstructionMatcher
*, 4>;
483 // The set of instruction matchers that have not yet been claimed for mutation
485 MutatableInsnSet MutatableInsns
;
487 /// A map of named operands defined by the matchers that may be referenced by
489 StringMap
<OperandMatcher
*> DefinedOperands
;
491 /// A map of anonymous physical register operands defined by the matchers that
492 /// may be referenced by the renderers.
493 DenseMap
<Record
*, OperandMatcher
*> PhysRegOperands
;
495 /// ID for the next instruction variable defined with
496 /// implicitlyDefineInsnVar()
497 unsigned NextInsnVarID
;
499 /// ID for the next output instruction allocated with allocateOutputInsnID()
500 unsigned NextOutputInsnID
;
502 /// ID for the next temporary register ID allocated with allocateTempRegID()
503 unsigned NextTempRegID
;
505 /// ID for the next recorded type. Starts at -1 and counts down.
506 TempTypeIdx NextTempTypeIdx
= -1;
508 // HwMode predicate index for this rule. -1 if no HwMode.
511 /// Current GISelFlags
512 GISelFlags Flags
= 0;
514 std::vector
<std::string
> RequiredSimplePredicates
;
515 std::vector
<Record
*> RequiredFeatures
;
516 std::vector
<std::unique_ptr
<PredicateMatcher
>> EpilogueMatchers
;
518 DenseSet
<unsigned> ErasedInsnIDs
;
520 ArrayRef
<SMLoc
> SrcLoc
;
522 typedef std::tuple
<Record
*, unsigned, unsigned>
523 DefinedComplexPatternSubOperand
;
524 typedef StringMap
<DefinedComplexPatternSubOperand
>
525 DefinedComplexPatternSubOperandMap
;
526 /// A map of Symbolic Names to ComplexPattern sub-operands.
527 DefinedComplexPatternSubOperandMap ComplexSubOperands
;
528 /// A map used to for multiple referenced error check of ComplexSubOperand.
529 /// ComplexSubOperand can't be referenced multiple from different operands,
530 /// however multiple references from same operand are allowed since that is
531 /// how 'same operand checks' are generated.
532 StringMap
<std::string
> ComplexSubOperandsParentName
;
535 static uint64_t NextRuleID
;
537 GISelFlags
updateGISelFlag(GISelFlags CurFlags
, const Record
*R
,
538 StringRef FlagName
, GISelFlags FlagBit
);
541 RuleMatcher(ArrayRef
<SMLoc
> SrcLoc
)
542 : NextInsnVarID(0), NextOutputInsnID(0), NextTempRegID(0), SrcLoc(SrcLoc
),
543 RuleID(NextRuleID
++) {}
544 RuleMatcher(RuleMatcher
&&Other
) = default;
545 RuleMatcher
&operator=(RuleMatcher
&&Other
) = default;
547 TempTypeIdx
getNextTempTypeIdx() { return NextTempTypeIdx
--; }
549 uint64_t getRuleID() const { return RuleID
; }
551 InstructionMatcher
&addInstructionMatcher(StringRef SymbolicName
);
552 void addRequiredFeature(Record
*Feature
);
553 const std::vector
<Record
*> &getRequiredFeatures() const;
555 void addHwModeIdx(unsigned Idx
) { HwModeIdx
= Idx
; }
556 int getHwModeIdx() const { return HwModeIdx
; }
558 void addRequiredSimplePredicate(StringRef PredName
);
559 const std::vector
<std::string
> &getRequiredSimplePredicates();
561 /// Attempts to mark \p ID as erased (GIR_EraseFromParent called on it).
562 /// If \p ID has already been erased, returns false and GIR_EraseFromParent
563 /// should NOT be emitted.
564 bool tryEraseInsnID(unsigned ID
) { return ErasedInsnIDs
.insert(ID
).second
; }
566 // Emplaces an action of the specified Kind at the end of the action list.
568 // Returns a reference to the newly created action.
570 // Like std::vector::emplace_back(), may invalidate all iterators if the new
571 // size exceeds the capacity. Otherwise, only invalidates the past-the-end
573 template <class Kind
, class... Args
> Kind
&addAction(Args
&&...args
) {
574 Actions
.emplace_back(std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
575 return *static_cast<Kind
*>(Actions
.back().get());
578 // Emplaces an action of the specified Kind before the given insertion point.
580 // Returns an iterator pointing at the newly created instruction.
582 // Like std::vector::insert(), may invalidate all iterators if the new size
583 // exceeds the capacity. Otherwise, only invalidates the iterators from the
584 // insertion point onwards.
585 template <class Kind
, class... Args
>
586 action_iterator
insertAction(action_iterator InsertPt
, Args
&&...args
) {
587 return Actions
.emplace(InsertPt
,
588 std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
591 void setPermanentGISelFlags(GISelFlags V
) { Flags
= V
; }
593 // Update the active GISelFlags based on the GISelFlags Record R.
594 // A SaveAndRestore object is returned so the old GISelFlags are restored
595 // at the end of the scope.
596 SaveAndRestore
<GISelFlags
> setGISelFlags(const Record
*R
);
597 GISelFlags
getGISelFlags() const { return Flags
; }
599 /// Define an instruction without emitting any code to do so.
600 unsigned implicitlyDefineInsnVar(InstructionMatcher
&Matcher
);
602 unsigned getInsnVarID(InstructionMatcher
&InsnMatcher
) const;
603 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_begin() const {
604 return InsnVariableIDs
.begin();
606 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_end() const {
607 return InsnVariableIDs
.end();
609 iterator_range
<typename
DefinedInsnVariablesMap::const_iterator
>
610 defined_insn_vars() const {
611 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
614 MutatableInsnSet::const_iterator
mutatable_insns_begin() const {
615 return MutatableInsns
.begin();
617 MutatableInsnSet::const_iterator
mutatable_insns_end() const {
618 return MutatableInsns
.end();
620 iterator_range
<typename
MutatableInsnSet::const_iterator
>
621 mutatable_insns() const {
622 return make_range(mutatable_insns_begin(), mutatable_insns_end());
624 void reserveInsnMatcherForMutation(InstructionMatcher
*InsnMatcher
) {
625 bool R
= MutatableInsns
.erase(InsnMatcher
);
626 assert(R
&& "Reserving a mutatable insn that isn't available");
630 action_iterator
actions_begin() { return Actions
.begin(); }
631 action_iterator
actions_end() { return Actions
.end(); }
632 iterator_range
<action_iterator
> actions() {
633 return make_range(actions_begin(), actions_end());
636 void defineOperand(StringRef SymbolicName
, OperandMatcher
&OM
);
638 void definePhysRegOperand(Record
*Reg
, OperandMatcher
&OM
);
640 Error
defineComplexSubOperand(StringRef SymbolicName
, Record
*ComplexPattern
,
641 unsigned RendererID
, unsigned SubOperandID
,
642 StringRef ParentSymbolicName
);
644 std::optional
<DefinedComplexPatternSubOperand
>
645 getComplexSubOperand(StringRef SymbolicName
) const {
646 const auto &I
= ComplexSubOperands
.find(SymbolicName
);
647 if (I
== ComplexSubOperands
.end())
652 InstructionMatcher
&getInstructionMatcher(StringRef SymbolicName
) const;
653 OperandMatcher
&getOperandMatcher(StringRef Name
);
654 const OperandMatcher
&getOperandMatcher(StringRef Name
) const;
655 const OperandMatcher
&getPhysRegOperandMatcher(Record
*) const;
657 void optimize() override
;
658 void emit(MatchTable
&Table
) override
;
660 /// Compare the priority of this object and B.
662 /// Returns true if this object is more important than B.
663 bool isHigherPriorityThan(const RuleMatcher
&B
) const;
665 /// Report the maximum number of temporary operands needed by the rule
667 unsigned countRendererFns() const;
669 std::unique_ptr
<PredicateMatcher
> popFirstCondition() override
;
670 const PredicateMatcher
&getFirstCondition() const override
;
671 LLTCodeGen
getFirstConditionAsRootType();
672 bool hasFirstCondition() const override
;
673 unsigned getNumOperands() const;
674 StringRef
getOpcode() const;
676 // FIXME: Remove this as soon as possible
677 InstructionMatcher
&insnmatchers_front() const { return *Matchers
.front(); }
679 unsigned allocateOutputInsnID() { return NextOutputInsnID
++; }
680 unsigned allocateTempRegID() { return NextTempRegID
++; }
682 iterator_range
<MatchersTy::iterator
> insnmatchers() {
683 return make_range(Matchers
.begin(), Matchers
.end());
685 bool insnmatchers_empty() const { return Matchers
.empty(); }
686 void insnmatchers_pop_front() { Matchers
.erase(Matchers
.begin()); }
689 template <class PredicateTy
> class PredicateListMatcher
{
691 /// Template instantiations should specialize this to return a string to use
692 /// for the comment emitted when there are no predicates.
693 std::string
getNoPredicateComment() const;
696 using PredicatesTy
= std::deque
<std::unique_ptr
<PredicateTy
>>;
697 PredicatesTy Predicates
;
699 /// Track if the list of predicates was manipulated by one of the optimization
701 bool Optimized
= false;
704 typename
PredicatesTy::iterator
predicates_begin() {
705 return Predicates
.begin();
707 typename
PredicatesTy::iterator
predicates_end() { return Predicates
.end(); }
708 iterator_range
<typename
PredicatesTy::iterator
> predicates() {
709 return make_range(predicates_begin(), predicates_end());
711 typename
PredicatesTy::size_type
predicates_size() const {
712 return Predicates
.size();
714 bool predicates_empty() const { return Predicates
.empty(); }
716 template <typename Ty
> bool contains() const {
717 return any_of(Predicates
, [&](auto &P
) { return isa
<Ty
>(P
.get()); });
720 std::unique_ptr
<PredicateTy
> predicates_pop_front() {
721 std::unique_ptr
<PredicateTy
> Front
= std::move(Predicates
.front());
722 Predicates
.pop_front();
727 void prependPredicate(std::unique_ptr
<PredicateTy
> &&Predicate
) {
728 Predicates
.push_front(std::move(Predicate
));
731 void eraseNullPredicates() {
733 std::stable_partition(Predicates
.begin(), Predicates
.end(),
734 std::logical_not
<std::unique_ptr
<PredicateTy
>>());
735 if (NewEnd
!= Predicates
.begin()) {
736 Predicates
.erase(Predicates
.begin(), NewEnd
);
741 /// Emit MatchTable opcodes that tests whether all the predicates are met.
742 template <class... Args
>
743 void emitPredicateListOpcodes(MatchTable
&Table
, Args
&&...args
) {
744 if (Predicates
.empty() && !Optimized
) {
745 Table
<< MatchTable::Comment(getNoPredicateComment())
746 << MatchTable::LineBreak
;
750 for (const auto &Predicate
: predicates())
751 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
754 /// Provide a function to avoid emitting certain predicates. This is used to
755 /// defer some predicate checks until after others
756 using PredicateFilterFunc
= std::function
<bool(const PredicateTy
&)>;
758 /// Emit MatchTable opcodes for predicates which satisfy \p
759 /// ShouldEmitPredicate. This should be called multiple times to ensure all
760 /// predicates are eventually added to the match table.
761 template <class... Args
>
762 void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate
,
763 MatchTable
&Table
, Args
&&...args
) {
764 if (Predicates
.empty() && !Optimized
) {
765 Table
<< MatchTable::Comment(getNoPredicateComment())
766 << MatchTable::LineBreak
;
770 for (const auto &Predicate
: predicates()) {
771 if (ShouldEmitPredicate(*Predicate
))
772 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
777 class PredicateMatcher
{
779 /// This enum is used for RTTI and also defines the priority that is given to
780 /// the predicate when generating the matcher code. Kinds with higher priority
781 /// must be tested first.
783 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
784 /// but OPM_Int must have priority over OPM_RegBank since constant integers
785 /// are represented by a virtual register defined by a G_CONSTANT instruction.
787 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
788 /// are currently not compared between each other.
794 IPM_AtomicOrderingMMO
,
797 IPM_MemoryAddressSpace
,
801 IPM_GenericPredicate
,
814 OPM_RecordNamedOperand
,
824 PredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
, unsigned OpIdx
= ~0)
825 : Kind(Kind
), InsnVarID(InsnVarID
), OpIdx(OpIdx
) {}
826 virtual ~PredicateMatcher();
828 unsigned getInsnVarID() const { return InsnVarID
; }
829 unsigned getOpIdx() const { return OpIdx
; }
831 /// Emit MatchTable opcodes that check the predicate for the given operand.
832 virtual void emitPredicateOpcodes(MatchTable
&Table
,
833 RuleMatcher
&Rule
) const = 0;
835 PredicateKind
getKind() const { return Kind
; }
837 bool dependsOnOperands() const {
838 // Custom predicates really depend on the context pattern of the
839 // instruction, not just the individual instruction. This therefore
840 // implicitly depends on all other pattern constraints.
841 return Kind
== IPM_GenericPredicate
;
844 virtual bool isIdentical(const PredicateMatcher
&B
) const {
845 return B
.getKind() == getKind() && InsnVarID
== B
.InsnVarID
&&
849 virtual bool isIdenticalDownToValue(const PredicateMatcher
&B
) const {
850 return hasValue() && PredicateMatcher::isIdentical(B
);
853 virtual MatchTableRecord
getValue() const {
854 assert(hasValue() && "Can not get a value of a value-less predicate!");
855 llvm_unreachable("Not implemented yet");
857 virtual bool hasValue() const { return false; }
859 /// Report the maximum number of temporary operands needed by the predicate
861 virtual unsigned countRendererFns() const { return 0; }
864 /// Generates code to check a predicate of an operand.
866 /// Typical predicates include:
867 /// * Operand is a particular register.
868 /// * Operand is assigned a particular register bank.
869 /// * Operand is an MBB.
870 class OperandPredicateMatcher
: public PredicateMatcher
{
872 OperandPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
,
874 : PredicateMatcher(Kind
, InsnVarID
, OpIdx
) {}
875 virtual ~OperandPredicateMatcher();
877 /// Compare the priority of this object and B.
879 /// Returns true if this object is more important than B.
880 virtual bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const;
885 PredicateListMatcher
<OperandPredicateMatcher
>::getNoPredicateComment() const {
886 return "No operand predicates";
889 /// Generates code to check that a register operand is defined by the same exact
891 class SameOperandMatcher
: public OperandPredicateMatcher
{
892 std::string MatchingName
;
898 SameOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, StringRef MatchingName
,
899 unsigned OrigOpIdx
, GISelFlags Flags
)
900 : OperandPredicateMatcher(OPM_SameOperand
, InsnVarID
, OpIdx
),
901 MatchingName(MatchingName
), OrigOpIdx(OrigOpIdx
), Flags(Flags
) {}
903 static bool classof(const PredicateMatcher
*P
) {
904 return P
->getKind() == OPM_SameOperand
;
907 void emitPredicateOpcodes(MatchTable
&Table
,
908 RuleMatcher
&Rule
) const override
;
910 bool isIdentical(const PredicateMatcher
&B
) const override
{
911 return OperandPredicateMatcher::isIdentical(B
) &&
912 OrigOpIdx
== cast
<SameOperandMatcher
>(&B
)->OrigOpIdx
&&
913 MatchingName
== cast
<SameOperandMatcher
>(&B
)->MatchingName
;
917 /// Generates code to check that an operand is a particular LLT.
918 class LLTOperandMatcher
: public OperandPredicateMatcher
{
923 static std::map
<LLTCodeGen
, unsigned> TypeIDValues
;
925 static void initTypeIDValuesMap() {
926 TypeIDValues
.clear();
929 for (const LLTCodeGen
&LLTy
: KnownTypes
)
930 TypeIDValues
[LLTy
] = ID
++;
933 LLTOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, const LLTCodeGen
&Ty
)
934 : OperandPredicateMatcher(OPM_LLT
, InsnVarID
, OpIdx
), Ty(Ty
) {
935 KnownTypes
.insert(Ty
);
938 static bool classof(const PredicateMatcher
*P
) {
939 return P
->getKind() == OPM_LLT
;
942 bool isIdentical(const PredicateMatcher
&B
) const override
{
943 return OperandPredicateMatcher::isIdentical(B
) &&
944 Ty
== cast
<LLTOperandMatcher
>(&B
)->Ty
;
947 MatchTableRecord
getValue() const override
;
948 bool hasValue() const override
;
950 LLTCodeGen
getTy() const { return Ty
; }
952 void emitPredicateOpcodes(MatchTable
&Table
,
953 RuleMatcher
&Rule
) const override
;
956 /// Generates code to check that an operand is a pointer to any address space.
958 /// In SelectionDAG, the types did not describe pointers or address spaces. As a
959 /// result, iN is used to describe a pointer of N bits to any address space and
960 /// PatFrag predicates are typically used to constrain the address space.
961 /// There's no reliable means to derive the missing type information from the
962 /// pattern so imported rules must test the components of a pointer separately.
964 /// If SizeInBits is zero, then the pointer size will be obtained from the
966 class PointerToAnyOperandMatcher
: public OperandPredicateMatcher
{
971 PointerToAnyOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
973 : OperandPredicateMatcher(OPM_PointerToAny
, InsnVarID
, OpIdx
),
974 SizeInBits(SizeInBits
) {}
976 static bool classof(const PredicateMatcher
*P
) {
977 return P
->getKind() == OPM_PointerToAny
;
980 bool isIdentical(const PredicateMatcher
&B
) const override
{
981 return OperandPredicateMatcher::isIdentical(B
) &&
982 SizeInBits
== cast
<PointerToAnyOperandMatcher
>(&B
)->SizeInBits
;
985 void emitPredicateOpcodes(MatchTable
&Table
,
986 RuleMatcher
&Rule
) const override
;
989 /// Generates code to record named operand in RecordedOperands list at StoreIdx.
990 /// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
991 /// an argument to predicate's c++ code once all operands have been matched.
992 class RecordNamedOperandMatcher
: public OperandPredicateMatcher
{
998 RecordNamedOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
999 unsigned StoreIdx
, StringRef Name
)
1000 : OperandPredicateMatcher(OPM_RecordNamedOperand
, InsnVarID
, OpIdx
),
1001 StoreIdx(StoreIdx
), Name(Name
) {}
1003 static bool classof(const PredicateMatcher
*P
) {
1004 return P
->getKind() == OPM_RecordNamedOperand
;
1007 bool isIdentical(const PredicateMatcher
&B
) const override
{
1008 return OperandPredicateMatcher::isIdentical(B
) &&
1009 StoreIdx
== cast
<RecordNamedOperandMatcher
>(&B
)->StoreIdx
&&
1010 Name
== cast
<RecordNamedOperandMatcher
>(&B
)->Name
;
1013 void emitPredicateOpcodes(MatchTable
&Table
,
1014 RuleMatcher
&Rule
) const override
;
1017 /// Generates code to store a register operand's type into the set of temporary
1019 class RecordRegisterType
: public OperandPredicateMatcher
{
1024 RecordRegisterType(unsigned InsnVarID
, unsigned OpIdx
, TempTypeIdx Idx
)
1025 : OperandPredicateMatcher(OPM_RecordRegType
, InsnVarID
, OpIdx
), Idx(Idx
) {
1028 static bool classof(const PredicateMatcher
*P
) {
1029 return P
->getKind() == OPM_RecordRegType
;
1032 bool isIdentical(const PredicateMatcher
&B
) const override
{
1033 return OperandPredicateMatcher::isIdentical(B
) &&
1034 Idx
== cast
<RecordRegisterType
>(&B
)->Idx
;
1037 void emitPredicateOpcodes(MatchTable
&Table
,
1038 RuleMatcher
&Rule
) const override
;
1041 /// Generates code to check that an operand is a particular target constant.
1042 class ComplexPatternOperandMatcher
: public OperandPredicateMatcher
{
1044 const OperandMatcher
&Operand
;
1045 const Record
&TheDef
;
1047 unsigned getAllocatedTemporariesBaseID() const;
1050 bool isIdentical(const PredicateMatcher
&B
) const override
{ return false; }
1052 ComplexPatternOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1053 const OperandMatcher
&Operand
,
1054 const Record
&TheDef
)
1055 : OperandPredicateMatcher(OPM_ComplexPattern
, InsnVarID
, OpIdx
),
1056 Operand(Operand
), TheDef(TheDef
) {}
1058 static bool classof(const PredicateMatcher
*P
) {
1059 return P
->getKind() == OPM_ComplexPattern
;
1062 void emitPredicateOpcodes(MatchTable
&Table
,
1063 RuleMatcher
&Rule
) const override
;
1064 unsigned countRendererFns() const override
{ return 1; }
1067 /// Generates code to check that an operand is in a particular register bank.
1068 class RegisterBankOperandMatcher
: public OperandPredicateMatcher
{
1070 const CodeGenRegisterClass
&RC
;
1073 RegisterBankOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1074 const CodeGenRegisterClass
&RC
)
1075 : OperandPredicateMatcher(OPM_RegBank
, InsnVarID
, OpIdx
), RC(RC
) {}
1077 bool isIdentical(const PredicateMatcher
&B
) const override
;
1079 static bool classof(const PredicateMatcher
*P
) {
1080 return P
->getKind() == OPM_RegBank
;
1083 void emitPredicateOpcodes(MatchTable
&Table
,
1084 RuleMatcher
&Rule
) const override
;
1087 /// Generates code to check that an operand is a basic block.
1088 class MBBOperandMatcher
: public OperandPredicateMatcher
{
1090 MBBOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1091 : OperandPredicateMatcher(OPM_MBB
, InsnVarID
, OpIdx
) {}
1093 static bool classof(const PredicateMatcher
*P
) {
1094 return P
->getKind() == OPM_MBB
;
1097 void emitPredicateOpcodes(MatchTable
&Table
,
1098 RuleMatcher
&Rule
) const override
;
1101 class ImmOperandMatcher
: public OperandPredicateMatcher
{
1103 ImmOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1104 : OperandPredicateMatcher(IPM_Imm
, InsnVarID
, OpIdx
) {}
1106 static bool classof(const PredicateMatcher
*P
) {
1107 return P
->getKind() == IPM_Imm
;
1110 void emitPredicateOpcodes(MatchTable
&Table
,
1111 RuleMatcher
&Rule
) const override
;
1114 /// Generates code to check that an operand is a G_CONSTANT with a particular
1116 class ConstantIntOperandMatcher
: public OperandPredicateMatcher
{
1121 ConstantIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1122 : OperandPredicateMatcher(OPM_Int
, InsnVarID
, OpIdx
), Value(Value
) {}
1124 bool isIdentical(const PredicateMatcher
&B
) const override
{
1125 return OperandPredicateMatcher::isIdentical(B
) &&
1126 Value
== cast
<ConstantIntOperandMatcher
>(&B
)->Value
;
1129 static bool classof(const PredicateMatcher
*P
) {
1130 return P
->getKind() == OPM_Int
;
1133 void emitPredicateOpcodes(MatchTable
&Table
,
1134 RuleMatcher
&Rule
) const override
;
1137 /// Generates code to check that an operand is a raw int (where MO.isImm() or
1138 /// MO.isCImm() is true).
1139 class LiteralIntOperandMatcher
: public OperandPredicateMatcher
{
1144 LiteralIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1145 : OperandPredicateMatcher(OPM_LiteralInt
, InsnVarID
, OpIdx
),
1148 bool isIdentical(const PredicateMatcher
&B
) const override
{
1149 return OperandPredicateMatcher::isIdentical(B
) &&
1150 Value
== cast
<LiteralIntOperandMatcher
>(&B
)->Value
;
1153 static bool classof(const PredicateMatcher
*P
) {
1154 return P
->getKind() == OPM_LiteralInt
;
1157 void emitPredicateOpcodes(MatchTable
&Table
,
1158 RuleMatcher
&Rule
) const override
;
1161 /// Generates code to check that an operand is an CmpInst predicate
1162 class CmpPredicateOperandMatcher
: public OperandPredicateMatcher
{
1164 std::string PredName
;
1167 CmpPredicateOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, std::string P
)
1168 : OperandPredicateMatcher(OPM_CmpPredicate
, InsnVarID
, OpIdx
),
1171 bool isIdentical(const PredicateMatcher
&B
) const override
{
1172 return OperandPredicateMatcher::isIdentical(B
) &&
1173 PredName
== cast
<CmpPredicateOperandMatcher
>(&B
)->PredName
;
1176 static bool classof(const PredicateMatcher
*P
) {
1177 return P
->getKind() == OPM_CmpPredicate
;
1180 void emitPredicateOpcodes(MatchTable
&Table
,
1181 RuleMatcher
&Rule
) const override
;
1184 /// Generates code to check that an operand is an intrinsic ID.
1185 class IntrinsicIDOperandMatcher
: public OperandPredicateMatcher
{
1187 const CodeGenIntrinsic
*II
;
1190 IntrinsicIDOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1191 const CodeGenIntrinsic
*II
)
1192 : OperandPredicateMatcher(OPM_IntrinsicID
, InsnVarID
, OpIdx
), II(II
) {}
1194 bool isIdentical(const PredicateMatcher
&B
) const override
{
1195 return OperandPredicateMatcher::isIdentical(B
) &&
1196 II
== cast
<IntrinsicIDOperandMatcher
>(&B
)->II
;
1199 static bool classof(const PredicateMatcher
*P
) {
1200 return P
->getKind() == OPM_IntrinsicID
;
1203 void emitPredicateOpcodes(MatchTable
&Table
,
1204 RuleMatcher
&Rule
) const override
;
1207 /// Generates code to check that this operand is an immediate whose value meets
1208 /// an immediate predicate.
1209 class OperandImmPredicateMatcher
: public OperandPredicateMatcher
{
1211 TreePredicateFn Predicate
;
1214 OperandImmPredicateMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1215 const TreePredicateFn
&Predicate
)
1216 : OperandPredicateMatcher(IPM_ImmPredicate
, InsnVarID
, OpIdx
),
1217 Predicate(Predicate
) {}
1219 bool isIdentical(const PredicateMatcher
&B
) const override
{
1220 return OperandPredicateMatcher::isIdentical(B
) &&
1221 Predicate
.getOrigPatFragRecord() ==
1222 cast
<OperandImmPredicateMatcher
>(&B
)
1223 ->Predicate
.getOrigPatFragRecord();
1226 static bool classof(const PredicateMatcher
*P
) {
1227 return P
->getKind() == IPM_ImmPredicate
;
1230 void emitPredicateOpcodes(MatchTable
&Table
,
1231 RuleMatcher
&Rule
) const override
;
1234 /// Generates code to check that a set of predicates match for a particular
1236 class OperandMatcher
: public PredicateListMatcher
<OperandPredicateMatcher
> {
1238 InstructionMatcher
&Insn
;
1240 std::string SymbolicName
;
1242 /// The index of the first temporary variable allocated to this operand. The
1243 /// number of allocated temporaries can be found with
1244 /// countRendererFns().
1245 unsigned AllocatedTemporariesBaseID
;
1247 TempTypeIdx TTIdx
= 0;
1250 OperandMatcher(InstructionMatcher
&Insn
, unsigned OpIdx
,
1251 const std::string
&SymbolicName
,
1252 unsigned AllocatedTemporariesBaseID
)
1253 : Insn(Insn
), OpIdx(OpIdx
), SymbolicName(SymbolicName
),
1254 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID
) {}
1256 bool hasSymbolicName() const { return !SymbolicName
.empty(); }
1257 StringRef
getSymbolicName() const { return SymbolicName
; }
1258 void setSymbolicName(StringRef Name
) {
1259 assert(SymbolicName
.empty() && "Operand already has a symbolic name");
1260 SymbolicName
= std::string(Name
);
1263 /// Construct a new operand predicate and add it to the matcher.
1264 template <class Kind
, class... Args
>
1265 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1266 if (isSameAsAnotherOperand())
1267 return std::nullopt
;
1268 Predicates
.emplace_back(std::make_unique
<Kind
>(
1269 getInsnVarID(), getOpIdx(), std::forward
<Args
>(args
)...));
1270 return static_cast<Kind
*>(Predicates
.back().get());
1273 unsigned getOpIdx() const { return OpIdx
; }
1274 unsigned getInsnVarID() const;
1276 /// If this OperandMatcher has not been assigned a TempTypeIdx yet, assigns it
1277 /// one and adds a `RecordRegisterType` predicate to this matcher. If one has
1278 /// already been assigned, simply returns it.
1279 TempTypeIdx
getTempTypeIdx(RuleMatcher
&Rule
);
1281 std::string
getOperandExpr(unsigned InsnVarID
) const;
1283 InstructionMatcher
&getInstructionMatcher() const { return Insn
; }
1285 Error
addTypeCheckPredicate(const TypeSetByHwMode
&VTy
,
1286 bool OperandIsAPointer
);
1288 /// Emit MatchTable opcodes that test whether the instruction named in
1289 /// InsnVarID matches all the predicates and all the operands.
1290 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1292 /// Compare the priority of this object and B.
1294 /// Returns true if this object is more important than B.
1295 bool isHigherPriorityThan(OperandMatcher
&B
);
1297 /// Report the maximum number of temporary operands needed by the operand
1299 unsigned countRendererFns();
1301 unsigned getAllocatedTemporariesBaseID() const {
1302 return AllocatedTemporariesBaseID
;
1305 bool isSameAsAnotherOperand() {
1306 for (const auto &Predicate
: predicates())
1307 if (isa
<SameOperandMatcher
>(Predicate
))
1313 /// Generates code to check a predicate on an instruction.
1315 /// Typical predicates include:
1316 /// * The opcode of the instruction is a particular value.
1317 /// * The nsw/nuw flag is/isn't set.
1318 class InstructionPredicateMatcher
: public PredicateMatcher
{
1320 InstructionPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
)
1321 : PredicateMatcher(Kind
, InsnVarID
) {}
1322 virtual ~InstructionPredicateMatcher() {}
1324 /// Compare the priority of this object and B.
1326 /// Returns true if this object is more important than B.
1328 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const {
1329 return Kind
< B
.Kind
;
1335 PredicateListMatcher
<PredicateMatcher
>::getNoPredicateComment() const {
1336 return "No instruction predicates";
1339 /// Generates code to check the opcode of an instruction.
1340 class InstructionOpcodeMatcher
: public InstructionPredicateMatcher
{
1342 // Allow matching one to several, similar opcodes that share properties. This
1343 // is to handle patterns where one SelectionDAG operation maps to multiple
1344 // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
1345 // is treated as the canonical opcode.
1346 SmallVector
<const CodeGenInstruction
*, 2> Insts
;
1348 static DenseMap
<const CodeGenInstruction
*, unsigned> OpcodeValues
;
1350 MatchTableRecord
getInstValue(const CodeGenInstruction
*I
) const;
1353 static void initOpcodeValuesMap(const CodeGenTarget
&Target
);
1355 InstructionOpcodeMatcher(unsigned InsnVarID
,
1356 ArrayRef
<const CodeGenInstruction
*> I
)
1357 : InstructionPredicateMatcher(IPM_Opcode
, InsnVarID
),
1358 Insts(I
.begin(), I
.end()) {
1359 assert((Insts
.size() == 1 || Insts
.size() == 2) &&
1360 "unexpected number of opcode alternatives");
1363 static bool classof(const PredicateMatcher
*P
) {
1364 return P
->getKind() == IPM_Opcode
;
1367 bool isIdentical(const PredicateMatcher
&B
) const override
{
1368 return InstructionPredicateMatcher::isIdentical(B
) &&
1369 Insts
== cast
<InstructionOpcodeMatcher
>(&B
)->Insts
;
1372 bool hasValue() const override
{
1373 return Insts
.size() == 1 && OpcodeValues
.count(Insts
[0]);
1376 // TODO: This is used for the SwitchMatcher optimization. We should be able to
1377 // return a list of the opcodes to match.
1378 MatchTableRecord
getValue() const override
;
1380 void emitPredicateOpcodes(MatchTable
&Table
,
1381 RuleMatcher
&Rule
) const override
;
1383 /// Compare the priority of this object and B.
1385 /// Returns true if this object is more important than B.
1387 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const override
;
1389 bool isConstantInstruction() const;
1391 // The first opcode is the canonical opcode, and later are alternatives.
1392 StringRef
getOpcode() const;
1393 ArrayRef
<const CodeGenInstruction
*> getAlternativeOpcodes() { return Insts
; }
1394 bool isVariadicNumOperands() const;
1395 StringRef
getOperandType(unsigned OpIdx
) const;
1398 class InstructionNumOperandsMatcher final
: public InstructionPredicateMatcher
{
1399 unsigned NumOperands
= 0;
1402 InstructionNumOperandsMatcher(unsigned InsnVarID
, unsigned NumOperands
)
1403 : InstructionPredicateMatcher(IPM_NumOperands
, InsnVarID
),
1404 NumOperands(NumOperands
) {}
1406 static bool classof(const PredicateMatcher
*P
) {
1407 return P
->getKind() == IPM_NumOperands
;
1410 bool isIdentical(const PredicateMatcher
&B
) const override
{
1411 return InstructionPredicateMatcher::isIdentical(B
) &&
1412 NumOperands
== cast
<InstructionNumOperandsMatcher
>(&B
)->NumOperands
;
1415 void emitPredicateOpcodes(MatchTable
&Table
,
1416 RuleMatcher
&Rule
) const override
;
1419 /// Generates code to check that this instruction is a constant whose value
1420 /// meets an immediate predicate.
1422 /// Immediates are slightly odd since they are typically used like an operand
1423 /// but are represented as an operator internally. We typically write simm8:$src
1424 /// in a tablegen pattern, but this is just syntactic sugar for
1425 /// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1426 /// that will be matched and the predicate (which is attached to the imm
1427 /// operator) that will be tested. In SelectionDAG this describes a
1428 /// ConstantSDNode whose internal value will be tested using the simm8
1431 /// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1432 /// this representation, the immediate could be tested with an
1433 /// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1434 /// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1435 /// there are two implementation issues with producing that matcher
1436 /// configuration from the SelectionDAG pattern:
1437 /// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1438 /// were we to sink the immediate predicate to the operand we would have to
1439 /// have two partial implementations of PatFrag support, one for immediates
1440 /// and one for non-immediates.
1441 /// * At the point we handle the predicate, the OperandMatcher hasn't been
1442 /// created yet. If we were to sink the predicate to the OperandMatcher we
1443 /// would also have to complicate (or duplicate) the code that descends and
1444 /// creates matchers for the subtree.
1445 /// Overall, it's simpler to handle it in the place it was found.
1446 class InstructionImmPredicateMatcher
: public InstructionPredicateMatcher
{
1448 TreePredicateFn Predicate
;
1451 InstructionImmPredicateMatcher(unsigned InsnVarID
,
1452 const TreePredicateFn
&Predicate
)
1453 : InstructionPredicateMatcher(IPM_ImmPredicate
, InsnVarID
),
1454 Predicate(Predicate
) {}
1456 bool isIdentical(const PredicateMatcher
&B
) const override
;
1458 static bool classof(const PredicateMatcher
*P
) {
1459 return P
->getKind() == IPM_ImmPredicate
;
1462 void emitPredicateOpcodes(MatchTable
&Table
,
1463 RuleMatcher
&Rule
) const override
;
1466 /// Generates code to check that a memory instruction has a atomic ordering
1467 /// MachineMemoryOperand.
1468 class AtomicOrderingMMOPredicateMatcher
: public InstructionPredicateMatcher
{
1478 AOComparator Comparator
;
1481 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID
, StringRef Order
,
1482 AOComparator Comparator
= AO_Exactly
)
1483 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO
, InsnVarID
),
1484 Order(Order
), Comparator(Comparator
) {}
1486 static bool classof(const PredicateMatcher
*P
) {
1487 return P
->getKind() == IPM_AtomicOrderingMMO
;
1490 bool isIdentical(const PredicateMatcher
&B
) const override
;
1492 void emitPredicateOpcodes(MatchTable
&Table
,
1493 RuleMatcher
&Rule
) const override
;
1496 /// Generates code to check that the size of an MMO is exactly N bytes.
1497 class MemorySizePredicateMatcher
: public InstructionPredicateMatcher
{
1503 MemorySizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
, unsigned Size
)
1504 : InstructionPredicateMatcher(IPM_MemoryLLTSize
, InsnVarID
),
1505 MMOIdx(MMOIdx
), Size(Size
) {}
1507 static bool classof(const PredicateMatcher
*P
) {
1508 return P
->getKind() == IPM_MemoryLLTSize
;
1510 bool isIdentical(const PredicateMatcher
&B
) const override
{
1511 return InstructionPredicateMatcher::isIdentical(B
) &&
1512 MMOIdx
== cast
<MemorySizePredicateMatcher
>(&B
)->MMOIdx
&&
1513 Size
== cast
<MemorySizePredicateMatcher
>(&B
)->Size
;
1516 void emitPredicateOpcodes(MatchTable
&Table
,
1517 RuleMatcher
&Rule
) const override
;
1520 class MemoryAddressSpacePredicateMatcher
: public InstructionPredicateMatcher
{
1523 SmallVector
<unsigned, 4> AddrSpaces
;
1526 MemoryAddressSpacePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1527 ArrayRef
<unsigned> AddrSpaces
)
1528 : InstructionPredicateMatcher(IPM_MemoryAddressSpace
, InsnVarID
),
1529 MMOIdx(MMOIdx
), AddrSpaces(AddrSpaces
.begin(), AddrSpaces
.end()) {}
1531 static bool classof(const PredicateMatcher
*P
) {
1532 return P
->getKind() == IPM_MemoryAddressSpace
;
1535 bool isIdentical(const PredicateMatcher
&B
) const override
;
1537 void emitPredicateOpcodes(MatchTable
&Table
,
1538 RuleMatcher
&Rule
) const override
;
1541 class MemoryAlignmentPredicateMatcher
: public InstructionPredicateMatcher
{
1547 MemoryAlignmentPredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1549 : InstructionPredicateMatcher(IPM_MemoryAlignment
, InsnVarID
),
1550 MMOIdx(MMOIdx
), MinAlign(MinAlign
) {
1551 assert(MinAlign
> 0);
1554 static bool classof(const PredicateMatcher
*P
) {
1555 return P
->getKind() == IPM_MemoryAlignment
;
1558 bool isIdentical(const PredicateMatcher
&B
) const override
;
1560 void emitPredicateOpcodes(MatchTable
&Table
,
1561 RuleMatcher
&Rule
) const override
;
1564 /// Generates code to check that the size of an MMO is less-than, equal-to, or
1565 /// greater than a given LLT.
1566 class MemoryVsLLTSizePredicateMatcher
: public InstructionPredicateMatcher
{
1576 RelationKind Relation
;
1580 MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1581 enum RelationKind Relation
, unsigned OpIdx
)
1582 : InstructionPredicateMatcher(IPM_MemoryVsLLTSize
, InsnVarID
),
1583 MMOIdx(MMOIdx
), Relation(Relation
), OpIdx(OpIdx
) {}
1585 static bool classof(const PredicateMatcher
*P
) {
1586 return P
->getKind() == IPM_MemoryVsLLTSize
;
1588 bool isIdentical(const PredicateMatcher
&B
) const override
;
1590 void emitPredicateOpcodes(MatchTable
&Table
,
1591 RuleMatcher
&Rule
) const override
;
1594 // Matcher for immAllOnesV/immAllZerosV
1595 class VectorSplatImmPredicateMatcher
: public InstructionPredicateMatcher
{
1597 enum SplatKind
{ AllZeros
, AllOnes
};
1603 VectorSplatImmPredicateMatcher(unsigned InsnVarID
, SplatKind K
)
1604 : InstructionPredicateMatcher(IPM_VectorSplatImm
, InsnVarID
), Kind(K
) {}
1606 static bool classof(const PredicateMatcher
*P
) {
1607 return P
->getKind() == IPM_VectorSplatImm
;
1610 bool isIdentical(const PredicateMatcher
&B
) const override
{
1611 return InstructionPredicateMatcher::isIdentical(B
) &&
1612 Kind
== static_cast<const VectorSplatImmPredicateMatcher
&>(B
).Kind
;
1615 void emitPredicateOpcodes(MatchTable
&Table
,
1616 RuleMatcher
&Rule
) const override
;
1619 /// Generates code to check an arbitrary C++ instruction predicate.
1620 class GenericInstructionPredicateMatcher
: public InstructionPredicateMatcher
{
1622 std::string EnumVal
;
1625 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1626 TreePredicateFn Predicate
);
1628 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1629 const std::string
&EnumVal
)
1630 : InstructionPredicateMatcher(IPM_GenericPredicate
, InsnVarID
),
1633 static bool classof(const InstructionPredicateMatcher
*P
) {
1634 return P
->getKind() == IPM_GenericPredicate
;
1636 bool isIdentical(const PredicateMatcher
&B
) const override
;
1637 void emitPredicateOpcodes(MatchTable
&Table
,
1638 RuleMatcher
&Rule
) const override
;
1641 class MIFlagsInstructionPredicateMatcher
: public InstructionPredicateMatcher
{
1642 SmallVector
<StringRef
, 2> Flags
;
1643 bool CheckNot
; // false = GIM_MIFlags, true = GIM_MIFlagsNot
1646 MIFlagsInstructionPredicateMatcher(unsigned InsnVarID
,
1647 ArrayRef
<StringRef
> FlagsToCheck
,
1648 bool CheckNot
= false)
1649 : InstructionPredicateMatcher(IPM_MIFlags
, InsnVarID
),
1650 Flags(FlagsToCheck
), CheckNot(CheckNot
) {
1654 static bool classof(const InstructionPredicateMatcher
*P
) {
1655 return P
->getKind() == IPM_MIFlags
;
1658 bool isIdentical(const PredicateMatcher
&B
) const override
;
1659 void emitPredicateOpcodes(MatchTable
&Table
,
1660 RuleMatcher
&Rule
) const override
;
1663 /// Generates code to check for the absence of use of the result.
1664 // TODO? Generalize this to support checking for one use.
1665 class NoUsePredicateMatcher
: public InstructionPredicateMatcher
{
1667 NoUsePredicateMatcher(unsigned InsnVarID
)
1668 : InstructionPredicateMatcher(IPM_NoUse
, InsnVarID
) {}
1670 static bool classof(const PredicateMatcher
*P
) {
1671 return P
->getKind() == IPM_NoUse
;
1674 bool isIdentical(const PredicateMatcher
&B
) const override
{
1675 return InstructionPredicateMatcher::isIdentical(B
);
1678 void emitPredicateOpcodes(MatchTable
&Table
,
1679 RuleMatcher
&Rule
) const override
{
1680 Table
<< MatchTable::Opcode("GIM_CheckHasNoUse")
1681 << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID
)
1682 << MatchTable::LineBreak
;
1686 /// Generates code to check that a set of predicates and operands match for a
1687 /// particular instruction.
1689 /// Typical predicates include:
1690 /// * Has a specific opcode.
1691 /// * Has an nsw/nuw flag or doesn't.
1692 class InstructionMatcher final
: public PredicateListMatcher
<PredicateMatcher
> {
1694 typedef std::vector
<std::unique_ptr
<OperandMatcher
>> OperandVec
;
1698 /// The operands to match. All rendered operands must be present even if the
1699 /// condition is always true.
1700 OperandVec Operands
;
1701 bool NumOperandsCheck
= true;
1703 std::string SymbolicName
;
1706 /// PhysRegInputs - List list has an entry for each explicitly specified
1707 /// physreg input to the pattern. The first elt is the Register node, the
1708 /// second is the recorded slot number the input pattern match saved it in.
1709 SmallVector
<std::pair
<Record
*, unsigned>, 2> PhysRegInputs
;
1712 InstructionMatcher(RuleMatcher
&Rule
, StringRef SymbolicName
,
1713 bool NumOpsCheck
= true)
1714 : Rule(Rule
), NumOperandsCheck(NumOpsCheck
), SymbolicName(SymbolicName
) {
1715 // We create a new instruction matcher.
1716 // Get a new ID for that instruction.
1717 InsnVarID
= Rule
.implicitlyDefineInsnVar(*this);
1720 /// Construct a new instruction predicate and add it to the matcher.
1721 template <class Kind
, class... Args
>
1722 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1723 Predicates
.emplace_back(
1724 std::make_unique
<Kind
>(getInsnVarID(), std::forward
<Args
>(args
)...));
1725 return static_cast<Kind
*>(Predicates
.back().get());
1728 RuleMatcher
&getRuleMatcher() const { return Rule
; }
1730 unsigned getInsnVarID() const { return InsnVarID
; }
1732 /// Add an operand to the matcher.
1733 OperandMatcher
&addOperand(unsigned OpIdx
, const std::string
&SymbolicName
,
1734 unsigned AllocatedTemporariesBaseID
);
1735 OperandMatcher
&getOperand(unsigned OpIdx
);
1736 OperandMatcher
&addPhysRegInput(Record
*Reg
, unsigned OpIdx
,
1737 unsigned TempOpIdx
);
1739 ArrayRef
<std::pair
<Record
*, unsigned>> getPhysRegInputs() const {
1740 return PhysRegInputs
;
1743 StringRef
getSymbolicName() const { return SymbolicName
; }
1744 unsigned getNumOperands() const { return Operands
.size(); }
1745 OperandVec::iterator
operands_begin() { return Operands
.begin(); }
1746 OperandVec::iterator
operands_end() { return Operands
.end(); }
1747 iterator_range
<OperandVec::iterator
> operands() {
1748 return make_range(operands_begin(), operands_end());
1750 OperandVec::const_iterator
operands_begin() const { return Operands
.begin(); }
1751 OperandVec::const_iterator
operands_end() const { return Operands
.end(); }
1752 iterator_range
<OperandVec::const_iterator
> operands() const {
1753 return make_range(operands_begin(), operands_end());
1755 bool operands_empty() const { return Operands
.empty(); }
1757 void pop_front() { Operands
.erase(Operands
.begin()); }
1761 /// Emit MatchTable opcodes that test whether the instruction named in
1762 /// InsnVarName matches all the predicates and all the operands.
1763 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1765 /// Compare the priority of this object and B.
1767 /// Returns true if this object is more important than B.
1768 bool isHigherPriorityThan(InstructionMatcher
&B
);
1770 /// Report the maximum number of temporary operands needed by the instruction
1772 unsigned countRendererFns();
1774 InstructionOpcodeMatcher
&getOpcodeMatcher() {
1775 for (auto &P
: predicates())
1776 if (auto *OpMatcher
= dyn_cast
<InstructionOpcodeMatcher
>(P
.get()))
1778 llvm_unreachable("Didn't find an opcode matcher");
1781 bool isConstantInstruction() {
1782 return getOpcodeMatcher().isConstantInstruction();
1785 StringRef
getOpcode() { return getOpcodeMatcher().getOpcode(); }
1788 /// Generates code to check that the operand is a register defined by an
1789 /// instruction that matches the given instruction matcher.
1791 /// For example, the pattern:
1792 /// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1793 /// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1795 /// (G_ADD $src1, $src2)
1797 class InstructionOperandMatcher
: public OperandPredicateMatcher
{
1799 std::unique_ptr
<InstructionMatcher
> InsnMatcher
;
1804 InstructionOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1805 RuleMatcher
&Rule
, StringRef SymbolicName
,
1806 bool NumOpsCheck
= true)
1807 : OperandPredicateMatcher(OPM_Instruction
, InsnVarID
, OpIdx
),
1808 InsnMatcher(new InstructionMatcher(Rule
, SymbolicName
, NumOpsCheck
)),
1809 Flags(Rule
.getGISelFlags()) {}
1811 static bool classof(const PredicateMatcher
*P
) {
1812 return P
->getKind() == OPM_Instruction
;
1815 InstructionMatcher
&getInsnMatcher() const { return *InsnMatcher
; }
1817 void emitCaptureOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const;
1818 void emitPredicateOpcodes(MatchTable
&Table
,
1819 RuleMatcher
&Rule
) const override
{
1820 emitCaptureOpcodes(Table
, Rule
);
1821 InsnMatcher
->emitPredicateOpcodes(Table
, Rule
);
1824 bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const override
;
1826 /// Report the maximum number of temporary operands needed by the predicate
1828 unsigned countRendererFns() const override
{
1829 return InsnMatcher
->countRendererFns();
1833 //===- Actions ------------------------------------------------------------===//
1834 class OperandRenderer
{
1838 OR_CopyOrAddZeroReg
,
1841 OR_CopyConstantAsImm
,
1842 OR_CopyFConstantAsFPImm
,
1856 OperandRenderer(RendererKind Kind
) : Kind(Kind
) {}
1857 virtual ~OperandRenderer();
1859 RendererKind
getKind() const { return Kind
; }
1861 virtual void emitRenderOpcodes(MatchTable
&Table
,
1862 RuleMatcher
&Rule
) const = 0;
1865 /// A CopyRenderer emits code to copy a single operand from an existing
1866 /// instruction to the one being built.
1867 class CopyRenderer
: public OperandRenderer
{
1870 /// The name of the operand.
1871 const StringRef SymbolicName
;
1874 CopyRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1875 : OperandRenderer(OR_Copy
), NewInsnID(NewInsnID
),
1876 SymbolicName(SymbolicName
) {
1877 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
1880 static bool classof(const OperandRenderer
*R
) {
1881 return R
->getKind() == OR_Copy
;
1884 StringRef
getSymbolicName() const { return SymbolicName
; }
1886 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1889 /// A CopyRenderer emits code to copy a virtual register to a specific physical
1891 class CopyPhysRegRenderer
: public OperandRenderer
{
1897 CopyPhysRegRenderer(unsigned NewInsnID
, Record
*Reg
)
1898 : OperandRenderer(OR_CopyPhysReg
), NewInsnID(NewInsnID
), PhysReg(Reg
) {
1902 static bool classof(const OperandRenderer
*R
) {
1903 return R
->getKind() == OR_CopyPhysReg
;
1906 Record
*getPhysReg() const { return PhysReg
; }
1908 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1911 /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1912 /// existing instruction to the one being built. If the operand turns out to be
1913 /// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1914 class CopyOrAddZeroRegRenderer
: public OperandRenderer
{
1917 /// The name of the operand.
1918 const StringRef SymbolicName
;
1919 const Record
*ZeroRegisterDef
;
1922 CopyOrAddZeroRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
1923 Record
*ZeroRegisterDef
)
1924 : OperandRenderer(OR_CopyOrAddZeroReg
), NewInsnID(NewInsnID
),
1925 SymbolicName(SymbolicName
), ZeroRegisterDef(ZeroRegisterDef
) {
1926 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
1929 static bool classof(const OperandRenderer
*R
) {
1930 return R
->getKind() == OR_CopyOrAddZeroReg
;
1933 StringRef
getSymbolicName() const { return SymbolicName
; }
1935 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1938 /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1939 /// an extended immediate operand.
1940 class CopyConstantAsImmRenderer
: public OperandRenderer
{
1943 /// The name of the operand.
1944 const std::string SymbolicName
;
1948 CopyConstantAsImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1949 : OperandRenderer(OR_CopyConstantAsImm
), NewInsnID(NewInsnID
),
1950 SymbolicName(SymbolicName
), Signed(true) {}
1952 static bool classof(const OperandRenderer
*R
) {
1953 return R
->getKind() == OR_CopyConstantAsImm
;
1956 StringRef
getSymbolicName() const { return SymbolicName
; }
1958 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1961 /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1962 /// instruction to an extended immediate operand.
1963 class CopyFConstantAsFPImmRenderer
: public OperandRenderer
{
1966 /// The name of the operand.
1967 const std::string SymbolicName
;
1970 CopyFConstantAsFPImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1971 : OperandRenderer(OR_CopyFConstantAsFPImm
), NewInsnID(NewInsnID
),
1972 SymbolicName(SymbolicName
) {}
1974 static bool classof(const OperandRenderer
*R
) {
1975 return R
->getKind() == OR_CopyFConstantAsFPImm
;
1978 StringRef
getSymbolicName() const { return SymbolicName
; }
1980 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1983 /// A CopySubRegRenderer emits code to copy a single register operand from an
1984 /// existing instruction to the one being built and indicate that only a
1985 /// subregister should be copied.
1986 class CopySubRegRenderer
: public OperandRenderer
{
1989 /// The name of the operand.
1990 const StringRef SymbolicName
;
1991 /// The subregister to extract.
1992 const CodeGenSubRegIndex
*SubReg
;
1995 CopySubRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
1996 const CodeGenSubRegIndex
*SubReg
)
1997 : OperandRenderer(OR_CopySubReg
), NewInsnID(NewInsnID
),
1998 SymbolicName(SymbolicName
), SubReg(SubReg
) {}
2000 static bool classof(const OperandRenderer
*R
) {
2001 return R
->getKind() == OR_CopySubReg
;
2004 StringRef
getSymbolicName() const { return SymbolicName
; }
2006 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2009 /// Adds a specific physical register to the instruction being built.
2010 /// This is typically useful for WZR/XZR on AArch64.
2011 class AddRegisterRenderer
: public OperandRenderer
{
2014 const Record
*RegisterDef
;
2016 const CodeGenTarget
&Target
;
2019 AddRegisterRenderer(unsigned InsnID
, const CodeGenTarget
&Target
,
2020 const Record
*RegisterDef
, bool IsDef
= false)
2021 : OperandRenderer(OR_Register
), InsnID(InsnID
), RegisterDef(RegisterDef
),
2022 IsDef(IsDef
), Target(Target
) {}
2024 static bool classof(const OperandRenderer
*R
) {
2025 return R
->getKind() == OR_Register
;
2028 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2031 /// Adds a specific temporary virtual register to the instruction being built.
2032 /// This is used to chain instructions together when emitting multiple
2034 class TempRegRenderer
: public OperandRenderer
{
2038 const CodeGenSubRegIndex
*SubRegIdx
;
2043 TempRegRenderer(unsigned InsnID
, unsigned TempRegID
, bool IsDef
= false,
2044 const CodeGenSubRegIndex
*SubReg
= nullptr,
2045 bool IsDead
= false)
2046 : OperandRenderer(OR_Register
), InsnID(InsnID
), TempRegID(TempRegID
),
2047 SubRegIdx(SubReg
), IsDef(IsDef
), IsDead(IsDead
) {}
2049 static bool classof(const OperandRenderer
*R
) {
2050 return R
->getKind() == OR_TempRegister
;
2053 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2056 /// Adds a specific immediate to the instruction being built.
2057 /// If a LLT is passed, a ConstantInt immediate is created instead.
2058 class ImmRenderer
: public OperandRenderer
{
2062 std::optional
<LLTCodeGenOrTempType
> CImmLLT
;
2065 ImmRenderer(unsigned InsnID
, int64_t Imm
)
2066 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
) {}
2068 ImmRenderer(unsigned InsnID
, int64_t Imm
, const LLTCodeGenOrTempType
&CImmLLT
)
2069 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
), CImmLLT(CImmLLT
) {
2070 if (CImmLLT
.isLLTCodeGen())
2071 KnownTypes
.insert(CImmLLT
.getLLTCodeGen());
2074 static bool classof(const OperandRenderer
*R
) {
2075 return R
->getKind() == OR_Imm
;
2078 static void emitAddImm(MatchTable
&Table
, RuleMatcher
&RM
, unsigned InsnID
,
2079 int64_t Imm
, StringRef ImmName
= "Imm");
2081 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2084 /// Adds an enum value for a subreg index to the instruction being built.
2085 class SubRegIndexRenderer
: public OperandRenderer
{
2088 const CodeGenSubRegIndex
*SubRegIdx
;
2091 SubRegIndexRenderer(unsigned InsnID
, const CodeGenSubRegIndex
*SRI
)
2092 : OperandRenderer(OR_SubRegIndex
), InsnID(InsnID
), SubRegIdx(SRI
) {}
2094 static bool classof(const OperandRenderer
*R
) {
2095 return R
->getKind() == OR_SubRegIndex
;
2098 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2101 /// Adds operands by calling a renderer function supplied by the ComplexPattern
2102 /// matcher function.
2103 class RenderComplexPatternOperand
: public OperandRenderer
{
2106 const Record
&TheDef
;
2107 /// The name of the operand.
2108 const StringRef SymbolicName
;
2109 /// The renderer number. This must be unique within a rule since it's used to
2110 /// identify a temporary variable to hold the renderer function.
2111 unsigned RendererID
;
2112 /// When provided, this is the suboperand of the ComplexPattern operand to
2113 /// render. Otherwise all the suboperands will be rendered.
2114 std::optional
<unsigned> SubOperand
;
2115 /// The subregister to extract. Render the whole register if not specified.
2116 const CodeGenSubRegIndex
*SubReg
;
2118 unsigned getNumOperands() const {
2119 return TheDef
.getValueAsDag("Operands")->getNumArgs();
2123 RenderComplexPatternOperand(unsigned InsnID
, const Record
&TheDef
,
2124 StringRef SymbolicName
, unsigned RendererID
,
2125 std::optional
<unsigned> SubOperand
= std::nullopt
,
2126 const CodeGenSubRegIndex
*SubReg
= nullptr)
2127 : OperandRenderer(OR_ComplexPattern
), InsnID(InsnID
), TheDef(TheDef
),
2128 SymbolicName(SymbolicName
), RendererID(RendererID
),
2129 SubOperand(SubOperand
), SubReg(SubReg
) {}
2131 static bool classof(const OperandRenderer
*R
) {
2132 return R
->getKind() == OR_ComplexPattern
;
2135 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2138 class CustomRenderer
: public OperandRenderer
{
2141 const Record
&Renderer
;
2142 /// The name of the operand.
2143 const std::string SymbolicName
;
2146 CustomRenderer(unsigned InsnID
, const Record
&Renderer
,
2147 StringRef SymbolicName
)
2148 : OperandRenderer(OR_Custom
), InsnID(InsnID
), Renderer(Renderer
),
2149 SymbolicName(SymbolicName
) {}
2151 static bool classof(const OperandRenderer
*R
) {
2152 return R
->getKind() == OR_Custom
;
2155 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2158 class CustomOperandRenderer
: public OperandRenderer
{
2161 const Record
&Renderer
;
2162 /// The name of the operand.
2163 const std::string SymbolicName
;
2166 CustomOperandRenderer(unsigned InsnID
, const Record
&Renderer
,
2167 StringRef SymbolicName
)
2168 : OperandRenderer(OR_CustomOperand
), InsnID(InsnID
), Renderer(Renderer
),
2169 SymbolicName(SymbolicName
) {}
2171 static bool classof(const OperandRenderer
*R
) {
2172 return R
->getKind() == OR_CustomOperand
;
2175 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2178 /// An action taken when all Matcher predicates succeeded for a parent rule.
2180 /// Typical actions include:
2181 /// * Changing the opcode of an instruction.
2182 /// * Adding an operand to an instruction.
2192 AK_ConstraintOpsToDef
,
2193 AK_ConstraintOpsToRC
,
2197 MatchAction(ActionKind K
) : Kind(K
) {}
2199 ActionKind
getKind() const { return Kind
; }
2201 virtual ~MatchAction() {}
2203 // Some actions may need to add extra predicates to ensure they can run.
2204 virtual void emitAdditionalPredicates(MatchTable
&Table
,
2205 RuleMatcher
&Rule
) const {}
2207 /// Emit the MatchTable opcodes to implement the action.
2208 virtual void emitActionOpcodes(MatchTable
&Table
,
2209 RuleMatcher
&Rule
) const = 0;
2215 /// Generates a comment describing the matched rule being acted upon.
2216 class DebugCommentAction
: public MatchAction
{
2221 DebugCommentAction(StringRef S
)
2222 : MatchAction(AK_DebugComment
), S(std::string(S
)) {}
2224 static bool classof(const MatchAction
*A
) {
2225 return A
->getKind() == AK_DebugComment
;
2228 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2229 Table
<< MatchTable::Comment(S
) << MatchTable::LineBreak
;
2233 class CustomCXXAction
: public MatchAction
{
2234 std::string FnEnumName
;
2237 CustomCXXAction(StringRef FnEnumName
)
2238 : MatchAction(AK_CustomCXX
), FnEnumName(FnEnumName
.str()) {}
2240 static bool classof(const MatchAction
*A
) {
2241 return A
->getKind() == AK_CustomCXX
;
2244 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2247 /// Generates code to build an instruction or mutate an existing instruction
2248 /// into the desired instruction when this is possible.
2249 class BuildMIAction
: public MatchAction
{
2252 const CodeGenInstruction
*I
;
2253 InstructionMatcher
*Matched
;
2254 std::vector
<std::unique_ptr
<OperandRenderer
>> OperandRenderers
;
2255 SmallPtrSet
<Record
*, 4> DeadImplicitDefs
;
2257 std::vector
<const InstructionMatcher
*> CopiedFlags
;
2258 std::vector
<StringRef
> SetFlags
;
2259 std::vector
<StringRef
> UnsetFlags
;
2261 /// True if the instruction can be built solely by mutating the opcode.
2262 bool canMutate(RuleMatcher
&Rule
, const InstructionMatcher
*Insn
) const;
2265 BuildMIAction(unsigned InsnID
, const CodeGenInstruction
*I
)
2266 : MatchAction(AK_BuildMI
), InsnID(InsnID
), I(I
), Matched(nullptr) {}
2268 static bool classof(const MatchAction
*A
) {
2269 return A
->getKind() == AK_BuildMI
;
2272 unsigned getInsnID() const { return InsnID
; }
2273 const CodeGenInstruction
*getCGI() const { return I
; }
2275 void addSetMIFlags(StringRef Flag
) { SetFlags
.push_back(Flag
); }
2276 void addUnsetMIFlags(StringRef Flag
) { UnsetFlags
.push_back(Flag
); }
2277 void addCopiedMIFlags(const InstructionMatcher
&IM
) {
2278 CopiedFlags
.push_back(&IM
);
2281 void chooseInsnToMutate(RuleMatcher
&Rule
);
2283 void setDeadImplicitDef(Record
*R
) { DeadImplicitDefs
.insert(R
); }
2285 template <class Kind
, class... Args
> Kind
&addRenderer(Args
&&...args
) {
2286 OperandRenderers
.emplace_back(
2287 std::make_unique
<Kind
>(InsnID
, std::forward
<Args
>(args
)...));
2288 return *static_cast<Kind
*>(OperandRenderers
.back().get());
2291 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2294 /// Generates code to create a constant that defines a TempReg.
2295 /// The instruction created is usually a G_CONSTANT but it could also be a
2296 /// G_BUILD_VECTOR for vector types.
2297 class BuildConstantAction
: public MatchAction
{
2302 BuildConstantAction(unsigned TempRegID
, int64_t Val
)
2303 : MatchAction(AK_BuildConstantMI
), TempRegID(TempRegID
), Val(Val
) {}
2305 static bool classof(const MatchAction
*A
) {
2306 return A
->getKind() == AK_BuildConstantMI
;
2309 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2312 class EraseInstAction
: public MatchAction
{
2316 EraseInstAction(unsigned InsnID
)
2317 : MatchAction(AK_EraseInst
), InsnID(InsnID
) {}
2319 static bool classof(const MatchAction
*A
) {
2320 return A
->getKind() == AK_EraseInst
;
2323 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2324 static void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
,
2328 class ReplaceRegAction
: public MatchAction
{
2329 unsigned OldInsnID
, OldOpIdx
;
2330 unsigned NewInsnId
= -1, NewOpIdx
;
2331 unsigned TempRegID
= -1;
2334 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned NewInsnId
,
2336 : MatchAction(AK_EraseInst
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2337 NewInsnId(NewInsnId
), NewOpIdx(NewOpIdx
) {}
2339 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned TempRegID
)
2340 : MatchAction(AK_EraseInst
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2341 TempRegID(TempRegID
) {}
2343 static bool classof(const MatchAction
*A
) {
2344 return A
->getKind() == AK_ReplaceReg
;
2347 void emitAdditionalPredicates(MatchTable
&Table
,
2348 RuleMatcher
&Rule
) const override
;
2349 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2352 /// Generates code to constrain the operands of an output instruction to the
2353 /// register classes specified by the definition of that instruction.
2354 class ConstrainOperandsToDefinitionAction
: public MatchAction
{
2358 ConstrainOperandsToDefinitionAction(unsigned InsnID
)
2359 : MatchAction(AK_ConstraintOpsToDef
), InsnID(InsnID
) {}
2361 static bool classof(const MatchAction
*A
) {
2362 return A
->getKind() == AK_ConstraintOpsToDef
;
2365 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2366 Table
<< MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2367 << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID
)
2368 << MatchTable::LineBreak
;
2372 /// Generates code to constrain the specified operand of an output instruction
2373 /// to the specified register class.
2374 class ConstrainOperandToRegClassAction
: public MatchAction
{
2377 const CodeGenRegisterClass
&RC
;
2380 ConstrainOperandToRegClassAction(unsigned InsnID
, unsigned OpIdx
,
2381 const CodeGenRegisterClass
&RC
)
2382 : MatchAction(AK_ConstraintOpsToRC
), InsnID(InsnID
), OpIdx(OpIdx
),
2385 static bool classof(const MatchAction
*A
) {
2386 return A
->getKind() == AK_ConstraintOpsToRC
;
2389 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2392 /// Generates code to create a temporary register which can be used to chain
2393 /// instructions together.
2394 class MakeTempRegisterAction
: public MatchAction
{
2396 LLTCodeGenOrTempType Ty
;
2400 MakeTempRegisterAction(const LLTCodeGenOrTempType
&Ty
, unsigned TempRegID
)
2401 : MatchAction(AK_MakeTempReg
), Ty(Ty
), TempRegID(TempRegID
) {
2402 if (Ty
.isLLTCodeGen())
2403 KnownTypes
.insert(Ty
.getLLTCodeGen());
2406 static bool classof(const MatchAction
*A
) {
2407 return A
->getKind() == AK_MakeTempReg
;
2410 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;