1 //===- Patterns.h ----------------------------------------------*- C++ -*-===// 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 Contains the Pattern hierarchy alongside helper classes such as 10 /// PatFrag, MIFlagsInfo, PatternType, etc. 11 /// 12 /// These classes are used by the GlobalISel Combiner backend to help parse, 13 /// process and emit MIR patterns. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H 18 #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H 19 20 #include "llvm/ADT/ArrayRef.h" 21 #include "llvm/ADT/SetVector.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/ADT/Twine.h" 26 #include <memory> 27 #include <optional> 28 #include <string> 29 30 namespace llvm { 31 32 class Record; 33 class SMLoc; 34 class StringInit; 35 class CodeExpansions; 36 class CodeGenInstruction; 37 struct CodeGenIntrinsic; 38 39 namespace gi { 40 41 class CXXPredicateCode; 42 class LLTCodeGen; 43 class LLTCodeGenOrTempType; 44 class RuleMatcher; 45 46 //===- PatternType --------------------------------------------------------===// 47 48 struct VariadicPackTypeInfo { 49 VariadicPackTypeInfo(unsigned Min, unsigned Max) : Min(Min), Max(Max) { 50 assert(Min >= 1 && (Max >= Min || Max == 0)); 51 } 52 53 bool operator==(const VariadicPackTypeInfo &Other) const { 54 return Min == Other.Min && Max == Other.Max; 55 } 56 57 unsigned Min; 58 unsigned Max; 59 }; 60 61 /// Represent the type of a Pattern Operand. 62 /// 63 /// Types have two form: 64 /// - LLTs, which are straightforward. 65 /// - Special types, e.g. GITypeOf, Variadic arguments list. 66 class PatternType { 67 public: 68 static constexpr StringLiteral SpecialTyClassName = "GISpecialType"; 69 static constexpr StringLiteral TypeOfClassName = "GITypeOf"; 70 static constexpr StringLiteral VariadicClassName = "GIVariadic"; 71 72 enum PTKind : uint8_t { 73 PT_None, 74 75 PT_ValueType, 76 PT_TypeOf, 77 PT_VariadicPack, 78 }; 79 80 PatternType() : Kind(PT_None), Data() {} 81 82 static std::optional<PatternType> get(ArrayRef<SMLoc> DiagLoc, 83 const Record *R, Twine DiagCtx); 84 static PatternType getTypeOf(StringRef OpName); 85 86 bool isNone() const { return Kind == PT_None; } 87 bool isLLT() const { return Kind == PT_ValueType; } 88 bool isSpecial() const { return isTypeOf() || isVariadicPack(); } 89 bool isTypeOf() const { return Kind == PT_TypeOf; } 90 bool isVariadicPack() const { return Kind == PT_VariadicPack; } 91 92 PTKind getKind() const { return Kind; } 93 94 StringRef getTypeOfOpName() const; 95 const Record *getLLTRecord() const; 96 VariadicPackTypeInfo getVariadicPackTypeInfo() const; 97 98 explicit operator bool() const { return !isNone(); } 99 100 bool operator==(const PatternType &Other) const; 101 bool operator!=(const PatternType &Other) const { return !operator==(Other); } 102 103 std::string str() const; 104 105 private: 106 PatternType(PTKind Kind) : Kind(Kind), Data() {} 107 108 PTKind Kind; 109 union DataT { 110 DataT() : Str() {} 111 112 /// PT_ValueType -> ValueType Def. 113 const Record *Def; 114 115 /// PT_TypeOf -> Operand name (without the '$') 116 StringRef Str; 117 118 /// PT_VariadicPack -> min-max number of operands allowed. 119 VariadicPackTypeInfo VPTI; 120 } Data; 121 }; 122 123 //===- Pattern Base Class -------------------------------------------------===// 124 125 /// Base class for all patterns that can be written in an `apply`, `match` or 126 /// `pattern` DAG operator. 127 /// 128 /// For example: 129 /// 130 /// (apply (G_ZEXT $x, $y), (G_ZEXT $y, $z), "return isFoo(${z})") 131 /// 132 /// Creates 3 Pattern objects: 133 /// - Two CodeGenInstruction Patterns 134 /// - A CXXPattern 135 class Pattern { 136 public: 137 enum { 138 K_AnyOpcode, 139 K_CXX, 140 141 K_CodeGenInstruction, 142 K_PatFrag, 143 K_Builtin, 144 }; 145 146 virtual ~Pattern() = default; 147 148 unsigned getKind() const { return Kind; } 149 const char *getKindName() const; 150 151 bool hasName() const { return !Name.empty(); } 152 StringRef getName() const { return Name; } 153 154 virtual void print(raw_ostream &OS, bool PrintName = true) const = 0; 155 void dump() const; 156 157 protected: 158 Pattern(unsigned Kind, StringRef Name) : Kind(Kind), Name(Name) { 159 assert(!Name.empty() && "unnamed pattern!"); 160 } 161 162 void printImpl(raw_ostream &OS, bool PrintName, 163 function_ref<void()> ContentPrinter) const; 164 165 private: 166 unsigned Kind; 167 StringRef Name; 168 }; 169 170 //===- AnyOpcodePattern ---------------------------------------------------===// 171 172 /// `wip_match_opcode` patterns. 173 /// This matches one or more opcodes, and does not check any operands 174 /// whatsoever. 175 /// 176 /// TODO: Long-term, this needs to be removed. It's a hack around MIR 177 /// pattern matching limitations. 178 class AnyOpcodePattern : public Pattern { 179 public: 180 AnyOpcodePattern(StringRef Name) : Pattern(K_AnyOpcode, Name) {} 181 182 static bool classof(const Pattern *P) { return P->getKind() == K_AnyOpcode; } 183 184 void addOpcode(const CodeGenInstruction *I) { Insts.push_back(I); } 185 const auto &insts() const { return Insts; } 186 187 void print(raw_ostream &OS, bool PrintName = true) const override; 188 189 private: 190 SmallVector<const CodeGenInstruction *, 4> Insts; 191 }; 192 193 //===- CXXPattern ---------------------------------------------------------===// 194 195 /// Represents raw C++ code which may need some expansions. 196 /// 197 /// e.g. [{ return isFooBux(${src}.getReg()); }] 198 /// 199 /// For the expanded code, \see CXXPredicateCode. CXXPredicateCode objects are 200 /// created through `expandCode`. 201 /// 202 /// \see CodeExpander and \see CodeExpansions for more information on code 203 /// expansions. 204 /// 205 /// This object has two purposes: 206 /// - Represent C++ code as a pattern entry. 207 /// - Be a factory for expanded C++ code. 208 /// - It's immutable and only holds the raw code so we can expand the same 209 /// CXX pattern multiple times if we need to. 210 /// 211 /// Note that the code is always trimmed in the constructor, so leading and 212 /// trailing whitespaces are removed. This removes bloat in the output, avoids 213 /// formatting issues, but also allows us to check things like 214 /// `.startswith("return")` trivially without worrying about spaces. 215 class CXXPattern : public Pattern { 216 public: 217 CXXPattern(const StringInit &Code, StringRef Name); 218 219 CXXPattern(StringRef Code, StringRef Name) 220 : Pattern(K_CXX, Name), RawCode(Code.trim().str()) {} 221 222 static bool classof(const Pattern *P) { return P->getKind() == K_CXX; } 223 224 void setIsApply(bool Value = true) { IsApply = Value; } 225 StringRef getRawCode() const { return RawCode; } 226 227 /// Expands raw code, replacing things such as `${foo}` with their 228 /// substitution in \p CE. 229 /// 230 /// Can only be used on 'match' CXX Patterns. 'apply' CXX pattern emission 231 /// is handled differently as we emit both the 'match' and 'apply' part 232 /// together in a single Custom CXX Action. 233 /// 234 /// \param CE Map of Code Expansions 235 /// \param Locs SMLocs for the Code Expander, in case it needs to emit 236 /// diagnostics. 237 /// \param AddComment Optionally called to emit a comment before the expanded 238 /// code. 239 /// 240 /// \return A CXXPredicateCode object that contains the expanded code. Note 241 /// that this may or may not insert a new object. All CXXPredicateCode objects 242 /// are held in a set to avoid emitting duplicate C++ code. 243 const CXXPredicateCode & 244 expandCode(const CodeExpansions &CE, ArrayRef<SMLoc> Locs, 245 function_ref<void(raw_ostream &)> AddComment = {}) const; 246 247 void print(raw_ostream &OS, bool PrintName = true) const override; 248 249 private: 250 bool IsApply = false; 251 std::string RawCode; 252 }; 253 254 //===- InstructionPattern ---------------------------------------------===// 255 256 /// An operand for an InstructionPattern. 257 /// 258 /// Operands are composed of three elements: 259 /// - (Optional) Value 260 /// - (Optional) Name 261 /// - (Optional) Type 262 /// 263 /// Some examples: 264 /// (i32 0):$x -> V=int(0), Name='x', Type=i32 265 /// 0:$x -> V=int(0), Name='x' 266 /// $x -> Name='x' 267 /// i32:$x -> Name='x', Type = i32 268 class InstructionOperand { 269 public: 270 using IntImmTy = int64_t; 271 272 InstructionOperand(IntImmTy Imm, StringRef Name, PatternType Type) 273 : Value(Imm), Name(Name), Type(Type) {} 274 275 InstructionOperand(StringRef Name, PatternType Type) 276 : Name(Name), Type(Type) {} 277 278 bool isNamedImmediate() const { return hasImmValue() && isNamedOperand(); } 279 280 bool hasImmValue() const { return Value.has_value(); } 281 IntImmTy getImmValue() const { return *Value; } 282 283 bool isNamedOperand() const { return !Name.empty(); } 284 StringRef getOperandName() const { 285 assert(isNamedOperand() && "Operand is unnamed"); 286 return Name; 287 } 288 289 InstructionOperand withNewName(StringRef NewName) const { 290 InstructionOperand Result = *this; 291 Result.Name = NewName; 292 return Result; 293 } 294 295 void setIsDef(bool Value = true) { Def = Value; } 296 bool isDef() const { return Def; } 297 298 void setType(PatternType NewType) { 299 assert((!Type || (Type == NewType)) && "Overwriting type!"); 300 Type = NewType; 301 } 302 PatternType getType() const { return Type; } 303 304 std::string describe() const; 305 void print(raw_ostream &OS) const; 306 307 void dump() const; 308 309 private: 310 std::optional<int64_t> Value; 311 StringRef Name; 312 PatternType Type; 313 bool Def = false; 314 }; 315 316 /// Base class for CodeGenInstructionPattern & PatFragPattern, which handles all 317 /// the boilerplate for patterns that have a list of operands for some (pseudo) 318 /// instruction. 319 class InstructionPattern : public Pattern { 320 public: 321 virtual ~InstructionPattern() = default; 322 323 static bool classof(const Pattern *P) { 324 return P->getKind() == K_CodeGenInstruction || P->getKind() == K_PatFrag || 325 P->getKind() == K_Builtin; 326 } 327 328 template <typename... Ty> void addOperand(Ty &&...Init) { 329 Operands.emplace_back(std::forward<Ty>(Init)...); 330 } 331 332 auto &operands() { return Operands; } 333 const auto &operands() const { return Operands; } 334 unsigned operands_size() const { return Operands.size(); } 335 InstructionOperand &getOperand(unsigned K) { return Operands[K]; } 336 const InstructionOperand &getOperand(unsigned K) const { return Operands[K]; } 337 338 const InstructionOperand &operands_back() const { return Operands.back(); } 339 340 /// When this InstructionPattern is used as the match root, returns the 341 /// operands that must be redefined in the 'apply' pattern for the rule to be 342 /// valid. 343 /// 344 /// For most patterns, this just returns the defs. 345 /// For PatFrag this only returns the root of the PF. 346 /// 347 /// Returns an empty array on error. 348 virtual ArrayRef<InstructionOperand> getApplyDefsNeeded() const { 349 return {operands().begin(), getNumInstDefs()}; 350 } 351 352 auto named_operands() { 353 return make_filter_range(Operands, 354 [&](auto &O) { return O.isNamedOperand(); }); 355 } 356 357 auto named_operands() const { 358 return make_filter_range(Operands, 359 [&](auto &O) { return O.isNamedOperand(); }); 360 } 361 362 virtual bool isVariadic() const { return false; } 363 virtual unsigned getNumInstOperands() const = 0; 364 virtual unsigned getNumInstDefs() const = 0; 365 366 bool hasAllDefs() const { return operands_size() >= getNumInstDefs(); } 367 368 virtual StringRef getInstName() const = 0; 369 370 /// Diagnoses all uses of special types in this Pattern and returns true if at 371 /// least one diagnostic was emitted. 372 bool diagnoseAllSpecialTypes(ArrayRef<SMLoc> Loc, Twine Msg) const; 373 374 void reportUnreachable(ArrayRef<SMLoc> Locs) const; 375 virtual bool checkSemantics(ArrayRef<SMLoc> Loc); 376 377 void print(raw_ostream &OS, bool PrintName = true) const override; 378 379 protected: 380 InstructionPattern(unsigned K, StringRef Name) : Pattern(K, Name) {} 381 382 virtual void printExtras(raw_ostream &OS) const {} 383 384 SmallVector<InstructionOperand, 4> Operands; 385 }; 386 387 //===- OperandTable -------------------------------------------------------===// 388 389 /// Maps InstructionPattern operands to their definitions. This allows us to tie 390 /// different patterns of a (apply), (match) or (patterns) set of patterns 391 /// together. 392 class OperandTable { 393 public: 394 bool addPattern(InstructionPattern *P, 395 function_ref<void(StringRef)> DiagnoseRedef); 396 397 struct LookupResult { 398 LookupResult() = default; 399 LookupResult(InstructionPattern *Def) : Found(true), Def(Def) {} 400 401 bool Found = false; 402 InstructionPattern *Def = nullptr; 403 404 bool isLiveIn() const { return Found && !Def; } 405 }; 406 407 LookupResult lookup(StringRef OpName) const { 408 if (auto It = Table.find(OpName); It != Table.end()) 409 return LookupResult(It->second); 410 return LookupResult(); 411 } 412 413 InstructionPattern *getDef(StringRef OpName) const { 414 return lookup(OpName).Def; 415 } 416 417 void print(raw_ostream &OS, StringRef Name = "", StringRef Indent = "") const; 418 419 auto begin() const { return Table.begin(); } 420 auto end() const { return Table.end(); } 421 422 void dump() const; 423 424 private: 425 StringMap<InstructionPattern *> Table; 426 }; 427 428 //===- MIFlagsInfo --------------------------------------------------------===// 429 430 /// Helper class to contain data associated with a MIFlags operand. 431 class MIFlagsInfo { 432 public: 433 void addSetFlag(const Record *R); 434 void addUnsetFlag(const Record *R); 435 void addCopyFlag(StringRef InstName); 436 437 const auto &set_flags() const { return SetF; } 438 const auto &unset_flags() const { return UnsetF; } 439 const auto ©_flags() const { return CopyF; } 440 441 private: 442 SetVector<StringRef> SetF, UnsetF, CopyF; 443 }; 444 445 //===- CodeGenInstructionPattern ------------------------------------------===// 446 447 /// Matches an instruction or intrinsic: 448 /// e.g. `G_ADD $x, $y, $z` or `int_amdgcn_cos $a` 449 /// 450 /// Intrinsics are just normal instructions with a special operand for intrinsic 451 /// ID. Despite G_INTRINSIC opcodes being variadic, we consider that the 452 /// Intrinsic's info takes priority. This means we return: 453 /// - false for isVariadic() and other variadic-related queries. 454 /// - getNumInstDefs and getNumInstOperands use the intrinsic's in/out 455 /// operands. 456 class CodeGenInstructionPattern : public InstructionPattern { 457 public: 458 CodeGenInstructionPattern(const CodeGenInstruction &I, StringRef Name) 459 : InstructionPattern(K_CodeGenInstruction, Name), I(I) {} 460 461 static bool classof(const Pattern *P) { 462 return P->getKind() == K_CodeGenInstruction; 463 } 464 465 bool is(StringRef OpcodeName) const; 466 467 void setIntrinsic(const CodeGenIntrinsic *I) { IntrinInfo = I; } 468 const CodeGenIntrinsic *getIntrinsic() const { return IntrinInfo; } 469 bool isIntrinsic() const { return IntrinInfo; } 470 471 bool hasVariadicDefs() const; 472 bool isVariadic() const override; 473 unsigned getNumInstDefs() const override; 474 unsigned getNumInstOperands() const override; 475 476 MIFlagsInfo &getOrCreateMIFlagsInfo(); 477 const MIFlagsInfo *getMIFlagsInfo() const { return FI.get(); } 478 479 const CodeGenInstruction &getInst() const { return I; } 480 StringRef getInstName() const override; 481 482 private: 483 void printExtras(raw_ostream &OS) const override; 484 485 const CodeGenInstruction &I; 486 const CodeGenIntrinsic *IntrinInfo = nullptr; 487 std::unique_ptr<MIFlagsInfo> FI; 488 }; 489 490 //===- OperandTypeChecker -------------------------------------------------===// 491 492 /// This is a trivial type checker for all operands in a set of 493 /// InstructionPatterns. 494 /// 495 /// It infers the type of each operand, check it's consistent with the known 496 /// type of the operand, and then sets all of the types in all operands in 497 /// propagateTypes. 498 /// 499 /// It also handles verifying correctness of special types. 500 class OperandTypeChecker { 501 public: 502 OperandTypeChecker(ArrayRef<SMLoc> DiagLoc) : DiagLoc(DiagLoc) {} 503 504 /// Step 1: Check each pattern one by one. All patterns that pass through here 505 /// are added to a common worklist so propagateTypes can access them. 506 bool check(InstructionPattern &P, 507 std::function<bool(const PatternType &)> VerifyTypeOfOperand); 508 509 /// Step 2: Propagate all types. e.g. if one use of "$a" has type i32, make 510 /// all uses of "$a" have type i32. 511 void propagateTypes(); 512 513 protected: 514 ArrayRef<SMLoc> DiagLoc; 515 516 private: 517 using InconsistentTypeDiagFn = std::function<void()>; 518 519 void PrintSeenWithTypeIn(InstructionPattern &P, StringRef OpName, 520 PatternType Ty) const; 521 522 struct OpTypeInfo { 523 PatternType Type; 524 InconsistentTypeDiagFn PrintTypeSrcNote = []() {}; 525 }; 526 527 StringMap<OpTypeInfo> Types; 528 529 SmallVector<InstructionPattern *, 16> Pats; 530 }; 531 532 //===- PatFrag ------------------------------------------------------------===// 533 534 /// Represents a parsed GICombinePatFrag. This can be thought of as the 535 /// equivalent of a CodeGenInstruction, but for PatFragPatterns. 536 /// 537 /// PatFrags are made of 3 things: 538 /// - Out parameters (defs) 539 /// - In parameters 540 /// - A set of pattern lists (alternatives). 541 /// 542 /// If the PatFrag uses instruction patterns, the root must be one of the defs. 543 /// 544 /// Note that this DOES NOT represent the use of the PatFrag, only its 545 /// definition. The use of the PatFrag in a Pattern is represented by 546 /// PatFragPattern. 547 /// 548 /// PatFrags use the term "parameter" instead of operand because they're 549 /// essentially macros, and using that name avoids confusion. Other than that, 550 /// they're structured similarly to a MachineInstruction - all parameters 551 /// (operands) are in the same list, with defs at the start. This helps mapping 552 /// parameters to values, because, param N of a PatFrag is always operand N of a 553 /// PatFragPattern. 554 class PatFrag { 555 public: 556 static constexpr StringLiteral ClassName = "GICombinePatFrag"; 557 558 enum ParamKind { 559 PK_Root, 560 PK_MachineOperand, 561 PK_Imm, 562 }; 563 564 struct Param { 565 StringRef Name; 566 ParamKind Kind; 567 }; 568 569 using ParamVec = SmallVector<Param, 4>; 570 using ParamIt = ParamVec::const_iterator; 571 572 /// Represents an alternative of the PatFrag. When parsing a GICombinePatFrag, 573 /// this is created from its "Alternatives" list. Each alternative is a list 574 /// of patterns written wrapped in a `(pattern ...)` dag init. 575 /// 576 /// Each argument to the `pattern` DAG operator is parsed into a Pattern 577 /// instance. 578 struct Alternative { 579 OperandTable OpTable; 580 SmallVector<std::unique_ptr<Pattern>, 4> Pats; 581 }; 582 583 explicit PatFrag(const Record &Def); 584 585 static StringRef getParamKindStr(ParamKind OK); 586 587 StringRef getName() const; 588 589 const Record &getDef() const { return Def; } 590 ArrayRef<SMLoc> getLoc() const; 591 592 Alternative &addAlternative() { return Alts.emplace_back(); } 593 const Alternative &getAlternative(unsigned K) const { return Alts[K]; } 594 unsigned num_alternatives() const { return Alts.size(); } 595 596 void addInParam(StringRef Name, ParamKind Kind); 597 iterator_range<ParamIt> in_params() const; 598 unsigned num_in_params() const { return Params.size() - NumOutParams; } 599 600 void addOutParam(StringRef Name, ParamKind Kind); 601 iterator_range<ParamIt> out_params() const; 602 unsigned num_out_params() const { return NumOutParams; } 603 604 unsigned num_roots() const; 605 unsigned num_params() const { return num_in_params() + num_out_params(); } 606 607 /// Finds the operand \p Name and returns its index or -1 if not found. 608 /// Remember that all params are part of the same list, with out params at the 609 /// start. This means that the index returned can be used to access operands 610 /// of InstructionPatterns. 611 unsigned getParamIdx(StringRef Name) const; 612 const Param &getParam(unsigned K) const { return Params[K]; } 613 614 bool canBeMatchRoot() const { return num_roots() == 1; } 615 616 void print(raw_ostream &OS, StringRef Indent = "") const; 617 void dump() const; 618 619 /// Checks if the in-param \p ParamName can be unbound or not. 620 /// \p ArgName is the name of the argument passed to the PatFrag. 621 /// 622 /// An argument can be unbound only if, for all alternatives: 623 /// - There is no CXX pattern, OR: 624 /// - There is an InstructionPattern that binds the parameter. 625 /// 626 /// e.g. in (MyPatFrag $foo), if $foo has never been seen before (= it's 627 /// unbound), this checks if MyPatFrag supports it or not. 628 bool handleUnboundInParam(StringRef ParamName, StringRef ArgName, 629 ArrayRef<SMLoc> DiagLoc) const; 630 631 bool checkSemantics(); 632 bool buildOperandsTables(); 633 634 private: 635 static void printParamsList(raw_ostream &OS, iterator_range<ParamIt> Params); 636 637 void PrintError(Twine Msg) const; 638 639 const Record &Def; 640 unsigned NumOutParams = 0; 641 ParamVec Params; 642 SmallVector<Alternative, 2> Alts; 643 }; 644 645 //===- PatFragPattern -----------------------------------------------------===// 646 647 /// Represents a use of a GICombinePatFrag. 648 class PatFragPattern : public InstructionPattern { 649 public: 650 PatFragPattern(const PatFrag &PF, StringRef Name) 651 : InstructionPattern(K_PatFrag, Name), PF(PF) {} 652 653 static bool classof(const Pattern *P) { return P->getKind() == K_PatFrag; } 654 655 const PatFrag &getPatFrag() const { return PF; } 656 StringRef getInstName() const override { return PF.getName(); } 657 658 unsigned getNumInstDefs() const override { return PF.num_out_params(); } 659 unsigned getNumInstOperands() const override { return PF.num_params(); } 660 661 ArrayRef<InstructionOperand> getApplyDefsNeeded() const override; 662 663 bool checkSemantics(ArrayRef<SMLoc> DiagLoc) override; 664 665 /// Before emitting the patterns inside the PatFrag, add all necessary code 666 /// expansions to \p PatFragCEs imported from \p ParentCEs. 667 /// 668 /// For a MachineOperand PatFrag parameter, this will fetch the expansion for 669 /// that operand from \p ParentCEs and add it to \p PatFragCEs. Errors can be 670 /// emitted if the MachineOperand reference is unbound. 671 /// 672 /// For an Immediate PatFrag parameter this simply adds the integer value to 673 /// \p PatFragCEs as an expansion. 674 /// 675 /// \param ParentCEs Contains all of the code expansions declared by the other 676 /// patterns emitted so far in the pattern list containing 677 /// this PatFragPattern. 678 /// \param PatFragCEs Output Code Expansions (usually empty) 679 /// \param DiagLoc Diagnostic loc in case an error occurs. 680 /// \return `true` on success, `false` on failure. 681 bool mapInputCodeExpansions(const CodeExpansions &ParentCEs, 682 CodeExpansions &PatFragCEs, 683 ArrayRef<SMLoc> DiagLoc) const; 684 685 private: 686 const PatFrag &PF; 687 }; 688 689 //===- BuiltinPattern -----------------------------------------------------===// 690 691 /// Represents builtin instructions such as "GIReplaceReg" and "GIEraseRoot". 692 enum BuiltinKind { 693 BI_ReplaceReg, 694 BI_EraseRoot, 695 }; 696 697 class BuiltinPattern : public InstructionPattern { 698 struct BuiltinInfo { 699 StringLiteral DefName; 700 BuiltinKind Kind; 701 unsigned NumOps; 702 unsigned NumDefs; 703 }; 704 705 static constexpr std::array<BuiltinInfo, 2> KnownBuiltins = {{ 706 {"GIReplaceReg", BI_ReplaceReg, 2, 1}, 707 {"GIEraseRoot", BI_EraseRoot, 0, 0}, 708 }}; 709 710 public: 711 static constexpr StringLiteral ClassName = "GIBuiltinInst"; 712 713 BuiltinPattern(const Record &Def, StringRef Name) 714 : InstructionPattern(K_Builtin, Name), I(getBuiltinInfo(Def)) {} 715 716 static bool classof(const Pattern *P) { return P->getKind() == K_Builtin; } 717 718 unsigned getNumInstOperands() const override { return I.NumOps; } 719 unsigned getNumInstDefs() const override { return I.NumDefs; } 720 StringRef getInstName() const override { return I.DefName; } 721 BuiltinKind getBuiltinKind() const { return I.Kind; } 722 723 bool checkSemantics(ArrayRef<SMLoc> Loc) override; 724 725 private: 726 static BuiltinInfo getBuiltinInfo(const Record &Def); 727 728 BuiltinInfo I; 729 }; 730 731 } // namespace gi 732 } // end namespace llvm 733 734 #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H 735