1 //===- llvm/TableGen/Record.h - Classes for Table Records -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the main TableGen data structures, including the TableGen 11 // types, values, and high-level data structures. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TABLEGEN_RECORD_H 16 #define LLVM_TABLEGEN_RECORD_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/DenseSet.h" 21 #include "llvm/ADT/FoldingSet.h" 22 #include "llvm/ADT/PointerIntPair.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/ErrorHandling.h" 27 #include "llvm/Support/SMLoc.h" 28 #include "llvm/Support/TrailingObjects.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <algorithm> 31 #include <cassert> 32 #include <cstddef> 33 #include <cstdint> 34 #include <map> 35 #include <memory> 36 #include <string> 37 #include <utility> 38 #include <vector> 39 40 namespace llvm { 41 42 class ListRecTy; 43 struct MultiClass; 44 class Record; 45 class RecordKeeper; 46 class RecordVal; 47 class Resolver; 48 class StringInit; 49 class TypedInit; 50 51 //===----------------------------------------------------------------------===// 52 // Type Classes 53 //===----------------------------------------------------------------------===// 54 55 class RecTy { 56 public: 57 /// Subclass discriminator (for dyn_cast<> et al.) 58 enum RecTyKind { 59 BitRecTyKind, 60 BitsRecTyKind, 61 CodeRecTyKind, 62 IntRecTyKind, 63 StringRecTyKind, 64 ListRecTyKind, 65 DagRecTyKind, 66 RecordRecTyKind 67 }; 68 69 private: 70 RecTyKind Kind; 71 ListRecTy *ListTy = nullptr; 72 73 public: RecTy(RecTyKind K)74 RecTy(RecTyKind K) : Kind(K) {} 75 virtual ~RecTy() = default; 76 getRecTyKind()77 RecTyKind getRecTyKind() const { return Kind; } 78 79 virtual std::string getAsString() const = 0; print(raw_ostream & OS)80 void print(raw_ostream &OS) const { OS << getAsString(); } 81 void dump() const; 82 83 /// Return true if all values of 'this' type can be converted to the specified 84 /// type. 85 virtual bool typeIsConvertibleTo(const RecTy *RHS) const; 86 87 /// Return true if 'this' type is equal to or a subtype of RHS. For example, 88 /// a bit set is not an int, but they are convertible. 89 virtual bool typeIsA(const RecTy *RHS) const; 90 91 /// Returns the type representing list<this>. 92 ListRecTy *getListTy(); 93 }; 94 95 inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { 96 Ty.print(OS); 97 return OS; 98 } 99 100 /// 'bit' - Represent a single bit 101 class BitRecTy : public RecTy { 102 static BitRecTy Shared; 103 BitRecTy()104 BitRecTy() : RecTy(BitRecTyKind) {} 105 106 public: classof(const RecTy * RT)107 static bool classof(const RecTy *RT) { 108 return RT->getRecTyKind() == BitRecTyKind; 109 } 110 get()111 static BitRecTy *get() { return &Shared; } 112 getAsString()113 std::string getAsString() const override { return "bit"; } 114 115 bool typeIsConvertibleTo(const RecTy *RHS) const override; 116 }; 117 118 /// 'bits<n>' - Represent a fixed number of bits 119 class BitsRecTy : public RecTy { 120 unsigned Size; 121 BitsRecTy(unsigned Sz)122 explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {} 123 124 public: classof(const RecTy * RT)125 static bool classof(const RecTy *RT) { 126 return RT->getRecTyKind() == BitsRecTyKind; 127 } 128 129 static BitsRecTy *get(unsigned Sz); 130 getNumBits()131 unsigned getNumBits() const { return Size; } 132 133 std::string getAsString() const override; 134 135 bool typeIsConvertibleTo(const RecTy *RHS) const override; 136 137 bool typeIsA(const RecTy *RHS) const override; 138 }; 139 140 /// 'code' - Represent a code fragment 141 class CodeRecTy : public RecTy { 142 static CodeRecTy Shared; 143 CodeRecTy()144 CodeRecTy() : RecTy(CodeRecTyKind) {} 145 146 public: classof(const RecTy * RT)147 static bool classof(const RecTy *RT) { 148 return RT->getRecTyKind() == CodeRecTyKind; 149 } 150 get()151 static CodeRecTy *get() { return &Shared; } 152 getAsString()153 std::string getAsString() const override { return "code"; } 154 155 bool typeIsConvertibleTo(const RecTy *RHS) const override; 156 }; 157 158 /// 'int' - Represent an integer value of no particular size 159 class IntRecTy : public RecTy { 160 static IntRecTy Shared; 161 IntRecTy()162 IntRecTy() : RecTy(IntRecTyKind) {} 163 164 public: classof(const RecTy * RT)165 static bool classof(const RecTy *RT) { 166 return RT->getRecTyKind() == IntRecTyKind; 167 } 168 get()169 static IntRecTy *get() { return &Shared; } 170 getAsString()171 std::string getAsString() const override { return "int"; } 172 173 bool typeIsConvertibleTo(const RecTy *RHS) const override; 174 }; 175 176 /// 'string' - Represent an string value 177 class StringRecTy : public RecTy { 178 static StringRecTy Shared; 179 StringRecTy()180 StringRecTy() : RecTy(StringRecTyKind) {} 181 182 public: classof(const RecTy * RT)183 static bool classof(const RecTy *RT) { 184 return RT->getRecTyKind() == StringRecTyKind; 185 } 186 get()187 static StringRecTy *get() { return &Shared; } 188 189 std::string getAsString() const override; 190 191 bool typeIsConvertibleTo(const RecTy *RHS) const override; 192 }; 193 194 /// 'list<Ty>' - Represent a list of values, all of which must be of 195 /// the specified type. 196 class ListRecTy : public RecTy { 197 friend ListRecTy *RecTy::getListTy(); 198 199 RecTy *Ty; 200 ListRecTy(RecTy * T)201 explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {} 202 203 public: classof(const RecTy * RT)204 static bool classof(const RecTy *RT) { 205 return RT->getRecTyKind() == ListRecTyKind; 206 } 207 get(RecTy * T)208 static ListRecTy *get(RecTy *T) { return T->getListTy(); } getElementType()209 RecTy *getElementType() const { return Ty; } 210 211 std::string getAsString() const override; 212 213 bool typeIsConvertibleTo(const RecTy *RHS) const override; 214 215 bool typeIsA(const RecTy *RHS) const override; 216 }; 217 218 /// 'dag' - Represent a dag fragment 219 class DagRecTy : public RecTy { 220 static DagRecTy Shared; 221 DagRecTy()222 DagRecTy() : RecTy(DagRecTyKind) {} 223 224 public: classof(const RecTy * RT)225 static bool classof(const RecTy *RT) { 226 return RT->getRecTyKind() == DagRecTyKind; 227 } 228 get()229 static DagRecTy *get() { return &Shared; } 230 231 std::string getAsString() const override; 232 }; 233 234 /// '[classname]' - Type of record values that have zero or more superclasses. 235 /// 236 /// The list of superclasses is non-redundant, i.e. only contains classes that 237 /// are not the superclass of some other listed class. 238 class RecordRecTy final : public RecTy, public FoldingSetNode, 239 public TrailingObjects<RecordRecTy, Record *> { 240 friend class Record; 241 242 unsigned NumClasses; 243 RecordRecTy(unsigned Num)244 explicit RecordRecTy(unsigned Num) 245 : RecTy(RecordRecTyKind), NumClasses(Num) {} 246 247 public: 248 RecordRecTy(const RecordRecTy &) = delete; 249 RecordRecTy &operator=(const RecordRecTy &) = delete; 250 251 // Do not use sized deallocation due to trailing objects. delete(void * p)252 void operator delete(void *p) { ::operator delete(p); } 253 classof(const RecTy * RT)254 static bool classof(const RecTy *RT) { 255 return RT->getRecTyKind() == RecordRecTyKind; 256 } 257 258 /// Get the record type with the given non-redundant list of superclasses. 259 static RecordRecTy *get(ArrayRef<Record *> Classes); 260 261 void Profile(FoldingSetNodeID &ID) const; 262 getClasses()263 ArrayRef<Record *> getClasses() const { 264 return makeArrayRef(getTrailingObjects<Record *>(), NumClasses); 265 } 266 267 using const_record_iterator = Record * const *; 268 classes_begin()269 const_record_iterator classes_begin() const { return getClasses().begin(); } classes_end()270 const_record_iterator classes_end() const { return getClasses().end(); } 271 272 std::string getAsString() const override; 273 274 bool isSubClassOf(Record *Class) const; 275 bool typeIsConvertibleTo(const RecTy *RHS) const override; 276 277 bool typeIsA(const RecTy *RHS) const override; 278 }; 279 280 /// Find a common type that T1 and T2 convert to. 281 /// Return 0 if no such type exists. 282 RecTy *resolveTypes(RecTy *T1, RecTy *T2); 283 284 //===----------------------------------------------------------------------===// 285 // Initializer Classes 286 //===----------------------------------------------------------------------===// 287 288 class Init { 289 protected: 290 /// Discriminator enum (for isa<>, dyn_cast<>, et al.) 291 /// 292 /// This enum is laid out by a preorder traversal of the inheritance 293 /// hierarchy, and does not contain an entry for abstract classes, as per 294 /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst. 295 /// 296 /// We also explicitly include "first" and "last" values for each 297 /// interior node of the inheritance tree, to make it easier to read the 298 /// corresponding classof(). 299 /// 300 /// We could pack these a bit tighter by not having the IK_FirstXXXInit 301 /// and IK_LastXXXInit be their own values, but that would degrade 302 /// readability for really no benefit. 303 enum InitKind : uint8_t { 304 IK_First, // unused; silence a spurious warning 305 IK_FirstTypedInit, 306 IK_BitInit, 307 IK_BitsInit, 308 IK_CodeInit, 309 IK_DagInit, 310 IK_DefInit, 311 IK_FieldInit, 312 IK_IntInit, 313 IK_ListInit, 314 IK_FirstOpInit, 315 IK_BinOpInit, 316 IK_TernOpInit, 317 IK_UnOpInit, 318 IK_LastOpInit, 319 IK_FoldOpInit, 320 IK_IsAOpInit, 321 IK_StringInit, 322 IK_VarInit, 323 IK_VarListElementInit, 324 IK_VarBitInit, 325 IK_VarDefInit, 326 IK_LastTypedInit, 327 IK_UnsetInit 328 }; 329 330 private: 331 const InitKind Kind; 332 333 protected: 334 uint8_t Opc; // Used by UnOpInit, BinOpInit, and TernOpInit 335 336 private: 337 virtual void anchor(); 338 339 public: getKind()340 InitKind getKind() const { return Kind; } 341 342 protected: Kind(K)343 explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {} 344 345 public: 346 Init(const Init &) = delete; 347 Init &operator=(const Init &) = delete; 348 virtual ~Init() = default; 349 350 /// This virtual method should be overridden by values that may 351 /// not be completely specified yet. isComplete()352 virtual bool isComplete() const { return true; } 353 354 /// Is this a concrete and fully resolved value without any references or 355 /// stuck operations? Unset values are concrete. isConcrete()356 virtual bool isConcrete() const { return false; } 357 358 /// Print out this value. print(raw_ostream & OS)359 void print(raw_ostream &OS) const { OS << getAsString(); } 360 361 /// Convert this value to a string form. 362 virtual std::string getAsString() const = 0; 363 /// Convert this value to a string form, 364 /// without adding quote markers. This primaruly affects 365 /// StringInits where we will not surround the string value with 366 /// quotes. getAsUnquotedString()367 virtual std::string getAsUnquotedString() const { return getAsString(); } 368 369 /// Debugging method that may be called through a debugger, just 370 /// invokes print on stderr. 371 void dump() const; 372 373 /// If this initializer is convertible to Ty, return an initializer whose 374 /// type is-a Ty, generating a !cast operation if required. Otherwise, return 375 /// nullptr. 376 virtual Init *getCastTo(RecTy *Ty) const = 0; 377 378 /// Convert to an initializer whose type is-a Ty, or return nullptr if this 379 /// is not possible (this can happen if the initializer's type is convertible 380 /// to Ty, but there are unresolved references). 381 virtual Init *convertInitializerTo(RecTy *Ty) const = 0; 382 383 /// This method is used to implement the bitrange 384 /// selection operator. Given an initializer, it selects the specified bits 385 /// out, returning them as a new init of bits type. If it is not legal to use 386 /// the bit subscript operator on this initializer, return null. convertInitializerBitRange(ArrayRef<unsigned> Bits)387 virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const { 388 return nullptr; 389 } 390 391 /// This method is used to implement the list slice 392 /// selection operator. Given an initializer, it selects the specified list 393 /// elements, returning them as a new init of list type. If it is not legal 394 /// to take a slice of this, return null. convertInitListSlice(ArrayRef<unsigned> Elements)395 virtual Init *convertInitListSlice(ArrayRef<unsigned> Elements) const { 396 return nullptr; 397 } 398 399 /// This method is used to implement the FieldInit class. 400 /// Implementors of this method should return the type of the named field if 401 /// they are of record type. getFieldType(StringInit * FieldName)402 virtual RecTy *getFieldType(StringInit *FieldName) const { 403 return nullptr; 404 } 405 406 /// This method is used by classes that refer to other 407 /// variables which may not be defined at the time the expression is formed. 408 /// If a value is set for the variable later, this method will be called on 409 /// users of the value to allow the value to propagate out. resolveReferences(Resolver & R)410 virtual Init *resolveReferences(Resolver &R) const { 411 return const_cast<Init *>(this); 412 } 413 414 /// This method is used to return the initializer for the specified 415 /// bit. 416 virtual Init *getBit(unsigned Bit) const = 0; 417 }; 418 419 inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { 420 I.print(OS); return OS; 421 } 422 423 /// This is the common super-class of types that have a specific, 424 /// explicit, type. 425 class TypedInit : public Init { 426 RecTy *Ty; 427 428 protected: 429 explicit TypedInit(InitKind K, RecTy *T, uint8_t Opc = 0) Init(K,Opc)430 : Init(K, Opc), Ty(T) {} 431 432 public: 433 TypedInit(const TypedInit &) = delete; 434 TypedInit &operator=(const TypedInit &) = delete; 435 classof(const Init * I)436 static bool classof(const Init *I) { 437 return I->getKind() >= IK_FirstTypedInit && 438 I->getKind() <= IK_LastTypedInit; 439 } 440 getType()441 RecTy *getType() const { return Ty; } 442 443 Init *getCastTo(RecTy *Ty) const override; 444 Init *convertInitializerTo(RecTy *Ty) const override; 445 446 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override; 447 Init *convertInitListSlice(ArrayRef<unsigned> Elements) const override; 448 449 /// This method is used to implement the FieldInit class. 450 /// Implementors of this method should return the type of the named field if 451 /// they are of record type. 452 /// 453 RecTy *getFieldType(StringInit *FieldName) const override; 454 }; 455 456 /// '?' - Represents an uninitialized value 457 class UnsetInit : public Init { UnsetInit()458 UnsetInit() : Init(IK_UnsetInit) {} 459 460 public: 461 UnsetInit(const UnsetInit &) = delete; 462 UnsetInit &operator=(const UnsetInit &) = delete; 463 classof(const Init * I)464 static bool classof(const Init *I) { 465 return I->getKind() == IK_UnsetInit; 466 } 467 468 static UnsetInit *get(); 469 470 Init *getCastTo(RecTy *Ty) const override; 471 Init *convertInitializerTo(RecTy *Ty) const override; 472 getBit(unsigned Bit)473 Init *getBit(unsigned Bit) const override { 474 return const_cast<UnsetInit*>(this); 475 } 476 isComplete()477 bool isComplete() const override { return false; } isConcrete()478 bool isConcrete() const override { return true; } getAsString()479 std::string getAsString() const override { return "?"; } 480 }; 481 482 /// 'true'/'false' - Represent a concrete initializer for a bit. 483 class BitInit final : public TypedInit { 484 bool Value; 485 BitInit(bool V)486 explicit BitInit(bool V) : TypedInit(IK_BitInit, BitRecTy::get()), Value(V) {} 487 488 public: 489 BitInit(const BitInit &) = delete; 490 BitInit &operator=(BitInit &) = delete; 491 classof(const Init * I)492 static bool classof(const Init *I) { 493 return I->getKind() == IK_BitInit; 494 } 495 496 static BitInit *get(bool V); 497 getValue()498 bool getValue() const { return Value; } 499 500 Init *convertInitializerTo(RecTy *Ty) const override; 501 getBit(unsigned Bit)502 Init *getBit(unsigned Bit) const override { 503 assert(Bit < 1 && "Bit index out of range!"); 504 return const_cast<BitInit*>(this); 505 } 506 isConcrete()507 bool isConcrete() const override { return true; } getAsString()508 std::string getAsString() const override { return Value ? "1" : "0"; } 509 }; 510 511 /// '{ a, b, c }' - Represents an initializer for a BitsRecTy value. 512 /// It contains a vector of bits, whose size is determined by the type. 513 class BitsInit final : public TypedInit, public FoldingSetNode, 514 public TrailingObjects<BitsInit, Init *> { 515 unsigned NumBits; 516 BitsInit(unsigned N)517 BitsInit(unsigned N) 518 : TypedInit(IK_BitsInit, BitsRecTy::get(N)), NumBits(N) {} 519 520 public: 521 BitsInit(const BitsInit &) = delete; 522 BitsInit &operator=(const BitsInit &) = delete; 523 524 // Do not use sized deallocation due to trailing objects. delete(void * p)525 void operator delete(void *p) { ::operator delete(p); } 526 classof(const Init * I)527 static bool classof(const Init *I) { 528 return I->getKind() == IK_BitsInit; 529 } 530 531 static BitsInit *get(ArrayRef<Init *> Range); 532 533 void Profile(FoldingSetNodeID &ID) const; 534 getNumBits()535 unsigned getNumBits() const { return NumBits; } 536 537 Init *convertInitializerTo(RecTy *Ty) const override; 538 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override; 539 isComplete()540 bool isComplete() const override { 541 for (unsigned i = 0; i != getNumBits(); ++i) 542 if (!getBit(i)->isComplete()) return false; 543 return true; 544 } 545 allInComplete()546 bool allInComplete() const { 547 for (unsigned i = 0; i != getNumBits(); ++i) 548 if (getBit(i)->isComplete()) return false; 549 return true; 550 } 551 552 bool isConcrete() const override; 553 std::string getAsString() const override; 554 555 Init *resolveReferences(Resolver &R) const override; 556 getBit(unsigned Bit)557 Init *getBit(unsigned Bit) const override { 558 assert(Bit < NumBits && "Bit index out of range!"); 559 return getTrailingObjects<Init *>()[Bit]; 560 } 561 }; 562 563 /// '7' - Represent an initialization by a literal integer value. 564 class IntInit : public TypedInit { 565 int64_t Value; 566 IntInit(int64_t V)567 explicit IntInit(int64_t V) 568 : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {} 569 570 public: 571 IntInit(const IntInit &) = delete; 572 IntInit &operator=(const IntInit &) = delete; 573 classof(const Init * I)574 static bool classof(const Init *I) { 575 return I->getKind() == IK_IntInit; 576 } 577 578 static IntInit *get(int64_t V); 579 getValue()580 int64_t getValue() const { return Value; } 581 582 Init *convertInitializerTo(RecTy *Ty) const override; 583 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override; 584 isConcrete()585 bool isConcrete() const override { return true; } 586 std::string getAsString() const override; 587 getBit(unsigned Bit)588 Init *getBit(unsigned Bit) const override { 589 return BitInit::get((Value & (1ULL << Bit)) != 0); 590 } 591 }; 592 593 /// "foo" - Represent an initialization by a string value. 594 class StringInit : public TypedInit { 595 StringRef Value; 596 StringInit(StringRef V)597 explicit StringInit(StringRef V) 598 : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {} 599 600 public: 601 StringInit(const StringInit &) = delete; 602 StringInit &operator=(const StringInit &) = delete; 603 classof(const Init * I)604 static bool classof(const Init *I) { 605 return I->getKind() == IK_StringInit; 606 } 607 608 static StringInit *get(StringRef); 609 getValue()610 StringRef getValue() const { return Value; } 611 612 Init *convertInitializerTo(RecTy *Ty) const override; 613 isConcrete()614 bool isConcrete() const override { return true; } getAsString()615 std::string getAsString() const override { return "\"" + Value.str() + "\""; } 616 getAsUnquotedString()617 std::string getAsUnquotedString() const override { return Value; } 618 getBit(unsigned Bit)619 Init *getBit(unsigned Bit) const override { 620 llvm_unreachable("Illegal bit reference off string"); 621 } 622 }; 623 624 class CodeInit : public TypedInit { 625 StringRef Value; 626 CodeInit(StringRef V)627 explicit CodeInit(StringRef V) 628 : TypedInit(IK_CodeInit, static_cast<RecTy *>(CodeRecTy::get())), 629 Value(V) {} 630 631 public: 632 CodeInit(const StringInit &) = delete; 633 CodeInit &operator=(const StringInit &) = delete; 634 classof(const Init * I)635 static bool classof(const Init *I) { 636 return I->getKind() == IK_CodeInit; 637 } 638 639 static CodeInit *get(StringRef); 640 getValue()641 StringRef getValue() const { return Value; } 642 643 Init *convertInitializerTo(RecTy *Ty) const override; 644 isConcrete()645 bool isConcrete() const override { return true; } getAsString()646 std::string getAsString() const override { 647 return "[{" + Value.str() + "}]"; 648 } 649 getAsUnquotedString()650 std::string getAsUnquotedString() const override { return Value; } 651 getBit(unsigned Bit)652 Init *getBit(unsigned Bit) const override { 653 llvm_unreachable("Illegal bit reference off string"); 654 } 655 }; 656 657 /// [AL, AH, CL] - Represent a list of defs 658 /// 659 class ListInit final : public TypedInit, public FoldingSetNode, 660 public TrailingObjects<ListInit, Init *> { 661 unsigned NumValues; 662 663 public: 664 using const_iterator = Init *const *; 665 666 private: ListInit(unsigned N,RecTy * EltTy)667 explicit ListInit(unsigned N, RecTy *EltTy) 668 : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {} 669 670 public: 671 ListInit(const ListInit &) = delete; 672 ListInit &operator=(const ListInit &) = delete; 673 674 // Do not use sized deallocation due to trailing objects. delete(void * p)675 void operator delete(void *p) { ::operator delete(p); } 676 classof(const Init * I)677 static bool classof(const Init *I) { 678 return I->getKind() == IK_ListInit; 679 } 680 static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy); 681 682 void Profile(FoldingSetNodeID &ID) const; 683 getElement(unsigned i)684 Init *getElement(unsigned i) const { 685 assert(i < NumValues && "List element index out of range!"); 686 return getTrailingObjects<Init *>()[i]; 687 } getElementType()688 RecTy *getElementType() const { 689 return cast<ListRecTy>(getType())->getElementType(); 690 } 691 692 Record *getElementAsRecord(unsigned i) const; 693 694 Init *convertInitListSlice(ArrayRef<unsigned> Elements) const override; 695 696 Init *convertInitializerTo(RecTy *Ty) const override; 697 698 /// This method is used by classes that refer to other 699 /// variables which may not be defined at the time they expression is formed. 700 /// If a value is set for the variable later, this method will be called on 701 /// users of the value to allow the value to propagate out. 702 /// 703 Init *resolveReferences(Resolver &R) const override; 704 705 bool isConcrete() const override; 706 std::string getAsString() const override; 707 getValues()708 ArrayRef<Init*> getValues() const { 709 return makeArrayRef(getTrailingObjects<Init *>(), NumValues); 710 } 711 begin()712 const_iterator begin() const { return getTrailingObjects<Init *>(); } end()713 const_iterator end () const { return begin() + NumValues; } 714 size()715 size_t size () const { return NumValues; } empty()716 bool empty() const { return NumValues == 0; } 717 getBit(unsigned Bit)718 Init *getBit(unsigned Bit) const override { 719 llvm_unreachable("Illegal bit reference off list"); 720 } 721 }; 722 723 /// Base class for operators 724 /// 725 class OpInit : public TypedInit { 726 protected: OpInit(InitKind K,RecTy * Type,uint8_t Opc)727 explicit OpInit(InitKind K, RecTy *Type, uint8_t Opc) 728 : TypedInit(K, Type, Opc) {} 729 730 public: 731 OpInit(const OpInit &) = delete; 732 OpInit &operator=(OpInit &) = delete; 733 classof(const Init * I)734 static bool classof(const Init *I) { 735 return I->getKind() >= IK_FirstOpInit && 736 I->getKind() <= IK_LastOpInit; 737 } 738 739 // Clone - Clone this operator, replacing arguments with the new list 740 virtual OpInit *clone(ArrayRef<Init *> Operands) const = 0; 741 742 virtual unsigned getNumOperands() const = 0; 743 virtual Init *getOperand(unsigned i) const = 0; 744 745 Init *getBit(unsigned Bit) const override; 746 }; 747 748 /// !op (X) - Transform an init. 749 /// 750 class UnOpInit : public OpInit, public FoldingSetNode { 751 public: 752 enum UnaryOp : uint8_t { CAST, HEAD, TAIL, SIZE, EMPTY }; 753 754 private: 755 Init *LHS; 756 UnOpInit(UnaryOp opc,Init * lhs,RecTy * Type)757 UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) 758 : OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {} 759 760 public: 761 UnOpInit(const UnOpInit &) = delete; 762 UnOpInit &operator=(const UnOpInit &) = delete; 763 classof(const Init * I)764 static bool classof(const Init *I) { 765 return I->getKind() == IK_UnOpInit; 766 } 767 768 static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); 769 770 void Profile(FoldingSetNodeID &ID) const; 771 772 // Clone - Clone this operator, replacing arguments with the new list clone(ArrayRef<Init * > Operands)773 OpInit *clone(ArrayRef<Init *> Operands) const override { 774 assert(Operands.size() == 1 && 775 "Wrong number of operands for unary operation"); 776 return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); 777 } 778 getNumOperands()779 unsigned getNumOperands() const override { return 1; } 780 getOperand(unsigned i)781 Init *getOperand(unsigned i) const override { 782 assert(i == 0 && "Invalid operand id for unary operator"); 783 return getOperand(); 784 } 785 getOpcode()786 UnaryOp getOpcode() const { return (UnaryOp)Opc; } getOperand()787 Init *getOperand() const { return LHS; } 788 789 // Fold - If possible, fold this to a simpler init. Return this if not 790 // possible to fold. 791 Init *Fold(Record *CurRec, bool IsFinal = false) const; 792 793 Init *resolveReferences(Resolver &R) const override; 794 795 std::string getAsString() const override; 796 }; 797 798 /// !op (X, Y) - Combine two inits. 799 class BinOpInit : public OpInit, public FoldingSetNode { 800 public: 801 enum BinaryOp : uint8_t { ADD, AND, OR, SHL, SRA, SRL, LISTCONCAT, 802 STRCONCAT, CONCAT, EQ, NE, LE, LT, GE, GT }; 803 804 private: 805 Init *LHS, *RHS; 806 BinOpInit(BinaryOp opc,Init * lhs,Init * rhs,RecTy * Type)807 BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : 808 OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {} 809 810 public: 811 BinOpInit(const BinOpInit &) = delete; 812 BinOpInit &operator=(const BinOpInit &) = delete; 813 classof(const Init * I)814 static bool classof(const Init *I) { 815 return I->getKind() == IK_BinOpInit; 816 } 817 818 static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, 819 RecTy *Type); 820 static Init *getStrConcat(Init *lhs, Init *rhs); 821 822 void Profile(FoldingSetNodeID &ID) const; 823 824 // Clone - Clone this operator, replacing arguments with the new list clone(ArrayRef<Init * > Operands)825 OpInit *clone(ArrayRef<Init *> Operands) const override { 826 assert(Operands.size() == 2 && 827 "Wrong number of operands for binary operation"); 828 return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); 829 } 830 getNumOperands()831 unsigned getNumOperands() const override { return 2; } getOperand(unsigned i)832 Init *getOperand(unsigned i) const override { 833 switch (i) { 834 default: llvm_unreachable("Invalid operand id for binary operator"); 835 case 0: return getLHS(); 836 case 1: return getRHS(); 837 } 838 } 839 getOpcode()840 BinaryOp getOpcode() const { return (BinaryOp)Opc; } getLHS()841 Init *getLHS() const { return LHS; } getRHS()842 Init *getRHS() const { return RHS; } 843 844 // Fold - If possible, fold this to a simpler init. Return this if not 845 // possible to fold. 846 Init *Fold(Record *CurRec) const; 847 848 Init *resolveReferences(Resolver &R) const override; 849 850 std::string getAsString() const override; 851 }; 852 853 /// !op (X, Y, Z) - Combine two inits. 854 class TernOpInit : public OpInit, public FoldingSetNode { 855 public: 856 enum TernaryOp : uint8_t { SUBST, FOREACH, IF, DAG }; 857 858 private: 859 Init *LHS, *MHS, *RHS; 860 TernOpInit(TernaryOp opc,Init * lhs,Init * mhs,Init * rhs,RecTy * Type)861 TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, 862 RecTy *Type) : 863 OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {} 864 865 public: 866 TernOpInit(const TernOpInit &) = delete; 867 TernOpInit &operator=(const TernOpInit &) = delete; 868 classof(const Init * I)869 static bool classof(const Init *I) { 870 return I->getKind() == IK_TernOpInit; 871 } 872 873 static TernOpInit *get(TernaryOp opc, Init *lhs, 874 Init *mhs, Init *rhs, 875 RecTy *Type); 876 877 void Profile(FoldingSetNodeID &ID) const; 878 879 // Clone - Clone this operator, replacing arguments with the new list clone(ArrayRef<Init * > Operands)880 OpInit *clone(ArrayRef<Init *> Operands) const override { 881 assert(Operands.size() == 3 && 882 "Wrong number of operands for ternary operation"); 883 return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2], 884 getType()); 885 } 886 getNumOperands()887 unsigned getNumOperands() const override { return 3; } getOperand(unsigned i)888 Init *getOperand(unsigned i) const override { 889 switch (i) { 890 default: llvm_unreachable("Invalid operand id for ternary operator"); 891 case 0: return getLHS(); 892 case 1: return getMHS(); 893 case 2: return getRHS(); 894 } 895 } 896 getOpcode()897 TernaryOp getOpcode() const { return (TernaryOp)Opc; } getLHS()898 Init *getLHS() const { return LHS; } getMHS()899 Init *getMHS() const { return MHS; } getRHS()900 Init *getRHS() const { return RHS; } 901 902 // Fold - If possible, fold this to a simpler init. Return this if not 903 // possible to fold. 904 Init *Fold(Record *CurRec) const; 905 isComplete()906 bool isComplete() const override { 907 return LHS->isComplete() && MHS->isComplete() && RHS->isComplete(); 908 } 909 910 Init *resolveReferences(Resolver &R) const override; 911 912 std::string getAsString() const override; 913 }; 914 915 /// !foldl (a, b, expr, start, lst) - Fold over a list. 916 class FoldOpInit : public TypedInit, public FoldingSetNode { 917 private: 918 Init *Start; 919 Init *List; 920 Init *A; 921 Init *B; 922 Init *Expr; 923 FoldOpInit(Init * Start,Init * List,Init * A,Init * B,Init * Expr,RecTy * Type)924 FoldOpInit(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type) 925 : TypedInit(IK_FoldOpInit, Type), Start(Start), List(List), A(A), B(B), 926 Expr(Expr) {} 927 928 public: 929 FoldOpInit(const FoldOpInit &) = delete; 930 FoldOpInit &operator=(const FoldOpInit &) = delete; 931 classof(const Init * I)932 static bool classof(const Init *I) { return I->getKind() == IK_FoldOpInit; } 933 934 static FoldOpInit *get(Init *Start, Init *List, Init *A, Init *B, Init *Expr, 935 RecTy *Type); 936 937 void Profile(FoldingSetNodeID &ID) const; 938 939 // Fold - If possible, fold this to a simpler init. Return this if not 940 // possible to fold. 941 Init *Fold(Record *CurRec) const; 942 isComplete()943 bool isComplete() const override { return false; } 944 945 Init *resolveReferences(Resolver &R) const override; 946 947 Init *getBit(unsigned Bit) const override; 948 949 std::string getAsString() const override; 950 }; 951 952 /// !isa<type>(expr) - Dynamically determine the type of an expression. 953 class IsAOpInit : public TypedInit, public FoldingSetNode { 954 private: 955 RecTy *CheckType; 956 Init *Expr; 957 IsAOpInit(RecTy * CheckType,Init * Expr)958 IsAOpInit(RecTy *CheckType, Init *Expr) 959 : TypedInit(IK_IsAOpInit, IntRecTy::get()), CheckType(CheckType), 960 Expr(Expr) {} 961 962 public: 963 IsAOpInit(const IsAOpInit &) = delete; 964 IsAOpInit &operator=(const IsAOpInit &) = delete; 965 classof(const Init * I)966 static bool classof(const Init *I) { return I->getKind() == IK_IsAOpInit; } 967 968 static IsAOpInit *get(RecTy *CheckType, Init *Expr); 969 970 void Profile(FoldingSetNodeID &ID) const; 971 972 // Fold - If possible, fold this to a simpler init. Return this if not 973 // possible to fold. 974 Init *Fold() const; 975 isComplete()976 bool isComplete() const override { return false; } 977 978 Init *resolveReferences(Resolver &R) const override; 979 980 Init *getBit(unsigned Bit) const override; 981 982 std::string getAsString() const override; 983 }; 984 985 /// 'Opcode' - Represent a reference to an entire variable object. 986 class VarInit : public TypedInit { 987 Init *VarName; 988 VarInit(Init * VN,RecTy * T)989 explicit VarInit(Init *VN, RecTy *T) 990 : TypedInit(IK_VarInit, T), VarName(VN) {} 991 992 public: 993 VarInit(const VarInit &) = delete; 994 VarInit &operator=(const VarInit &) = delete; 995 classof(const Init * I)996 static bool classof(const Init *I) { 997 return I->getKind() == IK_VarInit; 998 } 999 1000 static VarInit *get(StringRef VN, RecTy *T); 1001 static VarInit *get(Init *VN, RecTy *T); 1002 1003 StringRef getName() const; getNameInit()1004 Init *getNameInit() const { return VarName; } 1005 getNameInitAsString()1006 std::string getNameInitAsString() const { 1007 return getNameInit()->getAsUnquotedString(); 1008 } 1009 1010 /// This method is used by classes that refer to other 1011 /// variables which may not be defined at the time they expression is formed. 1012 /// If a value is set for the variable later, this method will be called on 1013 /// users of the value to allow the value to propagate out. 1014 /// 1015 Init *resolveReferences(Resolver &R) const override; 1016 1017 Init *getBit(unsigned Bit) const override; 1018 getAsString()1019 std::string getAsString() const override { return getName(); } 1020 }; 1021 1022 /// Opcode{0} - Represent access to one bit of a variable or field. 1023 class VarBitInit final : public TypedInit { 1024 TypedInit *TI; 1025 unsigned Bit; 1026 VarBitInit(TypedInit * T,unsigned B)1027 VarBitInit(TypedInit *T, unsigned B) 1028 : TypedInit(IK_VarBitInit, BitRecTy::get()), TI(T), Bit(B) { 1029 assert(T->getType() && 1030 (isa<IntRecTy>(T->getType()) || 1031 (isa<BitsRecTy>(T->getType()) && 1032 cast<BitsRecTy>(T->getType())->getNumBits() > B)) && 1033 "Illegal VarBitInit expression!"); 1034 } 1035 1036 public: 1037 VarBitInit(const VarBitInit &) = delete; 1038 VarBitInit &operator=(const VarBitInit &) = delete; 1039 classof(const Init * I)1040 static bool classof(const Init *I) { 1041 return I->getKind() == IK_VarBitInit; 1042 } 1043 1044 static VarBitInit *get(TypedInit *T, unsigned B); 1045 getBitVar()1046 Init *getBitVar() const { return TI; } getBitNum()1047 unsigned getBitNum() const { return Bit; } 1048 1049 std::string getAsString() const override; 1050 Init *resolveReferences(Resolver &R) const override; 1051 getBit(unsigned B)1052 Init *getBit(unsigned B) const override { 1053 assert(B < 1 && "Bit index out of range!"); 1054 return const_cast<VarBitInit*>(this); 1055 } 1056 }; 1057 1058 /// List[4] - Represent access to one element of a var or 1059 /// field. 1060 class VarListElementInit : public TypedInit { 1061 TypedInit *TI; 1062 unsigned Element; 1063 VarListElementInit(TypedInit * T,unsigned E)1064 VarListElementInit(TypedInit *T, unsigned E) 1065 : TypedInit(IK_VarListElementInit, 1066 cast<ListRecTy>(T->getType())->getElementType()), 1067 TI(T), Element(E) { 1068 assert(T->getType() && isa<ListRecTy>(T->getType()) && 1069 "Illegal VarBitInit expression!"); 1070 } 1071 1072 public: 1073 VarListElementInit(const VarListElementInit &) = delete; 1074 VarListElementInit &operator=(const VarListElementInit &) = delete; 1075 classof(const Init * I)1076 static bool classof(const Init *I) { 1077 return I->getKind() == IK_VarListElementInit; 1078 } 1079 1080 static VarListElementInit *get(TypedInit *T, unsigned E); 1081 getVariable()1082 TypedInit *getVariable() const { return TI; } getElementNum()1083 unsigned getElementNum() const { return Element; } 1084 1085 std::string getAsString() const override; 1086 Init *resolveReferences(Resolver &R) const override; 1087 1088 Init *getBit(unsigned Bit) const override; 1089 }; 1090 1091 /// AL - Represent a reference to a 'def' in the description 1092 class DefInit : public TypedInit { 1093 friend class Record; 1094 1095 Record *Def; 1096 1097 explicit DefInit(Record *D); 1098 1099 public: 1100 DefInit(const DefInit &) = delete; 1101 DefInit &operator=(const DefInit &) = delete; 1102 classof(const Init * I)1103 static bool classof(const Init *I) { 1104 return I->getKind() == IK_DefInit; 1105 } 1106 1107 static DefInit *get(Record*); 1108 1109 Init *convertInitializerTo(RecTy *Ty) const override; 1110 getDef()1111 Record *getDef() const { return Def; } 1112 1113 //virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits); 1114 1115 RecTy *getFieldType(StringInit *FieldName) const override; 1116 isConcrete()1117 bool isConcrete() const override { return true; } 1118 std::string getAsString() const override; 1119 getBit(unsigned Bit)1120 Init *getBit(unsigned Bit) const override { 1121 llvm_unreachable("Illegal bit reference off def"); 1122 } 1123 }; 1124 1125 /// classname<targs...> - Represent an uninstantiated anonymous class 1126 /// instantiation. 1127 class VarDefInit final : public TypedInit, public FoldingSetNode, 1128 public TrailingObjects<VarDefInit, Init *> { 1129 Record *Class; 1130 DefInit *Def = nullptr; // after instantiation 1131 unsigned NumArgs; 1132 VarDefInit(Record * Class,unsigned N)1133 explicit VarDefInit(Record *Class, unsigned N) 1134 : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class), NumArgs(N) {} 1135 1136 DefInit *instantiate(); 1137 1138 public: 1139 VarDefInit(const VarDefInit &) = delete; 1140 VarDefInit &operator=(const VarDefInit &) = delete; 1141 1142 // Do not use sized deallocation due to trailing objects. delete(void * p)1143 void operator delete(void *p) { ::operator delete(p); } 1144 classof(const Init * I)1145 static bool classof(const Init *I) { 1146 return I->getKind() == IK_VarDefInit; 1147 } 1148 static VarDefInit *get(Record *Class, ArrayRef<Init *> Args); 1149 1150 void Profile(FoldingSetNodeID &ID) const; 1151 1152 Init *resolveReferences(Resolver &R) const override; 1153 Init *Fold() const; 1154 1155 std::string getAsString() const override; 1156 getArg(unsigned i)1157 Init *getArg(unsigned i) const { 1158 assert(i < NumArgs && "Argument index out of range!"); 1159 return getTrailingObjects<Init *>()[i]; 1160 } 1161 1162 using const_iterator = Init *const *; 1163 args_begin()1164 const_iterator args_begin() const { return getTrailingObjects<Init *>(); } args_end()1165 const_iterator args_end () const { return args_begin() + NumArgs; } 1166 args_size()1167 size_t args_size () const { return NumArgs; } args_empty()1168 bool args_empty() const { return NumArgs == 0; } 1169 args()1170 ArrayRef<Init *> args() const { return makeArrayRef(args_begin(), NumArgs); } 1171 getBit(unsigned Bit)1172 Init *getBit(unsigned Bit) const override { 1173 llvm_unreachable("Illegal bit reference off anonymous def"); 1174 } 1175 }; 1176 1177 /// X.Y - Represent a reference to a subfield of a variable 1178 class FieldInit : public TypedInit { 1179 Init *Rec; // Record we are referring to 1180 StringInit *FieldName; // Field we are accessing 1181 FieldInit(Init * R,StringInit * FN)1182 FieldInit(Init *R, StringInit *FN) 1183 : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) { 1184 assert(getType() && "FieldInit with non-record type!"); 1185 } 1186 1187 public: 1188 FieldInit(const FieldInit &) = delete; 1189 FieldInit &operator=(const FieldInit &) = delete; 1190 classof(const Init * I)1191 static bool classof(const Init *I) { 1192 return I->getKind() == IK_FieldInit; 1193 } 1194 1195 static FieldInit *get(Init *R, StringInit *FN); 1196 getRecord()1197 Init *getRecord() const { return Rec; } getFieldName()1198 StringInit *getFieldName() const { return FieldName; } 1199 1200 Init *getBit(unsigned Bit) const override; 1201 1202 Init *resolveReferences(Resolver &R) const override; 1203 Init *Fold(Record *CurRec) const; 1204 getAsString()1205 std::string getAsString() const override { 1206 return Rec->getAsString() + "." + FieldName->getValue().str(); 1207 } 1208 }; 1209 1210 /// (v a, b) - Represent a DAG tree value. DAG inits are required 1211 /// to have at least one value then a (possibly empty) list of arguments. Each 1212 /// argument can have a name associated with it. 1213 class DagInit final : public TypedInit, public FoldingSetNode, 1214 public TrailingObjects<DagInit, Init *, StringInit *> { 1215 friend TrailingObjects; 1216 1217 Init *Val; 1218 StringInit *ValName; 1219 unsigned NumArgs; 1220 unsigned NumArgNames; 1221 DagInit(Init * V,StringInit * VN,unsigned NumArgs,unsigned NumArgNames)1222 DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames) 1223 : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN), 1224 NumArgs(NumArgs), NumArgNames(NumArgNames) {} 1225 numTrailingObjects(OverloadToken<Init * >)1226 size_t numTrailingObjects(OverloadToken<Init *>) const { return NumArgs; } 1227 1228 public: 1229 DagInit(const DagInit &) = delete; 1230 DagInit &operator=(const DagInit &) = delete; 1231 classof(const Init * I)1232 static bool classof(const Init *I) { 1233 return I->getKind() == IK_DagInit; 1234 } 1235 1236 static DagInit *get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, 1237 ArrayRef<StringInit*> NameRange); 1238 static DagInit *get(Init *V, StringInit *VN, 1239 ArrayRef<std::pair<Init*, StringInit*>> Args); 1240 1241 void Profile(FoldingSetNodeID &ID) const; 1242 getOperator()1243 Init *getOperator() const { return Val; } 1244 getName()1245 StringInit *getName() const { return ValName; } 1246 getNameStr()1247 StringRef getNameStr() const { 1248 return ValName ? ValName->getValue() : StringRef(); 1249 } 1250 getNumArgs()1251 unsigned getNumArgs() const { return NumArgs; } 1252 getArg(unsigned Num)1253 Init *getArg(unsigned Num) const { 1254 assert(Num < NumArgs && "Arg number out of range!"); 1255 return getTrailingObjects<Init *>()[Num]; 1256 } 1257 getArgName(unsigned Num)1258 StringInit *getArgName(unsigned Num) const { 1259 assert(Num < NumArgNames && "Arg number out of range!"); 1260 return getTrailingObjects<StringInit *>()[Num]; 1261 } 1262 getArgNameStr(unsigned Num)1263 StringRef getArgNameStr(unsigned Num) const { 1264 StringInit *Init = getArgName(Num); 1265 return Init ? Init->getValue() : StringRef(); 1266 } 1267 getArgs()1268 ArrayRef<Init *> getArgs() const { 1269 return makeArrayRef(getTrailingObjects<Init *>(), NumArgs); 1270 } 1271 getArgNames()1272 ArrayRef<StringInit *> getArgNames() const { 1273 return makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames); 1274 } 1275 1276 Init *resolveReferences(Resolver &R) const override; 1277 1278 bool isConcrete() const override; 1279 std::string getAsString() const override; 1280 1281 using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator; 1282 using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator; 1283 arg_begin()1284 inline const_arg_iterator arg_begin() const { return getArgs().begin(); } arg_end()1285 inline const_arg_iterator arg_end () const { return getArgs().end(); } 1286 arg_size()1287 inline size_t arg_size () const { return NumArgs; } arg_empty()1288 inline bool arg_empty() const { return NumArgs == 0; } 1289 name_begin()1290 inline const_name_iterator name_begin() const { return getArgNames().begin();} name_end()1291 inline const_name_iterator name_end () const { return getArgNames().end(); } 1292 name_size()1293 inline size_t name_size () const { return NumArgNames; } name_empty()1294 inline bool name_empty() const { return NumArgNames == 0; } 1295 getBit(unsigned Bit)1296 Init *getBit(unsigned Bit) const override { 1297 llvm_unreachable("Illegal bit reference off dag"); 1298 } 1299 }; 1300 1301 //===----------------------------------------------------------------------===// 1302 // High-Level Classes 1303 //===----------------------------------------------------------------------===// 1304 1305 class RecordVal { 1306 friend class Record; 1307 1308 Init *Name; 1309 PointerIntPair<RecTy *, 1, bool> TyAndPrefix; 1310 Init *Value; 1311 1312 public: 1313 RecordVal(Init *N, RecTy *T, bool P); 1314 1315 StringRef getName() const; getNameInit()1316 Init *getNameInit() const { return Name; } 1317 getNameInitAsString()1318 std::string getNameInitAsString() const { 1319 return getNameInit()->getAsUnquotedString(); 1320 } 1321 getPrefix()1322 bool getPrefix() const { return TyAndPrefix.getInt(); } getType()1323 RecTy *getType() const { return TyAndPrefix.getPointer(); } getValue()1324 Init *getValue() const { return Value; } 1325 1326 bool setValue(Init *V); 1327 1328 void dump() const; 1329 void print(raw_ostream &OS, bool PrintSem = true) const; 1330 }; 1331 1332 inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) { 1333 RV.print(OS << " "); 1334 return OS; 1335 } 1336 1337 class Record { 1338 static unsigned LastID; 1339 1340 Init *Name; 1341 // Location where record was instantiated, followed by the location of 1342 // multiclass prototypes used. 1343 SmallVector<SMLoc, 4> Locs; 1344 SmallVector<Init *, 0> TemplateArgs; 1345 SmallVector<RecordVal, 0> Values; 1346 1347 // All superclasses in the inheritance forest in reverse preorder (yes, it 1348 // must be a forest; diamond-shaped inheritance is not allowed). 1349 SmallVector<std::pair<Record *, SMRange>, 0> SuperClasses; 1350 1351 // Tracks Record instances. Not owned by Record. 1352 RecordKeeper &TrackedRecords; 1353 1354 DefInit *TheInit = nullptr; 1355 1356 // Unique record ID. 1357 unsigned ID; 1358 1359 bool IsAnonymous; 1360 bool IsClass; 1361 1362 void checkName(); 1363 1364 public: 1365 // Constructs a record. 1366 explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records, 1367 bool Anonymous = false, bool Class = false) Name(N)1368 : Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records), 1369 ID(LastID++), IsAnonymous(Anonymous), IsClass(Class) { 1370 checkName(); 1371 } 1372 1373 explicit Record(StringRef N, ArrayRef<SMLoc> locs, RecordKeeper &records, 1374 bool Class = false) Record(StringInit::get (N),locs,records,false,Class)1375 : Record(StringInit::get(N), locs, records, false, Class) {} 1376 1377 // When copy-constructing a Record, we must still guarantee a globally unique 1378 // ID number. Don't copy TheInit either since it's owned by the original 1379 // record. All other fields can be copied normally. Record(const Record & O)1380 Record(const Record &O) 1381 : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), 1382 Values(O.Values), SuperClasses(O.SuperClasses), 1383 TrackedRecords(O.TrackedRecords), ID(LastID++), 1384 IsAnonymous(O.IsAnonymous), IsClass(O.IsClass) { } 1385 getNewUID()1386 static unsigned getNewUID() { return LastID++; } 1387 getID()1388 unsigned getID() const { return ID; } 1389 getName()1390 StringRef getName() const { return cast<StringInit>(Name)->getValue(); } 1391 getNameInit()1392 Init *getNameInit() const { 1393 return Name; 1394 } 1395 getNameInitAsString()1396 const std::string getNameInitAsString() const { 1397 return getNameInit()->getAsUnquotedString(); 1398 } 1399 1400 void setName(Init *Name); // Also updates RecordKeeper. 1401 getLoc()1402 ArrayRef<SMLoc> getLoc() const { return Locs; } appendLoc(SMLoc Loc)1403 void appendLoc(SMLoc Loc) { Locs.push_back(Loc); } 1404 1405 // Make the type that this record should have based on its superclasses. 1406 RecordRecTy *getType(); 1407 1408 /// get the corresponding DefInit. 1409 DefInit *getDefInit(); 1410 isClass()1411 bool isClass() const { return IsClass; } 1412 getTemplateArgs()1413 ArrayRef<Init *> getTemplateArgs() const { 1414 return TemplateArgs; 1415 } 1416 getValues()1417 ArrayRef<RecordVal> getValues() const { return Values; } 1418 getSuperClasses()1419 ArrayRef<std::pair<Record *, SMRange>> getSuperClasses() const { 1420 return SuperClasses; 1421 } 1422 1423 /// Append the direct super classes of this record to Classes. 1424 void getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const; 1425 isTemplateArg(Init * Name)1426 bool isTemplateArg(Init *Name) const { 1427 for (Init *TA : TemplateArgs) 1428 if (TA == Name) return true; 1429 return false; 1430 } 1431 getValue(const Init * Name)1432 const RecordVal *getValue(const Init *Name) const { 1433 for (const RecordVal &Val : Values) 1434 if (Val.Name == Name) return &Val; 1435 return nullptr; 1436 } 1437 getValue(StringRef Name)1438 const RecordVal *getValue(StringRef Name) const { 1439 return getValue(StringInit::get(Name)); 1440 } 1441 getValue(const Init * Name)1442 RecordVal *getValue(const Init *Name) { 1443 return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name)); 1444 } 1445 getValue(StringRef Name)1446 RecordVal *getValue(StringRef Name) { 1447 return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name)); 1448 } 1449 addTemplateArg(Init * Name)1450 void addTemplateArg(Init *Name) { 1451 assert(!isTemplateArg(Name) && "Template arg already defined!"); 1452 TemplateArgs.push_back(Name); 1453 } 1454 addValue(const RecordVal & RV)1455 void addValue(const RecordVal &RV) { 1456 assert(getValue(RV.getNameInit()) == nullptr && "Value already added!"); 1457 Values.push_back(RV); 1458 } 1459 removeValue(Init * Name)1460 void removeValue(Init *Name) { 1461 for (unsigned i = 0, e = Values.size(); i != e; ++i) 1462 if (Values[i].getNameInit() == Name) { 1463 Values.erase(Values.begin()+i); 1464 return; 1465 } 1466 llvm_unreachable("Cannot remove an entry that does not exist!"); 1467 } 1468 removeValue(StringRef Name)1469 void removeValue(StringRef Name) { 1470 removeValue(StringInit::get(Name)); 1471 } 1472 isSubClassOf(const Record * R)1473 bool isSubClassOf(const Record *R) const { 1474 for (const auto &SCPair : SuperClasses) 1475 if (SCPair.first == R) 1476 return true; 1477 return false; 1478 } 1479 isSubClassOf(StringRef Name)1480 bool isSubClassOf(StringRef Name) const { 1481 for (const auto &SCPair : SuperClasses) { 1482 if (const auto *SI = dyn_cast<StringInit>(SCPair.first->getNameInit())) { 1483 if (SI->getValue() == Name) 1484 return true; 1485 } else if (SCPair.first->getNameInitAsString() == Name) { 1486 return true; 1487 } 1488 } 1489 return false; 1490 } 1491 addSuperClass(Record * R,SMRange Range)1492 void addSuperClass(Record *R, SMRange Range) { 1493 assert(!TheInit && "changing type of record after it has been referenced"); 1494 assert(!isSubClassOf(R) && "Already subclassing record!"); 1495 SuperClasses.push_back(std::make_pair(R, Range)); 1496 } 1497 1498 /// If there are any field references that refer to fields 1499 /// that have been filled in, we can propagate the values now. 1500 /// 1501 /// This is a final resolve: any error messages, e.g. due to undefined 1502 /// !cast references, are generated now. 1503 void resolveReferences(); 1504 1505 /// Apply the resolver to the name of the record as well as to the 1506 /// initializers of all fields of the record except SkipVal. 1507 /// 1508 /// The resolver should not resolve any of the fields itself, to avoid 1509 /// recursion / infinite loops. 1510 void resolveReferences(Resolver &R, const RecordVal *SkipVal = nullptr); 1511 1512 /// If anything in this record refers to RV, replace the 1513 /// reference to RV with the RHS of RV. If RV is null, we resolve all 1514 /// possible references. 1515 void resolveReferencesTo(const RecordVal *RV); 1516 getRecords()1517 RecordKeeper &getRecords() const { 1518 return TrackedRecords; 1519 } 1520 isAnonymous()1521 bool isAnonymous() const { 1522 return IsAnonymous; 1523 } 1524 1525 void print(raw_ostream &OS) const; 1526 void dump() const; 1527 1528 //===--------------------------------------------------------------------===// 1529 // High-level methods useful to tablegen back-ends 1530 // 1531 1532 /// Return the initializer for a value with the specified name, 1533 /// or throw an exception if the field does not exist. 1534 Init *getValueInit(StringRef FieldName) const; 1535 1536 /// Return true if the named field is unset. isValueUnset(StringRef FieldName)1537 bool isValueUnset(StringRef FieldName) const { 1538 return isa<UnsetInit>(getValueInit(FieldName)); 1539 } 1540 1541 /// This method looks up the specified field and returns 1542 /// its value as a string, throwing an exception if the field does not exist 1543 /// or if the value is not a string. 1544 StringRef getValueAsString(StringRef FieldName) const; 1545 1546 /// This method looks up the specified field and returns 1547 /// its value as a BitsInit, throwing an exception if the field does not exist 1548 /// or if the value is not the right type. 1549 BitsInit *getValueAsBitsInit(StringRef FieldName) const; 1550 1551 /// This method looks up the specified field and returns 1552 /// its value as a ListInit, throwing an exception if the field does not exist 1553 /// or if the value is not the right type. 1554 ListInit *getValueAsListInit(StringRef FieldName) const; 1555 1556 /// This method looks up the specified field and 1557 /// returns its value as a vector of records, throwing an exception if the 1558 /// field does not exist or if the value is not the right type. 1559 std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const; 1560 1561 /// This method looks up the specified field and 1562 /// returns its value as a vector of integers, throwing an exception if the 1563 /// field does not exist or if the value is not the right type. 1564 std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const; 1565 1566 /// This method looks up the specified field and 1567 /// returns its value as a vector of strings, throwing an exception if the 1568 /// field does not exist or if the value is not the right type. 1569 std::vector<StringRef> getValueAsListOfStrings(StringRef FieldName) const; 1570 1571 /// This method looks up the specified field and returns its 1572 /// value as a Record, throwing an exception if the field does not exist or if 1573 /// the value is not the right type. 1574 Record *getValueAsDef(StringRef FieldName) const; 1575 1576 /// This method looks up the specified field and returns its 1577 /// value as a bit, throwing an exception if the field does not exist or if 1578 /// the value is not the right type. 1579 bool getValueAsBit(StringRef FieldName) const; 1580 1581 /// This method looks up the specified field and 1582 /// returns its value as a bit. If the field is unset, sets Unset to true and 1583 /// returns false. 1584 bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const; 1585 1586 /// This method looks up the specified field and returns its 1587 /// value as an int64_t, throwing an exception if the field does not exist or 1588 /// if the value is not the right type. 1589 int64_t getValueAsInt(StringRef FieldName) const; 1590 1591 /// This method looks up the specified field and returns its 1592 /// value as an Dag, throwing an exception if the field does not exist or if 1593 /// the value is not the right type. 1594 DagInit *getValueAsDag(StringRef FieldName) const; 1595 }; 1596 1597 raw_ostream &operator<<(raw_ostream &OS, const Record &R); 1598 1599 class RecordKeeper { 1600 friend class RecordRecTy; 1601 using RecordMap = std::map<std::string, std::unique_ptr<Record>>; 1602 RecordMap Classes, Defs; 1603 FoldingSet<RecordRecTy> RecordTypePool; 1604 std::map<std::string, Init *> ExtraGlobals; 1605 unsigned AnonCounter = 0; 1606 1607 public: getClasses()1608 const RecordMap &getClasses() const { return Classes; } getDefs()1609 const RecordMap &getDefs() const { return Defs; } 1610 getClass(StringRef Name)1611 Record *getClass(StringRef Name) const { 1612 auto I = Classes.find(Name); 1613 return I == Classes.end() ? nullptr : I->second.get(); 1614 } 1615 getDef(StringRef Name)1616 Record *getDef(StringRef Name) const { 1617 auto I = Defs.find(Name); 1618 return I == Defs.end() ? nullptr : I->second.get(); 1619 } 1620 getGlobal(StringRef Name)1621 Init *getGlobal(StringRef Name) const { 1622 if (Record *R = getDef(Name)) 1623 return R->getDefInit(); 1624 auto It = ExtraGlobals.find(Name); 1625 return It == ExtraGlobals.end() ? nullptr : It->second; 1626 } 1627 addClass(std::unique_ptr<Record> R)1628 void addClass(std::unique_ptr<Record> R) { 1629 bool Ins = Classes.insert(std::make_pair(R->getName(), 1630 std::move(R))).second; 1631 (void)Ins; 1632 assert(Ins && "Class already exists"); 1633 } 1634 addDef(std::unique_ptr<Record> R)1635 void addDef(std::unique_ptr<Record> R) { 1636 bool Ins = Defs.insert(std::make_pair(R->getName(), 1637 std::move(R))).second; 1638 (void)Ins; 1639 assert(Ins && "Record already exists"); 1640 } 1641 addExtraGlobal(StringRef Name,Init * I)1642 void addExtraGlobal(StringRef Name, Init *I) { 1643 bool Ins = ExtraGlobals.insert(std::make_pair(Name, I)).second; 1644 (void)Ins; 1645 assert(!getDef(Name)); 1646 assert(Ins && "Global already exists"); 1647 } 1648 1649 Init *getNewAnonymousName(); 1650 1651 //===--------------------------------------------------------------------===// 1652 // High-level helper methods, useful for tablegen backends... 1653 1654 /// This method returns all concrete definitions 1655 /// that derive from the specified class name. A class with the specified 1656 /// name must exist. 1657 std::vector<Record *> getAllDerivedDefinitions(StringRef ClassName) const; 1658 1659 void dump() const; 1660 }; 1661 1662 /// Sorting predicate to sort record pointers by name. 1663 struct LessRecord { operatorLessRecord1664 bool operator()(const Record *Rec1, const Record *Rec2) const { 1665 return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0; 1666 } 1667 }; 1668 1669 /// Sorting predicate to sort record pointers by their 1670 /// unique ID. If you just need a deterministic order, use this, since it 1671 /// just compares two `unsigned`; the other sorting predicates require 1672 /// string manipulation. 1673 struct LessRecordByID { operatorLessRecordByID1674 bool operator()(const Record *LHS, const Record *RHS) const { 1675 return LHS->getID() < RHS->getID(); 1676 } 1677 }; 1678 1679 /// Sorting predicate to sort record pointers by their 1680 /// name field. 1681 struct LessRecordFieldName { operatorLessRecordFieldName1682 bool operator()(const Record *Rec1, const Record *Rec2) const { 1683 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); 1684 } 1685 }; 1686 1687 struct LessRecordRegister { ascii_isdigitLessRecordRegister1688 static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; } 1689 1690 struct RecordParts { 1691 SmallVector<std::pair< bool, StringRef>, 4> Parts; 1692 RecordPartsLessRecordRegister::RecordParts1693 RecordParts(StringRef Rec) { 1694 if (Rec.empty()) 1695 return; 1696 1697 size_t Len = 0; 1698 const char *Start = Rec.data(); 1699 const char *Curr = Start; 1700 bool isDigitPart = ascii_isdigit(Curr[0]); 1701 for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) { 1702 bool isDigit = ascii_isdigit(Curr[I]); 1703 if (isDigit != isDigitPart) { 1704 Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len))); 1705 Len = 0; 1706 Start = &Curr[I]; 1707 isDigitPart = ascii_isdigit(Curr[I]); 1708 } 1709 } 1710 // Push the last part. 1711 Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len))); 1712 } 1713 sizeLessRecordRegister::RecordParts1714 size_t size() { return Parts.size(); } 1715 getPartLessRecordRegister::RecordParts1716 std::pair<bool, StringRef> getPart(size_t i) { 1717 assert (i < Parts.size() && "Invalid idx!"); 1718 return Parts[i]; 1719 } 1720 }; 1721 operatorLessRecordRegister1722 bool operator()(const Record *Rec1, const Record *Rec2) const { 1723 RecordParts LHSParts(StringRef(Rec1->getName())); 1724 RecordParts RHSParts(StringRef(Rec2->getName())); 1725 1726 size_t LHSNumParts = LHSParts.size(); 1727 size_t RHSNumParts = RHSParts.size(); 1728 assert (LHSNumParts && RHSNumParts && "Expected at least one part!"); 1729 1730 if (LHSNumParts != RHSNumParts) 1731 return LHSNumParts < RHSNumParts; 1732 1733 // We expect the registers to be of the form [_a-zA-Z]+([0-9]*[_a-zA-Z]*)*. 1734 for (size_t I = 0, E = LHSNumParts; I < E; I+=2) { 1735 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I); 1736 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I); 1737 // Expect even part to always be alpha. 1738 assert (LHSPart.first == false && RHSPart.first == false && 1739 "Expected both parts to be alpha."); 1740 if (int Res = LHSPart.second.compare(RHSPart.second)) 1741 return Res < 0; 1742 } 1743 for (size_t I = 1, E = LHSNumParts; I < E; I+=2) { 1744 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I); 1745 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I); 1746 // Expect odd part to always be numeric. 1747 assert (LHSPart.first == true && RHSPart.first == true && 1748 "Expected both parts to be numeric."); 1749 if (LHSPart.second.size() != RHSPart.second.size()) 1750 return LHSPart.second.size() < RHSPart.second.size(); 1751 1752 unsigned LHSVal, RHSVal; 1753 1754 bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed; 1755 assert(!LHSFailed && "Unable to convert LHS to integer."); 1756 bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed; 1757 assert(!RHSFailed && "Unable to convert RHS to integer."); 1758 1759 if (LHSVal != RHSVal) 1760 return LHSVal < RHSVal; 1761 } 1762 return LHSNumParts < RHSNumParts; 1763 } 1764 }; 1765 1766 raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK); 1767 1768 //===----------------------------------------------------------------------===// 1769 // Resolvers 1770 //===----------------------------------------------------------------------===// 1771 1772 /// Interface for looking up the initializer for a variable name, used by 1773 /// Init::resolveReferences. 1774 class Resolver { 1775 Record *CurRec; 1776 bool IsFinal = false; 1777 1778 public: Resolver(Record * CurRec)1779 explicit Resolver(Record *CurRec) : CurRec(CurRec) {} ~Resolver()1780 virtual ~Resolver() {} 1781 getCurrentRecord()1782 Record *getCurrentRecord() const { return CurRec; } 1783 1784 /// Return the initializer for the given variable name (should normally be a 1785 /// StringInit), or nullptr if the name could not be resolved. 1786 virtual Init *resolve(Init *VarName) = 0; 1787 1788 // Whether bits in a BitsInit should stay unresolved if resolving them would 1789 // result in a ? (UnsetInit). This behavior is used to represent instruction 1790 // encodings by keeping references to unset variables within a record. keepUnsetBits()1791 virtual bool keepUnsetBits() const { return false; } 1792 1793 // Whether this is the final resolve step before adding a record to the 1794 // RecordKeeper. Error reporting during resolve and related constant folding 1795 // should only happen when this is true. isFinal()1796 bool isFinal() const { return IsFinal; } 1797 setFinal(bool Final)1798 void setFinal(bool Final) { IsFinal = Final; } 1799 }; 1800 1801 /// Resolve arbitrary mappings. 1802 class MapResolver final : public Resolver { 1803 struct MappedValue { 1804 Init *V; 1805 bool Resolved; 1806 MappedValueMappedValue1807 MappedValue() : V(nullptr), Resolved(false) {} MappedValueMappedValue1808 MappedValue(Init *V, bool Resolved) : V(V), Resolved(Resolved) {} 1809 }; 1810 1811 DenseMap<Init *, MappedValue> Map; 1812 1813 public: Resolver(CurRec)1814 explicit MapResolver(Record *CurRec = nullptr) : Resolver(CurRec) {} 1815 set(Init * Key,Init * Value)1816 void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; } 1817 1818 Init *resolve(Init *VarName) override; 1819 }; 1820 1821 /// Resolve all variables from a record except for unset variables. 1822 class RecordResolver final : public Resolver { 1823 DenseMap<Init *, Init *> Cache; 1824 SmallVector<Init *, 4> Stack; 1825 1826 public: RecordResolver(Record & R)1827 explicit RecordResolver(Record &R) : Resolver(&R) {} 1828 1829 Init *resolve(Init *VarName) override; 1830 keepUnsetBits()1831 bool keepUnsetBits() const override { return true; } 1832 }; 1833 1834 /// Resolve all references to a specific RecordVal. 1835 // 1836 // TODO: This is used for resolving references to template arguments, in a 1837 // rather inefficient way. Change those uses to resolve all template 1838 // arguments simultaneously and get rid of this class. 1839 class RecordValResolver final : public Resolver { 1840 const RecordVal *RV; 1841 1842 public: RecordValResolver(Record & R,const RecordVal * RV)1843 explicit RecordValResolver(Record &R, const RecordVal *RV) 1844 : Resolver(&R), RV(RV) {} 1845 resolve(Init * VarName)1846 Init *resolve(Init *VarName) override { 1847 if (VarName == RV->getNameInit()) 1848 return RV->getValue(); 1849 return nullptr; 1850 } 1851 }; 1852 1853 /// Delegate resolving to a sub-resolver, but shadow some variable names. 1854 class ShadowResolver final : public Resolver { 1855 Resolver &R; 1856 DenseSet<Init *> Shadowed; 1857 1858 public: ShadowResolver(Resolver & R)1859 explicit ShadowResolver(Resolver &R) 1860 : Resolver(R.getCurrentRecord()), R(R) { 1861 setFinal(R.isFinal()); 1862 } 1863 addShadow(Init * Key)1864 void addShadow(Init *Key) { Shadowed.insert(Key); } 1865 resolve(Init * VarName)1866 Init *resolve(Init *VarName) override { 1867 if (Shadowed.count(VarName)) 1868 return nullptr; 1869 return R.resolve(VarName); 1870 } 1871 }; 1872 1873 /// (Optionally) delegate resolving to a sub-resolver, and keep track whether 1874 /// there were unresolved references. 1875 class TrackUnresolvedResolver final : public Resolver { 1876 Resolver *R; 1877 bool FoundUnresolved = false; 1878 1879 public: 1880 explicit TrackUnresolvedResolver(Resolver *R = nullptr) 1881 : Resolver(R ? R->getCurrentRecord() : nullptr), R(R) {} 1882 foundUnresolved()1883 bool foundUnresolved() const { return FoundUnresolved; } 1884 1885 Init *resolve(Init *VarName) override; 1886 }; 1887 1888 /// Do not resolve anything, but keep track of whether a given variable was 1889 /// referenced. 1890 class HasReferenceResolver final : public Resolver { 1891 Init *VarNameToTrack; 1892 bool Found = false; 1893 1894 public: HasReferenceResolver(Init * VarNameToTrack)1895 explicit HasReferenceResolver(Init *VarNameToTrack) 1896 : Resolver(nullptr), VarNameToTrack(VarNameToTrack) {} 1897 found()1898 bool found() const { return Found; } 1899 1900 Init *resolve(Init *VarName) override; 1901 }; 1902 1903 void EmitJSON(RecordKeeper &RK, raw_ostream &OS); 1904 1905 } // end namespace llvm 1906 1907 #endif // LLVM_TABLEGEN_RECORD_H 1908