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_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H
17 #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H
19 #include "Common/CodeGenDAGPatterns.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/CodeGenTypes/LowLevelType.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/SaveAndRestore.h"
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::uint32_t;
60 //===- Helper functions ---------------------------------------------------===//
62 void emitEncodingMacrosDef(raw_ostream
&OS
);
63 void emitEncodingMacrosUndef(raw_ostream
&OS
);
65 std::string
getNameForFeatureBitset(ArrayRef
<const Record
*> FeatureBitset
,
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::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 /// Combiners can sometimes just run C++ code to finish matching a rule &
477 /// mutate instructions instead of relying on MatchActions. Empty if unused.
478 std::string CustomCXXAction
;
480 using DefinedInsnVariablesMap
= std::map
<InstructionMatcher
*, unsigned>;
482 /// A map of instruction matchers to the local variables
483 DefinedInsnVariablesMap InsnVariableIDs
;
485 using MutatableInsnSet
= SmallPtrSet
<InstructionMatcher
*, 4>;
487 // The set of instruction matchers that have not yet been claimed for mutation
489 MutatableInsnSet MutatableInsns
;
491 /// A map of named operands defined by the matchers that may be referenced by
493 StringMap
<OperandMatcher
*> DefinedOperands
;
495 /// A map of anonymous physical register operands defined by the matchers that
496 /// may be referenced by the renderers.
497 DenseMap
<const Record
*, OperandMatcher
*> PhysRegOperands
;
499 /// ID for the next instruction variable defined with
500 /// implicitlyDefineInsnVar()
501 unsigned NextInsnVarID
;
503 /// ID for the next output instruction allocated with allocateOutputInsnID()
504 unsigned NextOutputInsnID
;
506 /// ID for the next temporary register ID allocated with allocateTempRegID()
507 unsigned NextTempRegID
;
509 /// ID for the next recorded type. Starts at -1 and counts down.
510 TempTypeIdx NextTempTypeIdx
= -1;
512 // HwMode predicate index for this rule. -1 if no HwMode.
515 /// Current GISelFlags
516 GISelFlags Flags
= 0;
518 std::vector
<std::string
> RequiredSimplePredicates
;
519 std::vector
<const Record
*> RequiredFeatures
;
520 std::vector
<std::unique_ptr
<PredicateMatcher
>> EpilogueMatchers
;
522 DenseSet
<unsigned> ErasedInsnIDs
;
524 ArrayRef
<SMLoc
> SrcLoc
;
526 typedef std::tuple
<const Record
*, unsigned, unsigned>
527 DefinedComplexPatternSubOperand
;
528 typedef StringMap
<DefinedComplexPatternSubOperand
>
529 DefinedComplexPatternSubOperandMap
;
530 /// A map of Symbolic Names to ComplexPattern sub-operands.
531 DefinedComplexPatternSubOperandMap ComplexSubOperands
;
532 /// A map used to for multiple referenced error check of ComplexSubOperand.
533 /// ComplexSubOperand can't be referenced multiple from different operands,
534 /// however multiple references from same operand are allowed since that is
535 /// how 'same operand checks' are generated.
536 StringMap
<std::string
> ComplexSubOperandsParentName
;
539 static uint64_t NextRuleID
;
541 GISelFlags
updateGISelFlag(GISelFlags CurFlags
, const Record
*R
,
542 StringRef FlagName
, GISelFlags FlagBit
);
545 RuleMatcher(ArrayRef
<SMLoc
> SrcLoc
)
546 : NextInsnVarID(0), NextOutputInsnID(0), NextTempRegID(0), SrcLoc(SrcLoc
),
547 RuleID(NextRuleID
++) {}
548 RuleMatcher(RuleMatcher
&&Other
) = default;
549 RuleMatcher
&operator=(RuleMatcher
&&Other
) = default;
551 TempTypeIdx
getNextTempTypeIdx() { return NextTempTypeIdx
--; }
553 uint64_t getRuleID() const { return RuleID
; }
555 InstructionMatcher
&addInstructionMatcher(StringRef SymbolicName
);
556 void addRequiredFeature(const Record
*Feature
) {
557 RequiredFeatures
.push_back(Feature
);
559 ArrayRef
<const Record
*> getRequiredFeatures() const {
560 return RequiredFeatures
;
563 void addHwModeIdx(unsigned Idx
) { HwModeIdx
= Idx
; }
564 int getHwModeIdx() const { return HwModeIdx
; }
566 void addRequiredSimplePredicate(StringRef PredName
);
567 const std::vector
<std::string
> &getRequiredSimplePredicates();
569 /// Attempts to mark \p ID as erased (GIR_EraseFromParent called on it).
570 /// If \p ID has already been erased, returns false and GIR_EraseFromParent
571 /// should NOT be emitted.
572 bool tryEraseInsnID(unsigned ID
) { return ErasedInsnIDs
.insert(ID
).second
; }
574 void setCustomCXXAction(StringRef FnEnumName
) {
575 CustomCXXAction
= FnEnumName
.str();
578 // Emplaces an action of the specified Kind at the end of the action list.
580 // Returns a reference to the newly created action.
582 // Like std::vector::emplace_back(), may invalidate all iterators if the new
583 // size exceeds the capacity. Otherwise, only invalidates the past-the-end
585 template <class Kind
, class... Args
> Kind
&addAction(Args
&&...args
) {
586 Actions
.emplace_back(std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
587 return *static_cast<Kind
*>(Actions
.back().get());
590 // Emplaces an action of the specified Kind before the given insertion point.
592 // Returns an iterator pointing at the newly created instruction.
594 // Like std::vector::insert(), may invalidate all iterators if the new size
595 // exceeds the capacity. Otherwise, only invalidates the iterators from the
596 // insertion point onwards.
597 template <class Kind
, class... Args
>
598 action_iterator
insertAction(action_iterator InsertPt
, Args
&&...args
) {
599 return Actions
.emplace(InsertPt
,
600 std::make_unique
<Kind
>(std::forward
<Args
>(args
)...));
603 void setPermanentGISelFlags(GISelFlags V
) { Flags
= V
; }
605 // Update the active GISelFlags based on the GISelFlags Record R.
606 // A SaveAndRestore object is returned so the old GISelFlags are restored
607 // at the end of the scope.
608 SaveAndRestore
<GISelFlags
> setGISelFlags(const Record
*R
);
609 GISelFlags
getGISelFlags() const { return Flags
; }
611 /// Define an instruction without emitting any code to do so.
612 unsigned implicitlyDefineInsnVar(InstructionMatcher
&Matcher
);
614 unsigned getInsnVarID(InstructionMatcher
&InsnMatcher
) const;
615 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_begin() const {
616 return InsnVariableIDs
.begin();
618 DefinedInsnVariablesMap::const_iterator
defined_insn_vars_end() const {
619 return InsnVariableIDs
.end();
621 iterator_range
<typename
DefinedInsnVariablesMap::const_iterator
>
622 defined_insn_vars() const {
623 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
626 MutatableInsnSet::const_iterator
mutatable_insns_begin() const {
627 return MutatableInsns
.begin();
629 MutatableInsnSet::const_iterator
mutatable_insns_end() const {
630 return MutatableInsns
.end();
632 iterator_range
<typename
MutatableInsnSet::const_iterator
>
633 mutatable_insns() const {
634 return make_range(mutatable_insns_begin(), mutatable_insns_end());
636 void reserveInsnMatcherForMutation(InstructionMatcher
*InsnMatcher
) {
637 bool R
= MutatableInsns
.erase(InsnMatcher
);
638 assert(R
&& "Reserving a mutatable insn that isn't available");
642 action_iterator
actions_begin() { return Actions
.begin(); }
643 action_iterator
actions_end() { return Actions
.end(); }
644 iterator_range
<action_iterator
> actions() {
645 return make_range(actions_begin(), actions_end());
648 bool hasOperand(StringRef SymbolicName
) const {
649 return DefinedOperands
.contains(SymbolicName
);
652 void defineOperand(StringRef SymbolicName
, OperandMatcher
&OM
);
654 void definePhysRegOperand(const Record
*Reg
, OperandMatcher
&OM
);
656 Error
defineComplexSubOperand(StringRef SymbolicName
,
657 const Record
*ComplexPattern
,
658 unsigned RendererID
, unsigned SubOperandID
,
659 StringRef ParentSymbolicName
);
661 std::optional
<DefinedComplexPatternSubOperand
>
662 getComplexSubOperand(StringRef SymbolicName
) const {
663 const auto &I
= ComplexSubOperands
.find(SymbolicName
);
664 if (I
== ComplexSubOperands
.end())
669 InstructionMatcher
&getInstructionMatcher(StringRef SymbolicName
) const;
670 OperandMatcher
&getOperandMatcher(StringRef Name
);
671 const OperandMatcher
&getOperandMatcher(StringRef Name
) const;
672 const OperandMatcher
&getPhysRegOperandMatcher(const Record
*) const;
674 void optimize() override
;
675 void emit(MatchTable
&Table
) override
;
677 /// Compare the priority of this object and B.
679 /// Returns true if this object is more important than B.
680 bool isHigherPriorityThan(const RuleMatcher
&B
) const;
682 /// Report the maximum number of temporary operands needed by the rule
684 unsigned countRendererFns() const;
686 std::unique_ptr
<PredicateMatcher
> popFirstCondition() override
;
687 const PredicateMatcher
&getFirstCondition() const override
;
688 LLTCodeGen
getFirstConditionAsRootType();
689 bool hasFirstCondition() const override
;
690 StringRef
getOpcode() const;
692 // FIXME: Remove this as soon as possible
693 InstructionMatcher
&insnmatchers_front() const { return *Matchers
.front(); }
695 unsigned allocateOutputInsnID() { return NextOutputInsnID
++; }
696 unsigned allocateTempRegID() { return NextTempRegID
++; }
698 iterator_range
<MatchersTy::iterator
> insnmatchers() {
699 return make_range(Matchers
.begin(), Matchers
.end());
701 bool insnmatchers_empty() const { return Matchers
.empty(); }
702 void insnmatchers_pop_front() { Matchers
.erase(Matchers
.begin()); }
705 template <class PredicateTy
> class PredicateListMatcher
{
707 /// Template instantiations should specialize this to return a string to use
708 /// for the comment emitted when there are no predicates.
709 std::string
getNoPredicateComment() const;
712 using PredicatesTy
= std::deque
<std::unique_ptr
<PredicateTy
>>;
713 PredicatesTy Predicates
;
715 /// Track if the list of predicates was manipulated by one of the optimization
717 bool Optimized
= false;
720 typename
PredicatesTy::iterator
predicates_begin() {
721 return Predicates
.begin();
723 typename
PredicatesTy::iterator
predicates_end() { return Predicates
.end(); }
724 iterator_range
<typename
PredicatesTy::iterator
> predicates() {
725 return make_range(predicates_begin(), predicates_end());
727 typename
PredicatesTy::size_type
predicates_size() const {
728 return Predicates
.size();
730 bool predicates_empty() const { return Predicates
.empty(); }
732 template <typename Ty
> bool contains() const {
733 return any_of(Predicates
, [&](auto &P
) { return isa
<Ty
>(P
.get()); });
736 std::unique_ptr
<PredicateTy
> predicates_pop_front() {
737 std::unique_ptr
<PredicateTy
> Front
= std::move(Predicates
.front());
738 Predicates
.pop_front();
743 void prependPredicate(std::unique_ptr
<PredicateTy
> &&Predicate
) {
744 Predicates
.push_front(std::move(Predicate
));
747 void eraseNullPredicates() {
749 std::stable_partition(Predicates
.begin(), Predicates
.end(),
750 std::logical_not
<std::unique_ptr
<PredicateTy
>>());
751 if (NewEnd
!= Predicates
.begin()) {
752 Predicates
.erase(Predicates
.begin(), NewEnd
);
757 /// Emit MatchTable opcodes that tests whether all the predicates are met.
758 template <class... Args
>
759 void emitPredicateListOpcodes(MatchTable
&Table
, Args
&&...args
) {
760 if (Predicates
.empty() && !Optimized
) {
761 Table
<< MatchTable::Comment(getNoPredicateComment())
762 << MatchTable::LineBreak
;
766 for (const auto &Predicate
: predicates())
767 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
770 /// Provide a function to avoid emitting certain predicates. This is used to
771 /// defer some predicate checks until after others
772 using PredicateFilterFunc
= std::function
<bool(const PredicateTy
&)>;
774 /// Emit MatchTable opcodes for predicates which satisfy \p
775 /// ShouldEmitPredicate. This should be called multiple times to ensure all
776 /// predicates are eventually added to the match table.
777 template <class... Args
>
778 void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate
,
779 MatchTable
&Table
, Args
&&...args
) {
780 if (Predicates
.empty() && !Optimized
) {
781 Table
<< MatchTable::Comment(getNoPredicateComment())
782 << MatchTable::LineBreak
;
786 for (const auto &Predicate
: predicates()) {
787 if (ShouldEmitPredicate(*Predicate
))
788 Predicate
->emitPredicateOpcodes(Table
, std::forward
<Args
>(args
)...);
793 class PredicateMatcher
{
795 /// This enum is used for RTTI and also defines the priority that is given to
796 /// the predicate when generating the matcher code. Kinds with higher priority
797 /// must be tested first.
799 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
800 /// but OPM_Int must have priority over OPM_RegBank since constant integers
801 /// are represented by a virtual register defined by a G_CONSTANT instruction.
803 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
804 /// are currently not compared between each other.
810 IPM_AtomicOrderingMMO
,
813 IPM_MemoryAddressSpace
,
818 IPM_GenericPredicate
,
831 OPM_RecordNamedOperand
,
841 PredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
, unsigned OpIdx
= ~0)
842 : Kind(Kind
), InsnVarID(InsnVarID
), OpIdx(OpIdx
) {}
843 virtual ~PredicateMatcher();
845 unsigned getInsnVarID() const { return InsnVarID
; }
846 unsigned getOpIdx() const { return OpIdx
; }
848 /// Emit MatchTable opcodes that check the predicate for the given operand.
849 virtual void emitPredicateOpcodes(MatchTable
&Table
,
850 RuleMatcher
&Rule
) const = 0;
852 PredicateKind
getKind() const { return Kind
; }
854 bool dependsOnOperands() const {
855 // Custom predicates really depend on the context pattern of the
856 // instruction, not just the individual instruction. This therefore
857 // implicitly depends on all other pattern constraints.
858 return Kind
== IPM_GenericPredicate
;
861 virtual bool isIdentical(const PredicateMatcher
&B
) const {
862 return B
.getKind() == getKind() && InsnVarID
== B
.InsnVarID
&&
866 virtual bool isIdenticalDownToValue(const PredicateMatcher
&B
) const {
867 return hasValue() && PredicateMatcher::isIdentical(B
);
870 virtual MatchTableRecord
getValue() const {
871 assert(hasValue() && "Can not get a value of a value-less predicate!");
872 llvm_unreachable("Not implemented yet");
874 virtual bool hasValue() const { return false; }
876 /// Report the maximum number of temporary operands needed by the predicate
878 virtual unsigned countRendererFns() const { return 0; }
881 /// Generates code to check a predicate of an operand.
883 /// Typical predicates include:
884 /// * Operand is a particular register.
885 /// * Operand is assigned a particular register bank.
886 /// * Operand is an MBB.
887 class OperandPredicateMatcher
: public PredicateMatcher
{
889 OperandPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
,
891 : PredicateMatcher(Kind
, InsnVarID
, OpIdx
) {}
892 virtual ~OperandPredicateMatcher();
894 /// Compare the priority of this object and B.
896 /// Returns true if this object is more important than B.
897 virtual bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const;
902 PredicateListMatcher
<OperandPredicateMatcher
>::getNoPredicateComment() const {
903 return "No operand predicates";
906 /// Generates code to check that a register operand is defined by the same exact
908 class SameOperandMatcher
: public OperandPredicateMatcher
{
909 std::string MatchingName
;
915 SameOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, StringRef MatchingName
,
916 unsigned OrigOpIdx
, GISelFlags Flags
)
917 : OperandPredicateMatcher(OPM_SameOperand
, InsnVarID
, OpIdx
),
918 MatchingName(MatchingName
), OrigOpIdx(OrigOpIdx
), Flags(Flags
) {}
920 static bool classof(const PredicateMatcher
*P
) {
921 return P
->getKind() == OPM_SameOperand
;
924 void emitPredicateOpcodes(MatchTable
&Table
,
925 RuleMatcher
&Rule
) const override
;
927 bool isIdentical(const PredicateMatcher
&B
) const override
{
928 return OperandPredicateMatcher::isIdentical(B
) &&
929 OrigOpIdx
== cast
<SameOperandMatcher
>(&B
)->OrigOpIdx
&&
930 MatchingName
== cast
<SameOperandMatcher
>(&B
)->MatchingName
;
934 /// Generates code to check that an operand is a particular LLT.
935 class LLTOperandMatcher
: public OperandPredicateMatcher
{
940 static std::map
<LLTCodeGen
, unsigned> TypeIDValues
;
942 static void initTypeIDValuesMap() {
943 TypeIDValues
.clear();
946 for (const LLTCodeGen
&LLTy
: KnownTypes
)
947 TypeIDValues
[LLTy
] = ID
++;
950 LLTOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, const LLTCodeGen
&Ty
)
951 : OperandPredicateMatcher(OPM_LLT
, InsnVarID
, OpIdx
), Ty(Ty
) {
952 KnownTypes
.insert(Ty
);
955 static bool classof(const PredicateMatcher
*P
) {
956 return P
->getKind() == OPM_LLT
;
959 bool isIdentical(const PredicateMatcher
&B
) const override
{
960 return OperandPredicateMatcher::isIdentical(B
) &&
961 Ty
== cast
<LLTOperandMatcher
>(&B
)->Ty
;
964 MatchTableRecord
getValue() const override
;
965 bool hasValue() const override
;
967 LLTCodeGen
getTy() const { return Ty
; }
969 void emitPredicateOpcodes(MatchTable
&Table
,
970 RuleMatcher
&Rule
) const override
;
973 /// Generates code to check that an operand is a pointer to any address space.
975 /// In SelectionDAG, the types did not describe pointers or address spaces. As a
976 /// result, iN is used to describe a pointer of N bits to any address space and
977 /// PatFrag predicates are typically used to constrain the address space.
978 /// There's no reliable means to derive the missing type information from the
979 /// pattern so imported rules must test the components of a pointer separately.
981 /// If SizeInBits is zero, then the pointer size will be obtained from the
983 class PointerToAnyOperandMatcher
: public OperandPredicateMatcher
{
988 PointerToAnyOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
990 : OperandPredicateMatcher(OPM_PointerToAny
, InsnVarID
, OpIdx
),
991 SizeInBits(SizeInBits
) {}
993 static bool classof(const PredicateMatcher
*P
) {
994 return P
->getKind() == OPM_PointerToAny
;
997 bool isIdentical(const PredicateMatcher
&B
) const override
{
998 return OperandPredicateMatcher::isIdentical(B
) &&
999 SizeInBits
== cast
<PointerToAnyOperandMatcher
>(&B
)->SizeInBits
;
1002 void emitPredicateOpcodes(MatchTable
&Table
,
1003 RuleMatcher
&Rule
) const override
;
1006 /// Generates code to record named operand in RecordedOperands list at StoreIdx.
1007 /// Predicates with 'let PredicateCodeUsesOperands = 1' get RecordedOperands as
1008 /// an argument to predicate's c++ code once all operands have been matched.
1009 class RecordNamedOperandMatcher
: public OperandPredicateMatcher
{
1015 RecordNamedOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1016 unsigned StoreIdx
, StringRef Name
)
1017 : OperandPredicateMatcher(OPM_RecordNamedOperand
, InsnVarID
, OpIdx
),
1018 StoreIdx(StoreIdx
), Name(Name
) {}
1020 static bool classof(const PredicateMatcher
*P
) {
1021 return P
->getKind() == OPM_RecordNamedOperand
;
1024 bool isIdentical(const PredicateMatcher
&B
) const override
{
1025 return OperandPredicateMatcher::isIdentical(B
) &&
1026 StoreIdx
== cast
<RecordNamedOperandMatcher
>(&B
)->StoreIdx
&&
1027 Name
== cast
<RecordNamedOperandMatcher
>(&B
)->Name
;
1030 void emitPredicateOpcodes(MatchTable
&Table
,
1031 RuleMatcher
&Rule
) const override
;
1034 /// Generates code to store a register operand's type into the set of temporary
1036 class RecordRegisterType
: public OperandPredicateMatcher
{
1041 RecordRegisterType(unsigned InsnVarID
, unsigned OpIdx
, TempTypeIdx Idx
)
1042 : OperandPredicateMatcher(OPM_RecordRegType
, InsnVarID
, OpIdx
), Idx(Idx
) {
1045 static bool classof(const PredicateMatcher
*P
) {
1046 return P
->getKind() == OPM_RecordRegType
;
1049 bool isIdentical(const PredicateMatcher
&B
) const override
{
1050 return OperandPredicateMatcher::isIdentical(B
) &&
1051 Idx
== cast
<RecordRegisterType
>(&B
)->Idx
;
1054 void emitPredicateOpcodes(MatchTable
&Table
,
1055 RuleMatcher
&Rule
) const override
;
1058 /// Generates code to check that an operand is a particular target constant.
1059 class ComplexPatternOperandMatcher
: public OperandPredicateMatcher
{
1061 const OperandMatcher
&Operand
;
1062 const Record
&TheDef
;
1064 unsigned getAllocatedTemporariesBaseID() const;
1067 bool isIdentical(const PredicateMatcher
&B
) const override
{ return false; }
1069 ComplexPatternOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1070 const OperandMatcher
&Operand
,
1071 const Record
&TheDef
)
1072 : OperandPredicateMatcher(OPM_ComplexPattern
, InsnVarID
, OpIdx
),
1073 Operand(Operand
), TheDef(TheDef
) {}
1075 static bool classof(const PredicateMatcher
*P
) {
1076 return P
->getKind() == OPM_ComplexPattern
;
1079 void emitPredicateOpcodes(MatchTable
&Table
,
1080 RuleMatcher
&Rule
) const override
;
1081 unsigned countRendererFns() const override
{ return 1; }
1084 /// Generates code to check that an operand is in a particular register bank.
1085 class RegisterBankOperandMatcher
: public OperandPredicateMatcher
{
1087 const CodeGenRegisterClass
&RC
;
1090 RegisterBankOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1091 const CodeGenRegisterClass
&RC
)
1092 : OperandPredicateMatcher(OPM_RegBank
, InsnVarID
, OpIdx
), RC(RC
) {}
1094 bool isIdentical(const PredicateMatcher
&B
) const override
;
1096 static bool classof(const PredicateMatcher
*P
) {
1097 return P
->getKind() == OPM_RegBank
;
1100 void emitPredicateOpcodes(MatchTable
&Table
,
1101 RuleMatcher
&Rule
) const override
;
1104 /// Generates code to check that an operand is a basic block.
1105 class MBBOperandMatcher
: public OperandPredicateMatcher
{
1107 MBBOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1108 : OperandPredicateMatcher(OPM_MBB
, InsnVarID
, OpIdx
) {}
1110 static bool classof(const PredicateMatcher
*P
) {
1111 return P
->getKind() == OPM_MBB
;
1114 void emitPredicateOpcodes(MatchTable
&Table
,
1115 RuleMatcher
&Rule
) const override
;
1118 class ImmOperandMatcher
: public OperandPredicateMatcher
{
1120 ImmOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
)
1121 : OperandPredicateMatcher(IPM_Imm
, InsnVarID
, OpIdx
) {}
1123 static bool classof(const PredicateMatcher
*P
) {
1124 return P
->getKind() == IPM_Imm
;
1127 void emitPredicateOpcodes(MatchTable
&Table
,
1128 RuleMatcher
&Rule
) const override
;
1131 /// Generates code to check that an operand is a G_CONSTANT with a particular
1133 class ConstantIntOperandMatcher
: public OperandPredicateMatcher
{
1138 ConstantIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1139 : OperandPredicateMatcher(OPM_Int
, InsnVarID
, OpIdx
), Value(Value
) {}
1141 bool isIdentical(const PredicateMatcher
&B
) const override
{
1142 return OperandPredicateMatcher::isIdentical(B
) &&
1143 Value
== cast
<ConstantIntOperandMatcher
>(&B
)->Value
;
1146 static bool classof(const PredicateMatcher
*P
) {
1147 return P
->getKind() == OPM_Int
;
1150 void emitPredicateOpcodes(MatchTable
&Table
,
1151 RuleMatcher
&Rule
) const override
;
1154 /// Generates code to check that an operand is a raw int (where MO.isImm() or
1155 /// MO.isCImm() is true).
1156 class LiteralIntOperandMatcher
: public OperandPredicateMatcher
{
1161 LiteralIntOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, int64_t Value
)
1162 : OperandPredicateMatcher(OPM_LiteralInt
, InsnVarID
, OpIdx
),
1165 bool isIdentical(const PredicateMatcher
&B
) const override
{
1166 return OperandPredicateMatcher::isIdentical(B
) &&
1167 Value
== cast
<LiteralIntOperandMatcher
>(&B
)->Value
;
1170 static bool classof(const PredicateMatcher
*P
) {
1171 return P
->getKind() == OPM_LiteralInt
;
1174 void emitPredicateOpcodes(MatchTable
&Table
,
1175 RuleMatcher
&Rule
) const override
;
1178 /// Generates code to check that an operand is an CmpInst predicate
1179 class CmpPredicateOperandMatcher
: public OperandPredicateMatcher
{
1181 std::string PredName
;
1184 CmpPredicateOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
, std::string P
)
1185 : OperandPredicateMatcher(OPM_CmpPredicate
, InsnVarID
, OpIdx
),
1186 PredName(std::move(P
)) {}
1188 bool isIdentical(const PredicateMatcher
&B
) const override
{
1189 return OperandPredicateMatcher::isIdentical(B
) &&
1190 PredName
== cast
<CmpPredicateOperandMatcher
>(&B
)->PredName
;
1193 static bool classof(const PredicateMatcher
*P
) {
1194 return P
->getKind() == OPM_CmpPredicate
;
1197 void emitPredicateOpcodes(MatchTable
&Table
,
1198 RuleMatcher
&Rule
) const override
;
1201 /// Generates code to check that an operand is an intrinsic ID.
1202 class IntrinsicIDOperandMatcher
: public OperandPredicateMatcher
{
1204 const CodeGenIntrinsic
*II
;
1207 IntrinsicIDOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1208 const CodeGenIntrinsic
*II
)
1209 : OperandPredicateMatcher(OPM_IntrinsicID
, InsnVarID
, OpIdx
), II(II
) {}
1211 bool isIdentical(const PredicateMatcher
&B
) const override
{
1212 return OperandPredicateMatcher::isIdentical(B
) &&
1213 II
== cast
<IntrinsicIDOperandMatcher
>(&B
)->II
;
1216 static bool classof(const PredicateMatcher
*P
) {
1217 return P
->getKind() == OPM_IntrinsicID
;
1220 void emitPredicateOpcodes(MatchTable
&Table
,
1221 RuleMatcher
&Rule
) const override
;
1224 /// Generates code to check that this operand is an immediate whose value meets
1225 /// an immediate predicate.
1226 class OperandImmPredicateMatcher
: public OperandPredicateMatcher
{
1228 TreePredicateFn Predicate
;
1231 OperandImmPredicateMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1232 const TreePredicateFn
&Predicate
)
1233 : OperandPredicateMatcher(IPM_ImmPredicate
, InsnVarID
, OpIdx
),
1234 Predicate(Predicate
) {}
1236 bool isIdentical(const PredicateMatcher
&B
) const override
{
1237 return OperandPredicateMatcher::isIdentical(B
) &&
1238 Predicate
.getOrigPatFragRecord() ==
1239 cast
<OperandImmPredicateMatcher
>(&B
)
1240 ->Predicate
.getOrigPatFragRecord();
1243 static bool classof(const PredicateMatcher
*P
) {
1244 return P
->getKind() == IPM_ImmPredicate
;
1247 void emitPredicateOpcodes(MatchTable
&Table
,
1248 RuleMatcher
&Rule
) const override
;
1251 /// Generates code to check that a set of predicates match for a particular
1253 class OperandMatcher
: public PredicateListMatcher
<OperandPredicateMatcher
> {
1255 InstructionMatcher
&Insn
;
1257 std::string SymbolicName
;
1259 /// The index of the first temporary variable allocated to this operand. The
1260 /// number of allocated temporaries can be found with
1261 /// countRendererFns().
1262 unsigned AllocatedTemporariesBaseID
;
1264 TempTypeIdx TTIdx
= 0;
1266 // TODO: has many implications, figure them all out
1267 bool IsVariadic
= false;
1270 OperandMatcher(InstructionMatcher
&Insn
, unsigned OpIdx
,
1271 const std::string
&SymbolicName
,
1272 unsigned AllocatedTemporariesBaseID
, bool IsVariadic
= false)
1273 : Insn(Insn
), OpIdx(OpIdx
), SymbolicName(SymbolicName
),
1274 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID
),
1275 IsVariadic(IsVariadic
) {}
1277 bool hasSymbolicName() const { return !SymbolicName
.empty(); }
1278 StringRef
getSymbolicName() const { return SymbolicName
; }
1279 void setSymbolicName(StringRef Name
) {
1280 assert(SymbolicName
.empty() && "Operand already has a symbolic name");
1281 SymbolicName
= std::string(Name
);
1284 /// Construct a new operand predicate and add it to the matcher.
1285 template <class Kind
, class... Args
>
1286 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1287 // TODO: Should variadic ops support predicates?
1288 if (isSameAsAnotherOperand() || IsVariadic
)
1289 return std::nullopt
;
1290 Predicates
.emplace_back(std::make_unique
<Kind
>(
1291 getInsnVarID(), getOpIdx(), std::forward
<Args
>(args
)...));
1292 return static_cast<Kind
*>(Predicates
.back().get());
1295 unsigned getOpIdx() const { return OpIdx
; }
1296 unsigned getInsnVarID() const;
1298 bool isVariadic() const { return IsVariadic
; }
1300 /// If this OperandMatcher has not been assigned a TempTypeIdx yet, assigns it
1301 /// one and adds a `RecordRegisterType` predicate to this matcher. If one has
1302 /// already been assigned, simply returns it.
1303 TempTypeIdx
getTempTypeIdx(RuleMatcher
&Rule
);
1305 std::string
getOperandExpr(unsigned InsnVarID
) const;
1307 InstructionMatcher
&getInstructionMatcher() const { return Insn
; }
1309 Error
addTypeCheckPredicate(const TypeSetByHwMode
&VTy
,
1310 bool OperandIsAPointer
);
1312 /// Emit MatchTable opcodes that test whether the instruction named in
1313 /// InsnVarID matches all the predicates and all the operands.
1314 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1316 /// Compare the priority of this object and B.
1318 /// Returns true if this object is more important than B.
1319 bool isHigherPriorityThan(OperandMatcher
&B
);
1321 /// Report the maximum number of temporary operands needed by the operand
1323 unsigned countRendererFns();
1325 unsigned getAllocatedTemporariesBaseID() const {
1326 return AllocatedTemporariesBaseID
;
1329 bool isSameAsAnotherOperand() {
1330 for (const auto &Predicate
: predicates())
1331 if (isa
<SameOperandMatcher
>(Predicate
))
1337 /// Generates code to check a predicate on an instruction.
1339 /// Typical predicates include:
1340 /// * The opcode of the instruction is a particular value.
1341 /// * The nsw/nuw flag is/isn't set.
1342 class InstructionPredicateMatcher
: public PredicateMatcher
{
1344 InstructionPredicateMatcher(PredicateKind Kind
, unsigned InsnVarID
)
1345 : PredicateMatcher(Kind
, InsnVarID
) {}
1346 virtual ~InstructionPredicateMatcher() {}
1348 /// Compare the priority of this object and B.
1350 /// Returns true if this object is more important than B.
1352 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const {
1353 return Kind
< B
.Kind
;
1359 PredicateListMatcher
<PredicateMatcher
>::getNoPredicateComment() const {
1360 return "No instruction predicates";
1363 /// Generates code to check the opcode of an instruction.
1364 class InstructionOpcodeMatcher
: public InstructionPredicateMatcher
{
1366 // Allow matching one to several, similar opcodes that share properties. This
1367 // is to handle patterns where one SelectionDAG operation maps to multiple
1368 // GlobalISel ones (e.g. G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC). The first
1369 // is treated as the canonical opcode.
1370 SmallVector
<const CodeGenInstruction
*, 2> Insts
;
1372 static DenseMap
<const CodeGenInstruction
*, unsigned> OpcodeValues
;
1374 MatchTableRecord
getInstValue(const CodeGenInstruction
*I
) const;
1377 static void initOpcodeValuesMap(const CodeGenTarget
&Target
);
1379 InstructionOpcodeMatcher(unsigned InsnVarID
,
1380 ArrayRef
<const CodeGenInstruction
*> I
)
1381 : InstructionPredicateMatcher(IPM_Opcode
, InsnVarID
), Insts(I
) {
1382 assert((Insts
.size() == 1 || Insts
.size() == 2) &&
1383 "unexpected number of opcode alternatives");
1386 static bool classof(const PredicateMatcher
*P
) {
1387 return P
->getKind() == IPM_Opcode
;
1390 bool isIdentical(const PredicateMatcher
&B
) const override
{
1391 return InstructionPredicateMatcher::isIdentical(B
) &&
1392 Insts
== cast
<InstructionOpcodeMatcher
>(&B
)->Insts
;
1395 bool hasValue() const override
{
1396 return Insts
.size() == 1 && OpcodeValues
.count(Insts
[0]);
1399 // TODO: This is used for the SwitchMatcher optimization. We should be able to
1400 // return a list of the opcodes to match.
1401 MatchTableRecord
getValue() const override
;
1403 void emitPredicateOpcodes(MatchTable
&Table
,
1404 RuleMatcher
&Rule
) const override
;
1406 /// Compare the priority of this object and B.
1408 /// Returns true if this object is more important than B.
1410 isHigherPriorityThan(const InstructionPredicateMatcher
&B
) const override
;
1412 bool isConstantInstruction() const;
1414 // The first opcode is the canonical opcode, and later are alternatives.
1415 StringRef
getOpcode() const;
1416 ArrayRef
<const CodeGenInstruction
*> getAlternativeOpcodes() { return Insts
; }
1417 bool isVariadicNumOperands() const;
1418 StringRef
getOperandType(unsigned OpIdx
) const;
1421 class InstructionNumOperandsMatcher final
: public InstructionPredicateMatcher
{
1423 enum class CheckKind
{ Eq
, LE
, GE
};
1426 unsigned NumOperands
= 0;
1430 InstructionNumOperandsMatcher(unsigned InsnVarID
, unsigned NumOperands
,
1431 CheckKind CK
= CheckKind::Eq
)
1432 : InstructionPredicateMatcher(IPM_NumOperands
, InsnVarID
),
1433 NumOperands(NumOperands
), CK(CK
) {}
1435 static bool classof(const PredicateMatcher
*P
) {
1436 return P
->getKind() == IPM_NumOperands
;
1439 bool isIdentical(const PredicateMatcher
&B
) const override
{
1440 if (!InstructionPredicateMatcher::isIdentical(B
))
1442 const auto &Other
= *cast
<InstructionNumOperandsMatcher
>(&B
);
1443 return NumOperands
== Other
.NumOperands
&& CK
== Other
.CK
;
1446 void emitPredicateOpcodes(MatchTable
&Table
,
1447 RuleMatcher
&Rule
) const override
;
1450 /// Generates code to check that this instruction is a constant whose value
1451 /// meets an immediate predicate.
1453 /// Immediates are slightly odd since they are typically used like an operand
1454 /// but are represented as an operator internally. We typically write simm8:$src
1455 /// in a tablegen pattern, but this is just syntactic sugar for
1456 /// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1457 /// that will be matched and the predicate (which is attached to the imm
1458 /// operator) that will be tested. In SelectionDAG this describes a
1459 /// ConstantSDNode whose internal value will be tested using the simm8
1462 /// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1463 /// this representation, the immediate could be tested with an
1464 /// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1465 /// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1466 /// there are two implementation issues with producing that matcher
1467 /// configuration from the SelectionDAG pattern:
1468 /// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1469 /// were we to sink the immediate predicate to the operand we would have to
1470 /// have two partial implementations of PatFrag support, one for immediates
1471 /// and one for non-immediates.
1472 /// * At the point we handle the predicate, the OperandMatcher hasn't been
1473 /// created yet. If we were to sink the predicate to the OperandMatcher we
1474 /// would also have to complicate (or duplicate) the code that descends and
1475 /// creates matchers for the subtree.
1476 /// Overall, it's simpler to handle it in the place it was found.
1477 class InstructionImmPredicateMatcher
: public InstructionPredicateMatcher
{
1479 TreePredicateFn Predicate
;
1482 InstructionImmPredicateMatcher(unsigned InsnVarID
,
1483 const TreePredicateFn
&Predicate
)
1484 : InstructionPredicateMatcher(IPM_ImmPredicate
, InsnVarID
),
1485 Predicate(Predicate
) {}
1487 bool isIdentical(const PredicateMatcher
&B
) const override
;
1489 static bool classof(const PredicateMatcher
*P
) {
1490 return P
->getKind() == IPM_ImmPredicate
;
1493 void emitPredicateOpcodes(MatchTable
&Table
,
1494 RuleMatcher
&Rule
) const override
;
1497 /// Generates code to check that a memory instruction has a atomic ordering
1498 /// MachineMemoryOperand.
1499 class AtomicOrderingMMOPredicateMatcher
: public InstructionPredicateMatcher
{
1509 AOComparator Comparator
;
1512 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID
, StringRef Order
,
1513 AOComparator Comparator
= AO_Exactly
)
1514 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO
, InsnVarID
),
1515 Order(Order
), Comparator(Comparator
) {}
1517 static bool classof(const PredicateMatcher
*P
) {
1518 return P
->getKind() == IPM_AtomicOrderingMMO
;
1521 bool isIdentical(const PredicateMatcher
&B
) const override
;
1523 void emitPredicateOpcodes(MatchTable
&Table
,
1524 RuleMatcher
&Rule
) const override
;
1527 /// Generates code to check that the size of an MMO is exactly N bytes.
1528 class MemorySizePredicateMatcher
: public InstructionPredicateMatcher
{
1534 MemorySizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
, unsigned Size
)
1535 : InstructionPredicateMatcher(IPM_MemoryLLTSize
, InsnVarID
),
1536 MMOIdx(MMOIdx
), Size(Size
) {}
1538 static bool classof(const PredicateMatcher
*P
) {
1539 return P
->getKind() == IPM_MemoryLLTSize
;
1541 bool isIdentical(const PredicateMatcher
&B
) const override
{
1542 return InstructionPredicateMatcher::isIdentical(B
) &&
1543 MMOIdx
== cast
<MemorySizePredicateMatcher
>(&B
)->MMOIdx
&&
1544 Size
== cast
<MemorySizePredicateMatcher
>(&B
)->Size
;
1547 void emitPredicateOpcodes(MatchTable
&Table
,
1548 RuleMatcher
&Rule
) const override
;
1551 class MemoryAddressSpacePredicateMatcher
: public InstructionPredicateMatcher
{
1554 SmallVector
<unsigned, 4> AddrSpaces
;
1557 MemoryAddressSpacePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1558 ArrayRef
<unsigned> AddrSpaces
)
1559 : InstructionPredicateMatcher(IPM_MemoryAddressSpace
, InsnVarID
),
1560 MMOIdx(MMOIdx
), AddrSpaces(AddrSpaces
) {}
1562 static bool classof(const PredicateMatcher
*P
) {
1563 return P
->getKind() == IPM_MemoryAddressSpace
;
1566 bool isIdentical(const PredicateMatcher
&B
) const override
;
1568 void emitPredicateOpcodes(MatchTable
&Table
,
1569 RuleMatcher
&Rule
) const override
;
1572 class MemoryAlignmentPredicateMatcher
: public InstructionPredicateMatcher
{
1578 MemoryAlignmentPredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1580 : InstructionPredicateMatcher(IPM_MemoryAlignment
, InsnVarID
),
1581 MMOIdx(MMOIdx
), MinAlign(MinAlign
) {
1582 assert(MinAlign
> 0);
1585 static bool classof(const PredicateMatcher
*P
) {
1586 return P
->getKind() == IPM_MemoryAlignment
;
1589 bool isIdentical(const PredicateMatcher
&B
) const override
;
1591 void emitPredicateOpcodes(MatchTable
&Table
,
1592 RuleMatcher
&Rule
) const override
;
1595 /// Generates code to check that the size of an MMO is less-than, equal-to, or
1596 /// greater than a given LLT.
1597 class MemoryVsLLTSizePredicateMatcher
: public InstructionPredicateMatcher
{
1607 RelationKind Relation
;
1611 MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID
, unsigned MMOIdx
,
1612 enum RelationKind Relation
, unsigned OpIdx
)
1613 : InstructionPredicateMatcher(IPM_MemoryVsLLTSize
, InsnVarID
),
1614 MMOIdx(MMOIdx
), Relation(Relation
), OpIdx(OpIdx
) {}
1616 static bool classof(const PredicateMatcher
*P
) {
1617 return P
->getKind() == IPM_MemoryVsLLTSize
;
1619 bool isIdentical(const PredicateMatcher
&B
) const override
;
1621 void emitPredicateOpcodes(MatchTable
&Table
,
1622 RuleMatcher
&Rule
) const override
;
1625 // Matcher for immAllOnesV/immAllZerosV
1626 class VectorSplatImmPredicateMatcher
: public InstructionPredicateMatcher
{
1628 enum SplatKind
{ AllZeros
, AllOnes
};
1634 VectorSplatImmPredicateMatcher(unsigned InsnVarID
, SplatKind K
)
1635 : InstructionPredicateMatcher(IPM_VectorSplatImm
, InsnVarID
), Kind(K
) {}
1637 static bool classof(const PredicateMatcher
*P
) {
1638 return P
->getKind() == IPM_VectorSplatImm
;
1641 bool isIdentical(const PredicateMatcher
&B
) const override
{
1642 return InstructionPredicateMatcher::isIdentical(B
) &&
1643 Kind
== static_cast<const VectorSplatImmPredicateMatcher
&>(B
).Kind
;
1646 void emitPredicateOpcodes(MatchTable
&Table
,
1647 RuleMatcher
&Rule
) const override
;
1650 /// Generates code to check an arbitrary C++ instruction predicate.
1651 class GenericInstructionPredicateMatcher
: public InstructionPredicateMatcher
{
1653 std::string EnumVal
;
1656 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1657 TreePredicateFn Predicate
);
1659 GenericInstructionPredicateMatcher(unsigned InsnVarID
,
1660 const std::string
&EnumVal
)
1661 : InstructionPredicateMatcher(IPM_GenericPredicate
, InsnVarID
),
1664 static bool classof(const InstructionPredicateMatcher
*P
) {
1665 return P
->getKind() == IPM_GenericPredicate
;
1667 bool isIdentical(const PredicateMatcher
&B
) const override
;
1668 void emitPredicateOpcodes(MatchTable
&Table
,
1669 RuleMatcher
&Rule
) const override
;
1672 class MIFlagsInstructionPredicateMatcher
: public InstructionPredicateMatcher
{
1673 SmallVector
<StringRef
, 2> Flags
;
1674 bool CheckNot
; // false = GIM_MIFlags, true = GIM_MIFlagsNot
1677 MIFlagsInstructionPredicateMatcher(unsigned InsnVarID
,
1678 ArrayRef
<StringRef
> FlagsToCheck
,
1679 bool CheckNot
= false)
1680 : InstructionPredicateMatcher(IPM_MIFlags
, InsnVarID
),
1681 Flags(FlagsToCheck
), CheckNot(CheckNot
) {
1685 static bool classof(const InstructionPredicateMatcher
*P
) {
1686 return P
->getKind() == IPM_MIFlags
;
1689 bool isIdentical(const PredicateMatcher
&B
) const override
;
1690 void emitPredicateOpcodes(MatchTable
&Table
,
1691 RuleMatcher
&Rule
) const override
;
1694 /// Generates code to check for the absence of use of the result.
1695 // TODO? Generalize this to support checking for one use.
1696 class NoUsePredicateMatcher
: public InstructionPredicateMatcher
{
1698 NoUsePredicateMatcher(unsigned InsnVarID
)
1699 : InstructionPredicateMatcher(IPM_NoUse
, InsnVarID
) {}
1701 static bool classof(const PredicateMatcher
*P
) {
1702 return P
->getKind() == IPM_NoUse
;
1705 bool isIdentical(const PredicateMatcher
&B
) const override
{
1706 return InstructionPredicateMatcher::isIdentical(B
);
1709 void emitPredicateOpcodes(MatchTable
&Table
,
1710 RuleMatcher
&Rule
) const override
{
1711 Table
<< MatchTable::Opcode("GIM_CheckHasNoUse")
1712 << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID
)
1713 << MatchTable::LineBreak
;
1717 /// Generates code to check that the first result has only one use.
1718 class OneUsePredicateMatcher
: public InstructionPredicateMatcher
{
1720 OneUsePredicateMatcher(unsigned InsnVarID
)
1721 : InstructionPredicateMatcher(IPM_OneUse
, InsnVarID
) {}
1723 static bool classof(const PredicateMatcher
*P
) {
1724 return P
->getKind() == IPM_OneUse
;
1727 bool isIdentical(const PredicateMatcher
&B
) const override
{
1728 return InstructionPredicateMatcher::isIdentical(B
);
1731 void emitPredicateOpcodes(MatchTable
&Table
,
1732 RuleMatcher
&Rule
) const override
{
1733 Table
<< MatchTable::Opcode("GIM_CheckHasOneUse")
1734 << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID
)
1735 << MatchTable::LineBreak
;
1739 /// Generates code to check that a set of predicates and operands match for a
1740 /// particular instruction.
1742 /// Typical predicates include:
1743 /// * Has a specific opcode.
1744 /// * Has an nsw/nuw flag or doesn't.
1745 class InstructionMatcher final
: public PredicateListMatcher
<PredicateMatcher
> {
1747 typedef std::vector
<std::unique_ptr
<OperandMatcher
>> OperandVec
;
1751 /// The operands to match. All rendered operands must be present even if the
1752 /// condition is always true.
1753 OperandVec Operands
;
1755 std::string SymbolicName
;
1757 bool AllowNumOpsCheck
;
1759 /// PhysRegInputs - List list has an entry for each explicitly specified
1760 /// physreg input to the pattern. The first elt is the Register node, the
1761 /// second is the recorded slot number the input pattern match saved it in.
1762 SmallVector
<std::pair
<const Record
*, unsigned>, 2> PhysRegInputs
;
1764 bool canAddNumOperandsCheck() const {
1765 // Add if it's allowed, and:
1766 // - We don't have a variadic operand
1767 // - We don't already have such a check.
1768 return AllowNumOpsCheck
&& !hasVariadicMatcher() &&
1769 none_of(Predicates
, [&](const auto &P
) {
1770 return P
->getKind() ==
1771 InstructionPredicateMatcher::IPM_NumOperands
;
1776 InstructionMatcher(RuleMatcher
&Rule
, StringRef SymbolicName
,
1777 bool AllowNumOpsCheck
= true)
1778 : Rule(Rule
), SymbolicName(SymbolicName
),
1779 AllowNumOpsCheck(AllowNumOpsCheck
) {
1780 // We create a new instruction matcher.
1781 // Get a new ID for that instruction.
1782 InsnVarID
= Rule
.implicitlyDefineInsnVar(*this);
1785 /// Construct a new instruction predicate and add it to the matcher.
1786 template <class Kind
, class... Args
>
1787 std::optional
<Kind
*> addPredicate(Args
&&...args
) {
1788 Predicates
.emplace_back(
1789 std::make_unique
<Kind
>(getInsnVarID(), std::forward
<Args
>(args
)...));
1790 return static_cast<Kind
*>(Predicates
.back().get());
1793 RuleMatcher
&getRuleMatcher() const { return Rule
; }
1795 unsigned getInsnVarID() const { return InsnVarID
; }
1797 /// Add an operand to the matcher.
1798 OperandMatcher
&addOperand(unsigned OpIdx
, const std::string
&SymbolicName
,
1799 unsigned AllocatedTemporariesBaseID
,
1800 bool IsVariadic
= false);
1801 OperandMatcher
&getOperand(unsigned OpIdx
);
1802 OperandMatcher
&addPhysRegInput(const Record
*Reg
, unsigned OpIdx
,
1803 unsigned TempOpIdx
);
1805 ArrayRef
<std::pair
<const Record
*, unsigned>> getPhysRegInputs() const {
1806 return PhysRegInputs
;
1809 StringRef
getSymbolicName() const { return SymbolicName
; }
1811 unsigned getNumOperandMatchers() const { return Operands
.size(); }
1812 bool hasVariadicMatcher() const {
1813 return !Operands
.empty() && Operands
.back()->isVariadic();
1816 OperandVec::iterator
operands_begin() { return Operands
.begin(); }
1817 OperandVec::iterator
operands_end() { return Operands
.end(); }
1818 iterator_range
<OperandVec::iterator
> operands() {
1819 return make_range(operands_begin(), operands_end());
1821 OperandVec::const_iterator
operands_begin() const { return Operands
.begin(); }
1822 OperandVec::const_iterator
operands_end() const { return Operands
.end(); }
1823 iterator_range
<OperandVec::const_iterator
> operands() const {
1824 return make_range(operands_begin(), operands_end());
1826 bool operands_empty() const { return Operands
.empty(); }
1828 void pop_front() { Operands
.erase(Operands
.begin()); }
1832 /// Emit MatchTable opcodes that test whether the instruction named in
1833 /// InsnVarName matches all the predicates and all the operands.
1834 void emitPredicateOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
);
1836 /// Compare the priority of this object and B.
1838 /// Returns true if this object is more important than B.
1839 bool isHigherPriorityThan(InstructionMatcher
&B
);
1841 /// Report the maximum number of temporary operands needed by the instruction
1843 unsigned countRendererFns();
1845 InstructionOpcodeMatcher
&getOpcodeMatcher() {
1846 for (auto &P
: predicates())
1847 if (auto *OpMatcher
= dyn_cast
<InstructionOpcodeMatcher
>(P
.get()))
1849 llvm_unreachable("Didn't find an opcode matcher");
1852 bool isConstantInstruction() {
1853 return getOpcodeMatcher().isConstantInstruction();
1856 StringRef
getOpcode() { return getOpcodeMatcher().getOpcode(); }
1859 /// Generates code to check that the operand is a register defined by an
1860 /// instruction that matches the given instruction matcher.
1862 /// For example, the pattern:
1863 /// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1864 /// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1866 /// (G_ADD $src1, $src2)
1868 class InstructionOperandMatcher
: public OperandPredicateMatcher
{
1870 std::unique_ptr
<InstructionMatcher
> InsnMatcher
;
1875 InstructionOperandMatcher(unsigned InsnVarID
, unsigned OpIdx
,
1876 RuleMatcher
&Rule
, StringRef SymbolicName
,
1877 bool AllowNumOpsCheck
= true)
1878 : OperandPredicateMatcher(OPM_Instruction
, InsnVarID
, OpIdx
),
1880 new InstructionMatcher(Rule
, SymbolicName
, AllowNumOpsCheck
)),
1881 Flags(Rule
.getGISelFlags()) {}
1883 static bool classof(const PredicateMatcher
*P
) {
1884 return P
->getKind() == OPM_Instruction
;
1887 InstructionMatcher
&getInsnMatcher() const { return *InsnMatcher
; }
1889 void emitCaptureOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const;
1890 void emitPredicateOpcodes(MatchTable
&Table
,
1891 RuleMatcher
&Rule
) const override
{
1892 emitCaptureOpcodes(Table
, Rule
);
1893 InsnMatcher
->emitPredicateOpcodes(Table
, Rule
);
1896 bool isHigherPriorityThan(const OperandPredicateMatcher
&B
) const override
;
1898 /// Report the maximum number of temporary operands needed by the predicate
1900 unsigned countRendererFns() const override
{
1901 return InsnMatcher
->countRendererFns();
1905 //===- Actions ------------------------------------------------------------===//
1906 class OperandRenderer
{
1910 OR_CopyOrAddZeroReg
,
1913 OR_CopyConstantAsImm
,
1914 OR_CopyFConstantAsFPImm
,
1929 OperandRenderer(RendererKind Kind
) : Kind(Kind
) {}
1930 virtual ~OperandRenderer();
1932 RendererKind
getKind() const { return Kind
; }
1934 virtual void emitRenderOpcodes(MatchTable
&Table
,
1935 RuleMatcher
&Rule
) const = 0;
1938 /// A CopyRenderer emits code to copy a single operand from an existing
1939 /// instruction to the one being built.
1940 class CopyRenderer
: public OperandRenderer
{
1943 /// The name of the operand.
1944 const StringRef SymbolicName
;
1947 CopyRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
1948 : OperandRenderer(OR_Copy
), NewInsnID(NewInsnID
),
1949 SymbolicName(SymbolicName
) {
1950 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
1953 static bool classof(const OperandRenderer
*R
) {
1954 return R
->getKind() == OR_Copy
;
1957 StringRef
getSymbolicName() const { return SymbolicName
; }
1959 static void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
,
1960 unsigned NewInsnID
, unsigned OldInsnID
,
1961 unsigned OpIdx
, StringRef Name
,
1962 bool ForVariadic
= false);
1964 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1967 /// A CopyRenderer emits code to copy a virtual register to a specific physical
1969 class CopyPhysRegRenderer
: public OperandRenderer
{
1972 const Record
*PhysReg
;
1975 CopyPhysRegRenderer(unsigned NewInsnID
, const Record
*Reg
)
1976 : OperandRenderer(OR_CopyPhysReg
), NewInsnID(NewInsnID
), PhysReg(Reg
) {
1980 static bool classof(const OperandRenderer
*R
) {
1981 return R
->getKind() == OR_CopyPhysReg
;
1984 const Record
*getPhysReg() const { return PhysReg
; }
1986 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
1989 /// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1990 /// existing instruction to the one being built. If the operand turns out to be
1991 /// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1992 class CopyOrAddZeroRegRenderer
: public OperandRenderer
{
1995 /// The name of the operand.
1996 const StringRef SymbolicName
;
1997 const Record
*ZeroRegisterDef
;
2000 CopyOrAddZeroRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
2001 const Record
*ZeroRegisterDef
)
2002 : OperandRenderer(OR_CopyOrAddZeroReg
), NewInsnID(NewInsnID
),
2003 SymbolicName(SymbolicName
), ZeroRegisterDef(ZeroRegisterDef
) {
2004 assert(!SymbolicName
.empty() && "Cannot copy from an unspecified source");
2007 static bool classof(const OperandRenderer
*R
) {
2008 return R
->getKind() == OR_CopyOrAddZeroReg
;
2011 StringRef
getSymbolicName() const { return SymbolicName
; }
2013 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2016 /// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
2017 /// an extended immediate operand.
2018 class CopyConstantAsImmRenderer
: public OperandRenderer
{
2021 /// The name of the operand.
2022 const std::string SymbolicName
;
2026 CopyConstantAsImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
2027 : OperandRenderer(OR_CopyConstantAsImm
), NewInsnID(NewInsnID
),
2028 SymbolicName(SymbolicName
), Signed(true) {}
2030 static bool classof(const OperandRenderer
*R
) {
2031 return R
->getKind() == OR_CopyConstantAsImm
;
2034 StringRef
getSymbolicName() const { return SymbolicName
; }
2036 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2039 /// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
2040 /// instruction to an extended immediate operand.
2041 class CopyFConstantAsFPImmRenderer
: public OperandRenderer
{
2044 /// The name of the operand.
2045 const std::string SymbolicName
;
2048 CopyFConstantAsFPImmRenderer(unsigned NewInsnID
, StringRef SymbolicName
)
2049 : OperandRenderer(OR_CopyFConstantAsFPImm
), NewInsnID(NewInsnID
),
2050 SymbolicName(SymbolicName
) {}
2052 static bool classof(const OperandRenderer
*R
) {
2053 return R
->getKind() == OR_CopyFConstantAsFPImm
;
2056 StringRef
getSymbolicName() const { return SymbolicName
; }
2058 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2061 /// A CopySubRegRenderer emits code to copy a single register operand from an
2062 /// existing instruction to the one being built and indicate that only a
2063 /// subregister should be copied.
2064 class CopySubRegRenderer
: public OperandRenderer
{
2067 /// The name of the operand.
2068 const StringRef SymbolicName
;
2069 /// The subregister to extract.
2070 const CodeGenSubRegIndex
*SubReg
;
2073 CopySubRegRenderer(unsigned NewInsnID
, StringRef SymbolicName
,
2074 const CodeGenSubRegIndex
*SubReg
)
2075 : OperandRenderer(OR_CopySubReg
), NewInsnID(NewInsnID
),
2076 SymbolicName(SymbolicName
), SubReg(SubReg
) {}
2078 static bool classof(const OperandRenderer
*R
) {
2079 return R
->getKind() == OR_CopySubReg
;
2082 StringRef
getSymbolicName() const { return SymbolicName
; }
2084 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2087 /// Adds a specific physical register to the instruction being built.
2088 /// This is typically useful for WZR/XZR on AArch64.
2089 class AddRegisterRenderer
: public OperandRenderer
{
2092 const Record
*RegisterDef
;
2094 const CodeGenTarget
&Target
;
2097 AddRegisterRenderer(unsigned InsnID
, const CodeGenTarget
&Target
,
2098 const Record
*RegisterDef
, bool IsDef
= false)
2099 : OperandRenderer(OR_Register
), InsnID(InsnID
), RegisterDef(RegisterDef
),
2100 IsDef(IsDef
), Target(Target
) {}
2102 static bool classof(const OperandRenderer
*R
) {
2103 return R
->getKind() == OR_Register
;
2106 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2109 /// Adds a specific temporary virtual register to the instruction being built.
2110 /// This is used to chain instructions together when emitting multiple
2112 class TempRegRenderer
: public OperandRenderer
{
2116 const CodeGenSubRegIndex
*SubRegIdx
;
2121 TempRegRenderer(unsigned InsnID
, unsigned TempRegID
, bool IsDef
= false,
2122 const CodeGenSubRegIndex
*SubReg
= nullptr,
2123 bool IsDead
= false)
2124 : OperandRenderer(OR_Register
), InsnID(InsnID
), TempRegID(TempRegID
),
2125 SubRegIdx(SubReg
), IsDef(IsDef
), IsDead(IsDead
) {}
2127 static bool classof(const OperandRenderer
*R
) {
2128 return R
->getKind() == OR_TempRegister
;
2131 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2134 /// Adds a specific immediate to the instruction being built.
2135 /// If a LLT is passed, a ConstantInt immediate is created instead.
2136 class ImmRenderer
: public OperandRenderer
{
2140 std::optional
<LLTCodeGenOrTempType
> CImmLLT
;
2143 ImmRenderer(unsigned InsnID
, int64_t Imm
)
2144 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
) {}
2146 ImmRenderer(unsigned InsnID
, int64_t Imm
, const LLTCodeGenOrTempType
&CImmLLT
)
2147 : OperandRenderer(OR_Imm
), InsnID(InsnID
), Imm(Imm
), CImmLLT(CImmLLT
) {
2148 if (CImmLLT
.isLLTCodeGen())
2149 KnownTypes
.insert(CImmLLT
.getLLTCodeGen());
2152 static bool classof(const OperandRenderer
*R
) {
2153 return R
->getKind() == OR_Imm
;
2156 static void emitAddImm(MatchTable
&Table
, RuleMatcher
&RM
, unsigned InsnID
,
2157 int64_t Imm
, StringRef ImmName
= "Imm");
2159 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2162 /// Adds an enum value for a subreg index to the instruction being built.
2163 class SubRegIndexRenderer
: public OperandRenderer
{
2166 const CodeGenSubRegIndex
*SubRegIdx
;
2169 SubRegIndexRenderer(unsigned InsnID
, const CodeGenSubRegIndex
*SRI
)
2170 : OperandRenderer(OR_SubRegIndex
), InsnID(InsnID
), SubRegIdx(SRI
) {}
2172 static bool classof(const OperandRenderer
*R
) {
2173 return R
->getKind() == OR_SubRegIndex
;
2176 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2179 /// Adds operands by calling a renderer function supplied by the ComplexPattern
2180 /// matcher function.
2181 class RenderComplexPatternOperand
: public OperandRenderer
{
2184 const Record
&TheDef
;
2185 /// The name of the operand.
2186 const StringRef SymbolicName
;
2187 /// The renderer number. This must be unique within a rule since it's used to
2188 /// identify a temporary variable to hold the renderer function.
2189 unsigned RendererID
;
2190 /// When provided, this is the suboperand of the ComplexPattern operand to
2191 /// render. Otherwise all the suboperands will be rendered.
2192 std::optional
<unsigned> SubOperand
;
2193 /// The subregister to extract. Render the whole register if not specified.
2194 const CodeGenSubRegIndex
*SubReg
;
2196 unsigned getNumOperands() const {
2197 return TheDef
.getValueAsDag("Operands")->getNumArgs();
2201 RenderComplexPatternOperand(unsigned InsnID
, const Record
&TheDef
,
2202 StringRef SymbolicName
, unsigned RendererID
,
2203 std::optional
<unsigned> SubOperand
= std::nullopt
,
2204 const CodeGenSubRegIndex
*SubReg
= nullptr)
2205 : OperandRenderer(OR_ComplexPattern
), InsnID(InsnID
), TheDef(TheDef
),
2206 SymbolicName(SymbolicName
), RendererID(RendererID
),
2207 SubOperand(SubOperand
), SubReg(SubReg
) {}
2209 static bool classof(const OperandRenderer
*R
) {
2210 return R
->getKind() == OR_ComplexPattern
;
2213 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2216 /// Adds an intrinsic ID operand to the instruction being built.
2217 class IntrinsicIDRenderer
: public OperandRenderer
{
2220 const CodeGenIntrinsic
*II
;
2223 IntrinsicIDRenderer(unsigned InsnID
, const CodeGenIntrinsic
*II
)
2224 : OperandRenderer(OR_Intrinsic
), InsnID(InsnID
), II(II
) {}
2226 static bool classof(const OperandRenderer
*R
) {
2227 return R
->getKind() == OR_Intrinsic
;
2230 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2233 class CustomRenderer
: public OperandRenderer
{
2236 const Record
&Renderer
;
2237 /// The name of the operand.
2238 const std::string SymbolicName
;
2241 CustomRenderer(unsigned InsnID
, const Record
&Renderer
,
2242 StringRef SymbolicName
)
2243 : OperandRenderer(OR_Custom
), InsnID(InsnID
), Renderer(Renderer
),
2244 SymbolicName(SymbolicName
) {}
2246 static bool classof(const OperandRenderer
*R
) {
2247 return R
->getKind() == OR_Custom
;
2250 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2253 class CustomOperandRenderer
: public OperandRenderer
{
2256 const Record
&Renderer
;
2257 /// The name of the operand.
2258 const std::string SymbolicName
;
2261 CustomOperandRenderer(unsigned InsnID
, const Record
&Renderer
,
2262 StringRef SymbolicName
)
2263 : OperandRenderer(OR_CustomOperand
), InsnID(InsnID
), Renderer(Renderer
),
2264 SymbolicName(SymbolicName
) {}
2266 static bool classof(const OperandRenderer
*R
) {
2267 return R
->getKind() == OR_CustomOperand
;
2270 void emitRenderOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2273 /// An action taken when all Matcher predicates succeeded for a parent rule.
2275 /// Typical actions include:
2276 /// * Changing the opcode of an instruction.
2277 /// * Adding an operand to an instruction.
2286 AK_ConstraintOpsToDef
,
2287 AK_ConstraintOpsToRC
,
2291 MatchAction(ActionKind K
) : Kind(K
) {}
2293 ActionKind
getKind() const { return Kind
; }
2295 virtual ~MatchAction() {}
2297 // Some actions may need to add extra predicates to ensure they can run.
2298 virtual void emitAdditionalPredicates(MatchTable
&Table
,
2299 RuleMatcher
&Rule
) const {}
2301 /// Emit the MatchTable opcodes to implement the action.
2302 virtual void emitActionOpcodes(MatchTable
&Table
,
2303 RuleMatcher
&Rule
) const = 0;
2305 /// If this opcode has an overload that can call GIR_Done directly, emit that
2306 /// instead of the usual opcode and return "true". Return "false" if GIR_Done
2307 /// still needs to be emitted.
2308 virtual bool emitActionOpcodesAndDone(MatchTable
&Table
,
2309 RuleMatcher
&Rule
) const {
2310 emitActionOpcodes(Table
, Rule
);
2318 /// Generates a comment describing the matched rule being acted upon.
2319 class DebugCommentAction
: public MatchAction
{
2324 DebugCommentAction(StringRef S
)
2325 : MatchAction(AK_DebugComment
), S(std::string(S
)) {}
2327 static bool classof(const MatchAction
*A
) {
2328 return A
->getKind() == AK_DebugComment
;
2331 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2332 Table
<< MatchTable::Comment(S
) << MatchTable::LineBreak
;
2336 /// Generates code to build an instruction or mutate an existing instruction
2337 /// into the desired instruction when this is possible.
2338 class BuildMIAction
: public MatchAction
{
2341 const CodeGenInstruction
*I
;
2342 InstructionMatcher
*Matched
;
2343 std::vector
<std::unique_ptr
<OperandRenderer
>> OperandRenderers
;
2344 SmallPtrSet
<const Record
*, 4> DeadImplicitDefs
;
2346 std::vector
<const InstructionMatcher
*> CopiedFlags
;
2347 std::vector
<StringRef
> SetFlags
;
2348 std::vector
<StringRef
> UnsetFlags
;
2350 /// True if the instruction can be built solely by mutating the opcode.
2351 bool canMutate(RuleMatcher
&Rule
, const InstructionMatcher
*Insn
) const;
2354 BuildMIAction(unsigned InsnID
, const CodeGenInstruction
*I
)
2355 : MatchAction(AK_BuildMI
), InsnID(InsnID
), I(I
), Matched(nullptr) {}
2357 static bool classof(const MatchAction
*A
) {
2358 return A
->getKind() == AK_BuildMI
;
2361 unsigned getInsnID() const { return InsnID
; }
2362 const CodeGenInstruction
*getCGI() const { return I
; }
2364 void addSetMIFlags(StringRef Flag
) { SetFlags
.push_back(Flag
); }
2365 void addUnsetMIFlags(StringRef Flag
) { UnsetFlags
.push_back(Flag
); }
2366 void addCopiedMIFlags(const InstructionMatcher
&IM
) {
2367 CopiedFlags
.push_back(&IM
);
2370 void chooseInsnToMutate(RuleMatcher
&Rule
);
2372 void setDeadImplicitDef(const Record
*R
) { DeadImplicitDefs
.insert(R
); }
2374 template <class Kind
, class... Args
> Kind
&addRenderer(Args
&&...args
) {
2375 OperandRenderers
.emplace_back(
2376 std::make_unique
<Kind
>(InsnID
, std::forward
<Args
>(args
)...));
2377 return *static_cast<Kind
*>(OperandRenderers
.back().get());
2380 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2383 /// Generates code to create a constant that defines a TempReg.
2384 /// The instruction created is usually a G_CONSTANT but it could also be a
2385 /// G_BUILD_VECTOR for vector types.
2386 class BuildConstantAction
: public MatchAction
{
2391 BuildConstantAction(unsigned TempRegID
, int64_t Val
)
2392 : MatchAction(AK_BuildConstantMI
), TempRegID(TempRegID
), Val(Val
) {}
2394 static bool classof(const MatchAction
*A
) {
2395 return A
->getKind() == AK_BuildConstantMI
;
2398 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2401 class EraseInstAction
: public MatchAction
{
2405 EraseInstAction(unsigned InsnID
)
2406 : MatchAction(AK_EraseInst
), InsnID(InsnID
) {}
2408 unsigned getInsnID() const { return InsnID
; }
2410 static bool classof(const MatchAction
*A
) {
2411 return A
->getKind() == AK_EraseInst
;
2414 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2415 bool emitActionOpcodesAndDone(MatchTable
&Table
,
2416 RuleMatcher
&Rule
) const override
;
2419 class ReplaceRegAction
: public MatchAction
{
2420 unsigned OldInsnID
, OldOpIdx
;
2421 unsigned NewInsnId
= -1, NewOpIdx
;
2422 unsigned TempRegID
= -1;
2425 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned NewInsnId
,
2427 : MatchAction(AK_ReplaceReg
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2428 NewInsnId(NewInsnId
), NewOpIdx(NewOpIdx
) {}
2430 ReplaceRegAction(unsigned OldInsnID
, unsigned OldOpIdx
, unsigned TempRegID
)
2431 : MatchAction(AK_ReplaceReg
), OldInsnID(OldInsnID
), OldOpIdx(OldOpIdx
),
2432 TempRegID(TempRegID
) {}
2434 static bool classof(const MatchAction
*A
) {
2435 return A
->getKind() == AK_ReplaceReg
;
2438 void emitAdditionalPredicates(MatchTable
&Table
,
2439 RuleMatcher
&Rule
) const override
;
2440 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2443 /// Generates code to constrain the operands of an output instruction to the
2444 /// register classes specified by the definition of that instruction.
2445 class ConstrainOperandsToDefinitionAction
: public MatchAction
{
2449 ConstrainOperandsToDefinitionAction(unsigned InsnID
)
2450 : MatchAction(AK_ConstraintOpsToDef
), InsnID(InsnID
) {}
2452 static bool classof(const MatchAction
*A
) {
2453 return A
->getKind() == AK_ConstraintOpsToDef
;
2456 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
{
2458 Table
<< MatchTable::Opcode("GIR_RootConstrainSelectedInstOperands")
2459 << MatchTable::LineBreak
;
2461 Table
<< MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2462 << MatchTable::Comment("InsnID") << MatchTable::ULEB128Value(InsnID
)
2463 << MatchTable::LineBreak
;
2468 /// Generates code to constrain the specified operand of an output instruction
2469 /// to the specified register class.
2470 class ConstrainOperandToRegClassAction
: public MatchAction
{
2473 const CodeGenRegisterClass
&RC
;
2476 ConstrainOperandToRegClassAction(unsigned InsnID
, unsigned OpIdx
,
2477 const CodeGenRegisterClass
&RC
)
2478 : MatchAction(AK_ConstraintOpsToRC
), InsnID(InsnID
), OpIdx(OpIdx
),
2481 static bool classof(const MatchAction
*A
) {
2482 return A
->getKind() == AK_ConstraintOpsToRC
;
2485 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2488 /// Generates code to create a temporary register which can be used to chain
2489 /// instructions together.
2490 class MakeTempRegisterAction
: public MatchAction
{
2492 LLTCodeGenOrTempType Ty
;
2496 MakeTempRegisterAction(const LLTCodeGenOrTempType
&Ty
, unsigned TempRegID
)
2497 : MatchAction(AK_MakeTempReg
), Ty(Ty
), TempRegID(TempRegID
) {
2498 if (Ty
.isLLTCodeGen())
2499 KnownTypes
.insert(Ty
.getLLTCodeGen());
2502 static bool classof(const MatchAction
*A
) {
2503 return A
->getKind() == AK_MakeTempReg
;
2506 void emitActionOpcodes(MatchTable
&Table
, RuleMatcher
&Rule
) const override
;
2512 #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLE_H