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