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