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