File indexing completed on 2026-05-10 08:44:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_TABLEGEN_RECORD_H
0015 #define LLVM_TABLEGEN_RECORD_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/DenseSet.h"
0020 #include "llvm/ADT/FoldingSet.h"
0021 #include "llvm/ADT/PointerIntPair.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include "llvm/ADT/StringExtras.h"
0024 #include "llvm/ADT/StringRef.h"
0025 #include "llvm/Support/Casting.h"
0026 #include "llvm/Support/ErrorHandling.h"
0027 #include "llvm/Support/SMLoc.h"
0028 #include "llvm/Support/Timer.h"
0029 #include "llvm/Support/TrailingObjects.h"
0030 #include "llvm/Support/raw_ostream.h"
0031 #include <cassert>
0032 #include <cstddef>
0033 #include <cstdint>
0034 #include <map>
0035 #include <memory>
0036 #include <optional>
0037 #include <string>
0038 #include <utility>
0039 #include <variant>
0040 #include <vector>
0041
0042 namespace llvm {
0043 namespace detail {
0044 struct RecordKeeperImpl;
0045 }
0046
0047 class ListRecTy;
0048 class Record;
0049 class RecordKeeper;
0050 class RecordVal;
0051 class Resolver;
0052 class StringInit;
0053 class TypedInit;
0054 class TGTimer;
0055
0056
0057
0058
0059
0060 class RecTy {
0061 public:
0062
0063 enum RecTyKind {
0064 BitRecTyKind,
0065 BitsRecTyKind,
0066 IntRecTyKind,
0067 StringRecTyKind,
0068 ListRecTyKind,
0069 DagRecTyKind,
0070 RecordRecTyKind
0071 };
0072
0073 private:
0074 RecTyKind Kind;
0075
0076 RecordKeeper &RK;
0077
0078
0079 mutable const ListRecTy *ListTy = nullptr;
0080
0081 public:
0082 RecTy(RecTyKind K, RecordKeeper &RK) : Kind(K), RK(RK) {}
0083 virtual ~RecTy() = default;
0084
0085 RecTyKind getRecTyKind() const { return Kind; }
0086
0087
0088 RecordKeeper &getRecordKeeper() const { return RK; }
0089
0090 virtual std::string getAsString() const = 0;
0091 void print(raw_ostream &OS) const { OS << getAsString(); }
0092 void dump() const;
0093
0094
0095
0096 virtual bool typeIsConvertibleTo(const RecTy *RHS) const;
0097
0098
0099
0100 virtual bool typeIsA(const RecTy *RHS) const;
0101
0102
0103 const ListRecTy *getListTy() const;
0104 };
0105
0106 inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
0107 Ty.print(OS);
0108 return OS;
0109 }
0110
0111
0112 class BitRecTy : public RecTy {
0113 friend detail::RecordKeeperImpl;
0114
0115 BitRecTy(RecordKeeper &RK) : RecTy(BitRecTyKind, RK) {}
0116
0117 public:
0118 static bool classof(const RecTy *RT) {
0119 return RT->getRecTyKind() == BitRecTyKind;
0120 }
0121
0122 static const BitRecTy *get(RecordKeeper &RK);
0123
0124 std::string getAsString() const override { return "bit"; }
0125
0126 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0127 };
0128
0129
0130 class BitsRecTy : public RecTy {
0131 unsigned Size;
0132
0133 explicit BitsRecTy(RecordKeeper &RK, unsigned Sz)
0134 : RecTy(BitsRecTyKind, RK), Size(Sz) {}
0135
0136 public:
0137 static bool classof(const RecTy *RT) {
0138 return RT->getRecTyKind() == BitsRecTyKind;
0139 }
0140
0141 static const BitsRecTy *get(RecordKeeper &RK, unsigned Sz);
0142
0143 unsigned getNumBits() const { return Size; }
0144
0145 std::string getAsString() const override;
0146
0147 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0148 };
0149
0150
0151 class IntRecTy : public RecTy {
0152 friend detail::RecordKeeperImpl;
0153
0154 IntRecTy(RecordKeeper &RK) : RecTy(IntRecTyKind, RK) {}
0155
0156 public:
0157 static bool classof(const RecTy *RT) {
0158 return RT->getRecTyKind() == IntRecTyKind;
0159 }
0160
0161 static const IntRecTy *get(RecordKeeper &RK);
0162
0163 std::string getAsString() const override { return "int"; }
0164
0165 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0166 };
0167
0168
0169 class StringRecTy : public RecTy {
0170 friend detail::RecordKeeperImpl;
0171
0172 StringRecTy(RecordKeeper &RK) : RecTy(StringRecTyKind, RK) {}
0173
0174 public:
0175 static bool classof(const RecTy *RT) {
0176 return RT->getRecTyKind() == StringRecTyKind;
0177 }
0178
0179 static const StringRecTy *get(RecordKeeper &RK);
0180
0181 std::string getAsString() const override;
0182
0183 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0184 };
0185
0186
0187
0188 class ListRecTy : public RecTy {
0189 friend const ListRecTy *RecTy::getListTy() const;
0190
0191 const RecTy *ElementTy;
0192
0193 explicit ListRecTy(const RecTy *T)
0194 : RecTy(ListRecTyKind, T->getRecordKeeper()), ElementTy(T) {}
0195
0196 public:
0197 static bool classof(const RecTy *RT) {
0198 return RT->getRecTyKind() == ListRecTyKind;
0199 }
0200
0201 static const ListRecTy *get(const RecTy *T) { return T->getListTy(); }
0202 const RecTy *getElementType() const { return ElementTy; }
0203
0204 std::string getAsString() const override;
0205
0206 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0207
0208 bool typeIsA(const RecTy *RHS) const override;
0209 };
0210
0211
0212 class DagRecTy : public RecTy {
0213 friend detail::RecordKeeperImpl;
0214
0215 DagRecTy(RecordKeeper &RK) : RecTy(DagRecTyKind, RK) {}
0216
0217 public:
0218 static bool classof(const RecTy *RT) {
0219 return RT->getRecTyKind() == DagRecTyKind;
0220 }
0221
0222 static const DagRecTy *get(RecordKeeper &RK);
0223
0224 std::string getAsString() const override;
0225 };
0226
0227
0228
0229
0230
0231 class RecordRecTy final : public RecTy,
0232 public FoldingSetNode,
0233 public TrailingObjects<RecordRecTy, const Record *> {
0234 friend class Record;
0235 friend detail::RecordKeeperImpl;
0236
0237 unsigned NumClasses;
0238
0239 explicit RecordRecTy(RecordKeeper &RK, unsigned Num)
0240 : RecTy(RecordRecTyKind, RK), NumClasses(Num) {}
0241
0242 public:
0243 RecordRecTy(const RecordRecTy &) = delete;
0244 RecordRecTy &operator=(const RecordRecTy &) = delete;
0245
0246
0247 void operator delete(void *p) { ::operator delete(p); }
0248
0249 static bool classof(const RecTy *RT) {
0250 return RT->getRecTyKind() == RecordRecTyKind;
0251 }
0252
0253
0254 static const RecordRecTy *get(RecordKeeper &RK,
0255 ArrayRef<const Record *> Classes);
0256 static const RecordRecTy *get(const Record *Class);
0257
0258 void Profile(FoldingSetNodeID &ID) const;
0259
0260 ArrayRef<const Record *> getClasses() const {
0261 return ArrayRef(getTrailingObjects<const Record *>(), NumClasses);
0262 }
0263
0264 using const_record_iterator = const Record *const *;
0265
0266 const_record_iterator classes_begin() const { return getClasses().begin(); }
0267 const_record_iterator classes_end() const { return getClasses().end(); }
0268
0269 std::string getAsString() const override;
0270
0271 bool isSubClassOf(const Record *Class) const;
0272 bool typeIsConvertibleTo(const RecTy *RHS) const override;
0273
0274 bool typeIsA(const RecTy *RHS) const override;
0275 };
0276
0277
0278
0279 const RecTy *resolveTypes(const RecTy *T1, const RecTy *T2);
0280
0281
0282
0283
0284
0285 class Init {
0286 protected:
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 enum InitKind : uint8_t {
0301 IK_First,
0302 IK_FirstTypedInit,
0303 IK_BitInit,
0304 IK_BitsInit,
0305 IK_DagInit,
0306 IK_DefInit,
0307 IK_FieldInit,
0308 IK_IntInit,
0309 IK_ListInit,
0310 IK_FirstOpInit,
0311 IK_BinOpInit,
0312 IK_TernOpInit,
0313 IK_UnOpInit,
0314 IK_LastOpInit,
0315 IK_CondOpInit,
0316 IK_FoldOpInit,
0317 IK_IsAOpInit,
0318 IK_ExistsOpInit,
0319 IK_AnonymousNameInit,
0320 IK_StringInit,
0321 IK_VarInit,
0322 IK_VarBitInit,
0323 IK_VarDefInit,
0324 IK_LastTypedInit,
0325 IK_UnsetInit,
0326 IK_ArgumentInit,
0327 };
0328
0329 private:
0330 const InitKind Kind;
0331
0332 protected:
0333 uint8_t Opc;
0334
0335 private:
0336 virtual void anchor();
0337
0338 public:
0339
0340 InitKind getKind() const { return Kind; }
0341
0342
0343 RecordKeeper &getRecordKeeper() const;
0344
0345 protected:
0346 explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {}
0347
0348 public:
0349 Init(const Init &) = delete;
0350 Init &operator=(const Init &) = delete;
0351 virtual ~Init() = default;
0352
0353
0354 virtual bool isComplete() const { return true; }
0355
0356
0357
0358 virtual bool isConcrete() const { return false; }
0359
0360
0361 void print(raw_ostream &OS) const { OS << getAsString(); }
0362
0363
0364 virtual std::string getAsString() const = 0;
0365
0366
0367
0368 virtual std::string getAsUnquotedString() const { return getAsString(); }
0369
0370
0371
0372 void dump() const;
0373
0374
0375
0376
0377 virtual const Init *getCastTo(const RecTy *Ty) const = 0;
0378
0379
0380
0381
0382 virtual const Init *convertInitializerTo(const RecTy *Ty) const = 0;
0383
0384
0385
0386
0387
0388 virtual const Init *
0389 convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
0390 return nullptr;
0391 }
0392
0393
0394
0395
0396 virtual const RecTy *getFieldType(const StringInit *FieldName) const {
0397 return nullptr;
0398 }
0399
0400
0401
0402
0403
0404 virtual const Init *resolveReferences(Resolver &R) const { return this; }
0405
0406
0407 virtual const Init *getBit(unsigned Bit) const = 0;
0408 };
0409
0410 inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
0411 I.print(OS); return OS;
0412 }
0413
0414
0415
0416 class TypedInit : public Init {
0417 const RecTy *ValueTy;
0418
0419 protected:
0420 explicit TypedInit(InitKind K, const RecTy *T, uint8_t Opc = 0)
0421 : Init(K, Opc), ValueTy(T) {}
0422
0423 public:
0424 TypedInit(const TypedInit &) = delete;
0425 TypedInit &operator=(const TypedInit &) = delete;
0426
0427 static bool classof(const Init *I) {
0428 return I->getKind() >= IK_FirstTypedInit &&
0429 I->getKind() <= IK_LastTypedInit;
0430 }
0431
0432
0433 const RecTy *getType() const { return ValueTy; }
0434
0435
0436 RecordKeeper &getRecordKeeper() const { return ValueTy->getRecordKeeper(); }
0437
0438 const Init *getCastTo(const RecTy *Ty) const override;
0439 const Init *convertInitializerTo(const RecTy *Ty) const override;
0440
0441 const Init *
0442 convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
0443
0444
0445
0446
0447 const RecTy *getFieldType(const StringInit *FieldName) const override;
0448 };
0449
0450
0451 class UnsetInit final : public Init {
0452 friend detail::RecordKeeperImpl;
0453
0454
0455 RecordKeeper &RK;
0456
0457 UnsetInit(RecordKeeper &RK) : Init(IK_UnsetInit), RK(RK) {}
0458
0459 public:
0460 UnsetInit(const UnsetInit &) = delete;
0461 UnsetInit &operator=(const UnsetInit &) = delete;
0462
0463 static bool classof(const Init *I) {
0464 return I->getKind() == IK_UnsetInit;
0465 }
0466
0467
0468 static UnsetInit *get(RecordKeeper &RK);
0469
0470
0471 RecordKeeper &getRecordKeeper() const { return RK; }
0472
0473 const Init *getCastTo(const RecTy *Ty) const override;
0474 const Init *convertInitializerTo(const RecTy *Ty) const override;
0475
0476 const Init *getBit(unsigned Bit) const override { return this; }
0477
0478
0479 bool isComplete() const override { return false; }
0480
0481 bool isConcrete() const override { return true; }
0482
0483
0484 std::string getAsString() const override { return "?"; }
0485 };
0486
0487
0488 using ArgAuxType = std::variant<unsigned, const Init *>;
0489 class ArgumentInit final : public Init, public FoldingSetNode {
0490 public:
0491 enum Kind {
0492 Positional,
0493 Named,
0494 };
0495
0496 private:
0497 const Init *Value;
0498 ArgAuxType Aux;
0499
0500 protected:
0501 explicit ArgumentInit(const Init *Value, ArgAuxType Aux)
0502 : Init(IK_ArgumentInit), Value(Value), Aux(Aux) {}
0503
0504 public:
0505 ArgumentInit(const ArgumentInit &) = delete;
0506 ArgumentInit &operator=(const ArgumentInit &) = delete;
0507
0508 static bool classof(const Init *I) { return I->getKind() == IK_ArgumentInit; }
0509
0510 RecordKeeper &getRecordKeeper() const { return Value->getRecordKeeper(); }
0511
0512 static const ArgumentInit *get(const Init *Value, ArgAuxType Aux);
0513
0514 bool isPositional() const { return Aux.index() == Positional; }
0515 bool isNamed() const { return Aux.index() == Named; }
0516
0517 const Init *getValue() const { return Value; }
0518 unsigned getIndex() const {
0519 assert(isPositional() && "Should be positional!");
0520 return std::get<Positional>(Aux);
0521 }
0522 const Init *getName() const {
0523 assert(isNamed() && "Should be named!");
0524 return std::get<Named>(Aux);
0525 }
0526 const ArgumentInit *cloneWithValue(const Init *Value) const {
0527 return get(Value, Aux);
0528 }
0529
0530 void Profile(FoldingSetNodeID &ID) const;
0531
0532 const Init *resolveReferences(Resolver &R) const override;
0533 std::string getAsString() const override {
0534 if (isPositional())
0535 return utostr(getIndex()) + ": " + Value->getAsString();
0536 if (isNamed())
0537 return getName()->getAsString() + ": " + Value->getAsString();
0538 llvm_unreachable("Unsupported argument type!");
0539 return "";
0540 }
0541
0542 bool isComplete() const override { return false; }
0543 bool isConcrete() const override { return false; }
0544 const Init *getBit(unsigned Bit) const override { return Value->getBit(Bit); }
0545 const Init *getCastTo(const RecTy *Ty) const override {
0546 return Value->getCastTo(Ty);
0547 }
0548 const Init *convertInitializerTo(const RecTy *Ty) const override {
0549 return Value->convertInitializerTo(Ty);
0550 }
0551 };
0552
0553
0554 class BitInit final : public TypedInit {
0555 friend detail::RecordKeeperImpl;
0556
0557 bool Value;
0558
0559 explicit BitInit(bool V, const RecTy *T)
0560 : TypedInit(IK_BitInit, T), Value(V) {}
0561
0562 public:
0563 BitInit(const BitInit &) = delete;
0564 BitInit &operator=(BitInit &) = delete;
0565
0566 static bool classof(const Init *I) {
0567 return I->getKind() == IK_BitInit;
0568 }
0569
0570 static BitInit *get(RecordKeeper &RK, bool V);
0571
0572 bool getValue() const { return Value; }
0573
0574 const Init *convertInitializerTo(const RecTy *Ty) const override;
0575
0576 const Init *getBit(unsigned Bit) const override {
0577 assert(Bit < 1 && "Bit index out of range!");
0578 return this;
0579 }
0580
0581 bool isConcrete() const override { return true; }
0582 std::string getAsString() const override { return Value ? "1" : "0"; }
0583 };
0584
0585
0586
0587 class BitsInit final : public TypedInit,
0588 public FoldingSetNode,
0589 public TrailingObjects<BitsInit, const Init *> {
0590 unsigned NumBits;
0591
0592 BitsInit(RecordKeeper &RK, unsigned N)
0593 : TypedInit(IK_BitsInit, BitsRecTy::get(RK, N)), NumBits(N) {}
0594
0595 public:
0596 BitsInit(const BitsInit &) = delete;
0597 BitsInit &operator=(const BitsInit &) = delete;
0598
0599
0600 void operator delete(void *p) { ::operator delete(p); }
0601
0602 static bool classof(const Init *I) {
0603 return I->getKind() == IK_BitsInit;
0604 }
0605
0606 static BitsInit *get(RecordKeeper &RK, ArrayRef<const Init *> Range);
0607
0608 void Profile(FoldingSetNodeID &ID) const;
0609
0610 unsigned getNumBits() const { return NumBits; }
0611
0612 const Init *convertInitializerTo(const RecTy *Ty) const override;
0613 const Init *
0614 convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
0615 std::optional<int64_t> convertInitializerToInt() const;
0616
0617 bool isComplete() const override {
0618 for (unsigned i = 0; i != getNumBits(); ++i)
0619 if (!getBit(i)->isComplete()) return false;
0620 return true;
0621 }
0622
0623 bool allInComplete() const {
0624 for (unsigned i = 0; i != getNumBits(); ++i)
0625 if (getBit(i)->isComplete()) return false;
0626 return true;
0627 }
0628
0629 bool isConcrete() const override;
0630 std::string getAsString() const override;
0631
0632 const Init *resolveReferences(Resolver &R) const override;
0633
0634 const Init *getBit(unsigned Bit) const override {
0635 assert(Bit < NumBits && "Bit index out of range!");
0636 return getTrailingObjects<const Init *>()[Bit];
0637 }
0638 };
0639
0640
0641 class IntInit final : public TypedInit {
0642 int64_t Value;
0643
0644 explicit IntInit(RecordKeeper &RK, int64_t V)
0645 : TypedInit(IK_IntInit, IntRecTy::get(RK)), Value(V) {}
0646
0647 public:
0648 IntInit(const IntInit &) = delete;
0649 IntInit &operator=(const IntInit &) = delete;
0650
0651 static bool classof(const Init *I) {
0652 return I->getKind() == IK_IntInit;
0653 }
0654
0655 static IntInit *get(RecordKeeper &RK, int64_t V);
0656
0657 int64_t getValue() const { return Value; }
0658
0659 const Init *convertInitializerTo(const RecTy *Ty) const override;
0660 const Init *
0661 convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
0662
0663 bool isConcrete() const override { return true; }
0664 std::string getAsString() const override;
0665
0666 const Init *getBit(unsigned Bit) const override {
0667 return BitInit::get(getRecordKeeper(), (Value & (1ULL << Bit)) != 0);
0668 }
0669 };
0670
0671
0672 class AnonymousNameInit final : public TypedInit {
0673 unsigned Value;
0674
0675 explicit AnonymousNameInit(RecordKeeper &RK, unsigned V)
0676 : TypedInit(IK_AnonymousNameInit, StringRecTy::get(RK)), Value(V) {}
0677
0678 public:
0679 AnonymousNameInit(const AnonymousNameInit &) = delete;
0680 AnonymousNameInit &operator=(const AnonymousNameInit &) = delete;
0681
0682 static bool classof(const Init *I) {
0683 return I->getKind() == IK_AnonymousNameInit;
0684 }
0685
0686 static AnonymousNameInit *get(RecordKeeper &RK, unsigned);
0687
0688 unsigned getValue() const { return Value; }
0689
0690 const StringInit *getNameInit() const;
0691
0692 std::string getAsString() const override;
0693
0694 const Init *resolveReferences(Resolver &R) const override;
0695
0696 const Init *getBit(unsigned Bit) const override {
0697 llvm_unreachable("Illegal bit reference off string");
0698 }
0699 };
0700
0701
0702 class StringInit final : public TypedInit {
0703 public:
0704 enum StringFormat {
0705 SF_String,
0706 SF_Code,
0707 };
0708
0709 private:
0710 StringRef Value;
0711 StringFormat Format;
0712
0713 explicit StringInit(RecordKeeper &RK, StringRef V, StringFormat Fmt)
0714 : TypedInit(IK_StringInit, StringRecTy::get(RK)), Value(V), Format(Fmt) {}
0715
0716 public:
0717 StringInit(const StringInit &) = delete;
0718 StringInit &operator=(const StringInit &) = delete;
0719
0720 static bool classof(const Init *I) {
0721 return I->getKind() == IK_StringInit;
0722 }
0723
0724 static const StringInit *get(RecordKeeper &RK, StringRef,
0725 StringFormat Fmt = SF_String);
0726
0727 static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) {
0728 return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String;
0729 }
0730
0731 StringRef getValue() const { return Value; }
0732 StringFormat getFormat() const { return Format; }
0733 bool hasCodeFormat() const { return Format == SF_Code; }
0734
0735 const Init *convertInitializerTo(const RecTy *Ty) const override;
0736
0737 bool isConcrete() const override { return true; }
0738
0739 std::string getAsString() const override {
0740 if (Format == SF_String)
0741 return "\"" + Value.str() + "\"";
0742 else
0743 return "[{" + Value.str() + "}]";
0744 }
0745
0746 std::string getAsUnquotedString() const override {
0747 return std::string(Value);
0748 }
0749
0750 const Init *getBit(unsigned Bit) const override {
0751 llvm_unreachable("Illegal bit reference off string");
0752 }
0753 };
0754
0755
0756
0757 class ListInit final : public TypedInit,
0758 public FoldingSetNode,
0759 public TrailingObjects<ListInit, const Init *> {
0760 unsigned NumValues;
0761
0762 public:
0763 using const_iterator = const Init *const *;
0764
0765 private:
0766 explicit ListInit(unsigned N, const RecTy *EltTy)
0767 : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {}
0768
0769 public:
0770 ListInit(const ListInit &) = delete;
0771 ListInit &operator=(const ListInit &) = delete;
0772
0773
0774 void operator delete(void *p) { ::operator delete(p); }
0775
0776 static bool classof(const Init *I) {
0777 return I->getKind() == IK_ListInit;
0778 }
0779 static const ListInit *get(ArrayRef<const Init *> Range, const RecTy *EltTy);
0780
0781 void Profile(FoldingSetNodeID &ID) const;
0782
0783 const Init *getElement(unsigned i) const {
0784 assert(i < NumValues && "List element index out of range!");
0785 return getTrailingObjects<const Init *>()[i];
0786 }
0787 const RecTy *getElementType() const {
0788 return cast<ListRecTy>(getType())->getElementType();
0789 }
0790
0791 const Record *getElementAsRecord(unsigned i) const;
0792
0793 const Init *convertInitializerTo(const RecTy *Ty) const override;
0794
0795
0796
0797
0798
0799
0800 const Init *resolveReferences(Resolver &R) const override;
0801
0802 bool isComplete() const override;
0803 bool isConcrete() const override;
0804 std::string getAsString() const override;
0805
0806 ArrayRef<const Init *> getValues() const {
0807 return ArrayRef(getTrailingObjects<const Init *>(), NumValues);
0808 }
0809
0810 const_iterator begin() const { return getTrailingObjects<const Init *>(); }
0811 const_iterator end () const { return begin() + NumValues; }
0812
0813 size_t size () const { return NumValues; }
0814 bool empty() const { return NumValues == 0; }
0815
0816 const Init *getBit(unsigned Bit) const override {
0817 llvm_unreachable("Illegal bit reference off list");
0818 }
0819 };
0820
0821
0822
0823 class OpInit : public TypedInit {
0824 protected:
0825 explicit OpInit(InitKind K, const RecTy *Type, uint8_t Opc)
0826 : TypedInit(K, Type, Opc) {}
0827
0828 public:
0829 OpInit(const OpInit &) = delete;
0830 OpInit &operator=(OpInit &) = delete;
0831
0832 static bool classof(const Init *I) {
0833 return I->getKind() >= IK_FirstOpInit &&
0834 I->getKind() <= IK_LastOpInit;
0835 }
0836
0837 const Init *getBit(unsigned Bit) const final;
0838 };
0839
0840
0841
0842 class UnOpInit final : public OpInit, public FoldingSetNode {
0843 public:
0844 enum UnaryOp : uint8_t {
0845 TOLOWER,
0846 TOUPPER,
0847 CAST,
0848 NOT,
0849 HEAD,
0850 TAIL,
0851 SIZE,
0852 EMPTY,
0853 GETDAGOP,
0854 LOG2,
0855 REPR,
0856 LISTFLATTEN,
0857 INITIALIZED,
0858 };
0859
0860 private:
0861 const Init *LHS;
0862
0863 UnOpInit(UnaryOp opc, const Init *lhs, const RecTy *Type)
0864 : OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {}
0865
0866 public:
0867 UnOpInit(const UnOpInit &) = delete;
0868 UnOpInit &operator=(const UnOpInit &) = delete;
0869
0870 static bool classof(const Init *I) {
0871 return I->getKind() == IK_UnOpInit;
0872 }
0873
0874 static const UnOpInit *get(UnaryOp opc, const Init *lhs, const RecTy *Type);
0875
0876 void Profile(FoldingSetNodeID &ID) const;
0877
0878 UnaryOp getOpcode() const { return (UnaryOp)Opc; }
0879 const Init *getOperand() const { return LHS; }
0880
0881
0882
0883 const Init *Fold(const Record *CurRec, bool IsFinal = false) const;
0884
0885 const Init *resolveReferences(Resolver &R) const override;
0886
0887 std::string getAsString() const override;
0888 };
0889
0890
0891 class BinOpInit final : public OpInit, public FoldingSetNode {
0892 public:
0893 enum BinaryOp : uint8_t {
0894 ADD,
0895 SUB,
0896 MUL,
0897 DIV,
0898 AND,
0899 OR,
0900 XOR,
0901 SHL,
0902 SRA,
0903 SRL,
0904 LISTCONCAT,
0905 LISTSPLAT,
0906 LISTREMOVE,
0907 LISTELEM,
0908 LISTSLICE,
0909 RANGEC,
0910 STRCONCAT,
0911 INTERLEAVE,
0912 CONCAT,
0913 EQ,
0914 NE,
0915 LE,
0916 LT,
0917 GE,
0918 GT,
0919 GETDAGARG,
0920 GETDAGNAME,
0921 SETDAGOP,
0922 };
0923
0924 private:
0925 const Init *LHS, *RHS;
0926
0927 BinOpInit(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
0928 : OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {}
0929
0930 public:
0931 BinOpInit(const BinOpInit &) = delete;
0932 BinOpInit &operator=(const BinOpInit &) = delete;
0933
0934 static bool classof(const Init *I) {
0935 return I->getKind() == IK_BinOpInit;
0936 }
0937
0938 static const BinOpInit *get(BinaryOp opc, const Init *lhs, const Init *rhs,
0939 const RecTy *Type);
0940 static const Init *getStrConcat(const Init *lhs, const Init *rhs);
0941 static const Init *getListConcat(const TypedInit *lhs, const Init *rhs);
0942
0943 void Profile(FoldingSetNodeID &ID) const;
0944
0945 BinaryOp getOpcode() const { return (BinaryOp)Opc; }
0946 const Init *getLHS() const { return LHS; }
0947 const Init *getRHS() const { return RHS; }
0948
0949 std::optional<bool> CompareInit(unsigned Opc, const Init *LHS,
0950 const Init *RHS) const;
0951
0952
0953
0954 const Init *Fold(const Record *CurRec) const;
0955
0956 const Init *resolveReferences(Resolver &R) const override;
0957
0958 std::string getAsString() const override;
0959 };
0960
0961
0962 class TernOpInit final : public OpInit, public FoldingSetNode {
0963 public:
0964 enum TernaryOp : uint8_t {
0965 SUBST,
0966 FOREACH,
0967 FILTER,
0968 IF,
0969 DAG,
0970 RANGE,
0971 SUBSTR,
0972 FIND,
0973 SETDAGARG,
0974 SETDAGNAME,
0975 };
0976
0977 private:
0978 const Init *LHS, *MHS, *RHS;
0979
0980 TernOpInit(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs,
0981 const RecTy *Type)
0982 : OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
0983
0984 public:
0985 TernOpInit(const TernOpInit &) = delete;
0986 TernOpInit &operator=(const TernOpInit &) = delete;
0987
0988 static bool classof(const Init *I) {
0989 return I->getKind() == IK_TernOpInit;
0990 }
0991
0992 static const TernOpInit *get(TernaryOp opc, const Init *lhs, const Init *mhs,
0993 const Init *rhs, const RecTy *Type);
0994
0995 void Profile(FoldingSetNodeID &ID) const;
0996
0997 TernaryOp getOpcode() const { return (TernaryOp)Opc; }
0998 const Init *getLHS() const { return LHS; }
0999 const Init *getMHS() const { return MHS; }
1000 const Init *getRHS() const { return RHS; }
1001
1002
1003
1004 const Init *Fold(const Record *CurRec) const;
1005
1006 bool isComplete() const override {
1007 return LHS->isComplete() && MHS->isComplete() && RHS->isComplete();
1008 }
1009
1010 const Init *resolveReferences(Resolver &R) const override;
1011
1012 std::string getAsString() const override;
1013 };
1014
1015
1016
1017
1018 class CondOpInit final : public TypedInit,
1019 public FoldingSetNode,
1020 public TrailingObjects<CondOpInit, const Init *> {
1021 unsigned NumConds;
1022 const RecTy *ValType;
1023
1024 CondOpInit(unsigned NC, const RecTy *Type)
1025 : TypedInit(IK_CondOpInit, Type), NumConds(NC), ValType(Type) {}
1026
1027 size_t numTrailingObjects(OverloadToken<Init *>) const {
1028 return 2*NumConds;
1029 }
1030
1031 public:
1032 CondOpInit(const CondOpInit &) = delete;
1033 CondOpInit &operator=(const CondOpInit &) = delete;
1034
1035 static bool classof(const Init *I) {
1036 return I->getKind() == IK_CondOpInit;
1037 }
1038
1039 static const CondOpInit *get(ArrayRef<const Init *> C,
1040 ArrayRef<const Init *> V, const RecTy *Type);
1041
1042 void Profile(FoldingSetNodeID &ID) const;
1043
1044 const RecTy *getValType() const { return ValType; }
1045
1046 unsigned getNumConds() const { return NumConds; }
1047
1048 const Init *getCond(unsigned Num) const {
1049 assert(Num < NumConds && "Condition number out of range!");
1050 return getTrailingObjects<const Init *>()[Num];
1051 }
1052
1053 const Init *getVal(unsigned Num) const {
1054 assert(Num < NumConds && "Val number out of range!");
1055 return getTrailingObjects<const Init *>()[Num + NumConds];
1056 }
1057
1058 ArrayRef<const Init *> getConds() const {
1059 return ArrayRef(getTrailingObjects<const Init *>(), NumConds);
1060 }
1061
1062 ArrayRef<const Init *> getVals() const {
1063 return ArrayRef(getTrailingObjects<const Init *>() + NumConds, NumConds);
1064 }
1065
1066 const Init *Fold(const Record *CurRec) const;
1067
1068 const Init *resolveReferences(Resolver &R) const override;
1069
1070 bool isConcrete() const override;
1071 bool isComplete() const override;
1072 std::string getAsString() const override;
1073
1074 using const_case_iterator = SmallVectorImpl<const Init *>::const_iterator;
1075 using const_val_iterator = SmallVectorImpl<const Init *>::const_iterator;
1076
1077 inline const_case_iterator arg_begin() const { return getConds().begin(); }
1078 inline const_case_iterator arg_end () const { return getConds().end(); }
1079
1080 inline size_t case_size () const { return NumConds; }
1081 inline bool case_empty() const { return NumConds == 0; }
1082
1083 inline const_val_iterator name_begin() const { return getVals().begin();}
1084 inline const_val_iterator name_end () const { return getVals().end(); }
1085
1086 inline size_t val_size () const { return NumConds; }
1087 inline bool val_empty() const { return NumConds == 0; }
1088
1089 const Init *getBit(unsigned Bit) const override;
1090 };
1091
1092
1093 class FoldOpInit final : public TypedInit, public FoldingSetNode {
1094 private:
1095 const Init *Start, *List, *A, *B, *Expr;
1096
1097 FoldOpInit(const Init *Start, const Init *List, const Init *A, const Init *B,
1098 const Init *Expr, const RecTy *Type)
1099 : TypedInit(IK_FoldOpInit, Type), Start(Start), List(List), A(A), B(B),
1100 Expr(Expr) {}
1101
1102 public:
1103 FoldOpInit(const FoldOpInit &) = delete;
1104 FoldOpInit &operator=(const FoldOpInit &) = delete;
1105
1106 static bool classof(const Init *I) { return I->getKind() == IK_FoldOpInit; }
1107
1108 static const FoldOpInit *get(const Init *Start, const Init *List,
1109 const Init *A, const Init *B, const Init *Expr,
1110 const RecTy *Type);
1111
1112 void Profile(FoldingSetNodeID &ID) const;
1113
1114
1115
1116 const Init *Fold(const Record *CurRec) const;
1117
1118 bool isComplete() const override { return false; }
1119
1120 const Init *resolveReferences(Resolver &R) const override;
1121
1122 const Init *getBit(unsigned Bit) const override;
1123
1124 std::string getAsString() const override;
1125 };
1126
1127
1128 class IsAOpInit final : public TypedInit, public FoldingSetNode {
1129 private:
1130 const RecTy *CheckType;
1131 const Init *Expr;
1132
1133 IsAOpInit(const RecTy *CheckType, const Init *Expr)
1134 : TypedInit(IK_IsAOpInit, IntRecTy::get(CheckType->getRecordKeeper())),
1135 CheckType(CheckType), Expr(Expr) {}
1136
1137 public:
1138 IsAOpInit(const IsAOpInit &) = delete;
1139 IsAOpInit &operator=(const IsAOpInit &) = delete;
1140
1141 static bool classof(const Init *I) { return I->getKind() == IK_IsAOpInit; }
1142
1143 static const IsAOpInit *get(const RecTy *CheckType, const Init *Expr);
1144
1145 void Profile(FoldingSetNodeID &ID) const;
1146
1147
1148
1149 const Init *Fold() const;
1150
1151 bool isComplete() const override { return false; }
1152
1153 const Init *resolveReferences(Resolver &R) const override;
1154
1155 const Init *getBit(unsigned Bit) const override;
1156
1157 std::string getAsString() const override;
1158 };
1159
1160
1161
1162 class ExistsOpInit final : public TypedInit, public FoldingSetNode {
1163 private:
1164 const RecTy *CheckType;
1165 const Init *Expr;
1166
1167 ExistsOpInit(const RecTy *CheckType, const Init *Expr)
1168 : TypedInit(IK_ExistsOpInit, IntRecTy::get(CheckType->getRecordKeeper())),
1169 CheckType(CheckType), Expr(Expr) {}
1170
1171 public:
1172 ExistsOpInit(const ExistsOpInit &) = delete;
1173 ExistsOpInit &operator=(const ExistsOpInit &) = delete;
1174
1175 static bool classof(const Init *I) { return I->getKind() == IK_ExistsOpInit; }
1176
1177 static const ExistsOpInit *get(const RecTy *CheckType, const Init *Expr);
1178
1179 void Profile(FoldingSetNodeID &ID) const;
1180
1181
1182
1183 const Init *Fold(const Record *CurRec, bool IsFinal = false) const;
1184
1185 bool isComplete() const override { return false; }
1186
1187 const Init *resolveReferences(Resolver &R) const override;
1188
1189 const Init *getBit(unsigned Bit) const override;
1190
1191 std::string getAsString() const override;
1192 };
1193
1194
1195 class VarInit final : public TypedInit {
1196 const Init *VarName;
1197
1198 explicit VarInit(const Init *VN, const RecTy *T)
1199 : TypedInit(IK_VarInit, T), VarName(VN) {}
1200
1201 public:
1202 VarInit(const VarInit &) = delete;
1203 VarInit &operator=(const VarInit &) = delete;
1204
1205 static bool classof(const Init *I) {
1206 return I->getKind() == IK_VarInit;
1207 }
1208
1209 static const VarInit *get(StringRef VN, const RecTy *T);
1210 static const VarInit *get(const Init *VN, const RecTy *T);
1211
1212 StringRef getName() const;
1213 const Init *getNameInit() const { return VarName; }
1214
1215 std::string getNameInitAsString() const {
1216 return getNameInit()->getAsUnquotedString();
1217 }
1218
1219
1220
1221
1222
1223
1224 const Init *resolveReferences(Resolver &R) const override;
1225
1226 const Init *getBit(unsigned Bit) const override;
1227
1228 std::string getAsString() const override { return std::string(getName()); }
1229 };
1230
1231
1232 class VarBitInit final : public TypedInit {
1233 const TypedInit *TI;
1234 unsigned Bit;
1235
1236 VarBitInit(const TypedInit *T, unsigned B)
1237 : TypedInit(IK_VarBitInit, BitRecTy::get(T->getRecordKeeper())), TI(T),
1238 Bit(B) {
1239 assert(T->getType() &&
1240 (isa<IntRecTy>(T->getType()) ||
1241 (isa<BitsRecTy>(T->getType()) &&
1242 cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
1243 "Illegal VarBitInit expression!");
1244 }
1245
1246 public:
1247 VarBitInit(const VarBitInit &) = delete;
1248 VarBitInit &operator=(const VarBitInit &) = delete;
1249
1250 static bool classof(const Init *I) {
1251 return I->getKind() == IK_VarBitInit;
1252 }
1253
1254 static const VarBitInit *get(const TypedInit *T, unsigned B);
1255
1256 const Init *getBitVar() const { return TI; }
1257 unsigned getBitNum() const { return Bit; }
1258
1259 std::string getAsString() const override;
1260 const Init *resolveReferences(Resolver &R) const override;
1261
1262 const Init *getBit(unsigned B) const override {
1263 assert(B < 1 && "Bit index out of range!");
1264 return this;
1265 }
1266 };
1267
1268
1269 class DefInit final : public TypedInit {
1270 friend class Record;
1271
1272 const Record *Def;
1273
1274 explicit DefInit(const Record *D);
1275
1276 public:
1277 DefInit(const DefInit &) = delete;
1278 DefInit &operator=(const DefInit &) = delete;
1279
1280 static bool classof(const Init *I) {
1281 return I->getKind() == IK_DefInit;
1282 }
1283
1284 const Init *convertInitializerTo(const RecTy *Ty) const override;
1285
1286 const Record *getDef() const { return Def; }
1287
1288 const RecTy *getFieldType(const StringInit *FieldName) const override;
1289
1290 bool isConcrete() const override { return true; }
1291 std::string getAsString() const override;
1292
1293 const Init *getBit(unsigned Bit) const override {
1294 llvm_unreachable("Illegal bit reference off def");
1295 }
1296 };
1297
1298
1299
1300 class VarDefInit final
1301 : public TypedInit,
1302 public FoldingSetNode,
1303 public TrailingObjects<VarDefInit, const ArgumentInit *> {
1304 SMLoc Loc;
1305 const Record *Class;
1306 const DefInit *Def = nullptr;
1307 unsigned NumArgs;
1308
1309 explicit VarDefInit(SMLoc Loc, const Record *Class, unsigned N);
1310
1311 const DefInit *instantiate();
1312
1313 public:
1314 VarDefInit(const VarDefInit &) = delete;
1315 VarDefInit &operator=(const VarDefInit &) = delete;
1316
1317
1318 void operator delete(void *p) { ::operator delete(p); }
1319
1320 static bool classof(const Init *I) {
1321 return I->getKind() == IK_VarDefInit;
1322 }
1323 static const VarDefInit *get(SMLoc Loc, const Record *Class,
1324 ArrayRef<const ArgumentInit *> Args);
1325
1326 void Profile(FoldingSetNodeID &ID) const;
1327
1328 const Init *resolveReferences(Resolver &R) const override;
1329 const Init *Fold() const;
1330
1331 std::string getAsString() const override;
1332
1333 const ArgumentInit *getArg(unsigned i) const {
1334 assert(i < NumArgs && "Argument index out of range!");
1335 return getTrailingObjects<const ArgumentInit *>()[i];
1336 }
1337
1338 using const_iterator = const ArgumentInit *const *;
1339
1340 const_iterator args_begin() const {
1341 return getTrailingObjects<const ArgumentInit *>();
1342 }
1343 const_iterator args_end () const { return args_begin() + NumArgs; }
1344
1345 size_t args_size () const { return NumArgs; }
1346 bool args_empty() const { return NumArgs == 0; }
1347
1348 ArrayRef<const ArgumentInit *> args() const {
1349 return ArrayRef(args_begin(), NumArgs);
1350 }
1351
1352 const Init *getBit(unsigned Bit) const override {
1353 llvm_unreachable("Illegal bit reference off anonymous def");
1354 }
1355 };
1356
1357
1358 class FieldInit final : public TypedInit {
1359 const Init *Rec;
1360 const StringInit *FieldName;
1361
1362 FieldInit(const Init *R, const StringInit *FN)
1363 : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
1364 #ifndef NDEBUG
1365 if (!getType()) {
1366 llvm::errs() << "In Record = " << Rec->getAsString()
1367 << ", got FieldName = " << *FieldName
1368 << " with non-record type!\n";
1369 llvm_unreachable("FieldInit with non-record type!");
1370 }
1371 #endif
1372 }
1373
1374 public:
1375 FieldInit(const FieldInit &) = delete;
1376 FieldInit &operator=(const FieldInit &) = delete;
1377
1378 static bool classof(const Init *I) {
1379 return I->getKind() == IK_FieldInit;
1380 }
1381
1382 static const FieldInit *get(const Init *R, const StringInit *FN);
1383
1384 const Init *getRecord() const { return Rec; }
1385 const StringInit *getFieldName() const { return FieldName; }
1386
1387 const Init *getBit(unsigned Bit) const override;
1388
1389 const Init *resolveReferences(Resolver &R) const override;
1390 const Init *Fold(const Record *CurRec) const;
1391
1392 bool isConcrete() const override;
1393 std::string getAsString() const override {
1394 return Rec->getAsString() + "." + FieldName->getValue().str();
1395 }
1396 };
1397
1398
1399
1400
1401 class DagInit final
1402 : public TypedInit,
1403 public FoldingSetNode,
1404 public TrailingObjects<DagInit, const Init *, const StringInit *> {
1405 friend TrailingObjects;
1406
1407 const Init *Val;
1408 const StringInit *ValName;
1409 unsigned NumArgs;
1410 unsigned NumArgNames;
1411
1412 DagInit(const Init *V, const StringInit *VN, unsigned NumArgs,
1413 unsigned NumArgNames)
1414 : TypedInit(IK_DagInit, DagRecTy::get(V->getRecordKeeper())), Val(V),
1415 ValName(VN), NumArgs(NumArgs), NumArgNames(NumArgNames) {}
1416
1417 size_t numTrailingObjects(OverloadToken<const Init *>) const {
1418 return NumArgs;
1419 }
1420
1421 public:
1422 DagInit(const DagInit &) = delete;
1423 DagInit &operator=(const DagInit &) = delete;
1424
1425 static bool classof(const Init *I) {
1426 return I->getKind() == IK_DagInit;
1427 }
1428
1429 static const DagInit *get(const Init *V, const StringInit *VN,
1430 ArrayRef<const Init *> ArgRange,
1431 ArrayRef<const StringInit *> NameRange);
1432 static const DagInit *
1433 get(const Init *V, const StringInit *VN,
1434 ArrayRef<std::pair<const Init *, const StringInit *>> Args);
1435
1436 void Profile(FoldingSetNodeID &ID) const;
1437
1438 const Init *getOperator() const { return Val; }
1439 const Record *getOperatorAsDef(ArrayRef<SMLoc> Loc) const;
1440
1441 const StringInit *getName() const { return ValName; }
1442
1443 StringRef getNameStr() const {
1444 return ValName ? ValName->getValue() : StringRef();
1445 }
1446
1447 unsigned getNumArgs() const { return NumArgs; }
1448
1449 const Init *getArg(unsigned Num) const {
1450 assert(Num < NumArgs && "Arg number out of range!");
1451 return getTrailingObjects<const Init *>()[Num];
1452 }
1453
1454
1455
1456 std::optional<unsigned> getArgNo(StringRef Name) const;
1457
1458 const StringInit *getArgName(unsigned Num) const {
1459 assert(Num < NumArgNames && "Arg number out of range!");
1460 return getTrailingObjects<const StringInit *>()[Num];
1461 }
1462
1463 StringRef getArgNameStr(unsigned Num) const {
1464 const StringInit *Init = getArgName(Num);
1465 return Init ? Init->getValue() : StringRef();
1466 }
1467
1468 ArrayRef<const Init *> getArgs() const {
1469 return ArrayRef(getTrailingObjects<const Init *>(), NumArgs);
1470 }
1471
1472 ArrayRef<const StringInit *> getArgNames() const {
1473 return ArrayRef(getTrailingObjects<const StringInit *>(), NumArgNames);
1474 }
1475
1476 const Init *resolveReferences(Resolver &R) const override;
1477
1478 bool isConcrete() const override;
1479 std::string getAsString() const override;
1480
1481 using const_arg_iterator = SmallVectorImpl<const Init *>::const_iterator;
1482 using const_name_iterator =
1483 SmallVectorImpl<const StringInit *>::const_iterator;
1484
1485 inline const_arg_iterator arg_begin() const { return getArgs().begin(); }
1486 inline const_arg_iterator arg_end () const { return getArgs().end(); }
1487
1488 inline size_t arg_size () const { return NumArgs; }
1489 inline bool arg_empty() const { return NumArgs == 0; }
1490
1491 inline const_name_iterator name_begin() const { return getArgNames().begin();}
1492 inline const_name_iterator name_end () const { return getArgNames().end(); }
1493
1494 inline size_t name_size () const { return NumArgNames; }
1495 inline bool name_empty() const { return NumArgNames == 0; }
1496
1497 const Init *getBit(unsigned Bit) const override {
1498 llvm_unreachable("Illegal bit reference off dag");
1499 }
1500 };
1501
1502
1503
1504
1505
1506
1507
1508 class RecordVal {
1509 friend class Record;
1510
1511 public:
1512 enum FieldKind {
1513 FK_Normal,
1514 FK_NonconcreteOK,
1515 FK_TemplateArg,
1516 };
1517
1518 private:
1519 const Init *Name;
1520 SMLoc Loc;
1521 PointerIntPair<const RecTy *, 2, FieldKind> TyAndKind;
1522 const Init *Value;
1523 bool IsUsed = false;
1524
1525
1526 SmallVector<SMRange, 0> ReferenceLocs;
1527
1528 public:
1529 RecordVal(const Init *N, const RecTy *T, FieldKind K);
1530 RecordVal(const Init *N, SMLoc Loc, const RecTy *T, FieldKind K);
1531
1532
1533 RecordKeeper &getRecordKeeper() const { return Name->getRecordKeeper(); }
1534
1535
1536 StringRef getName() const;
1537
1538
1539 const Init *getNameInit() const { return Name; }
1540
1541
1542 std::string getNameInitAsString() const {
1543 return getNameInit()->getAsUnquotedString();
1544 }
1545
1546
1547 const SMLoc &getLoc() const { return Loc; }
1548
1549
1550 bool isNonconcreteOK() const {
1551 return TyAndKind.getInt() == FK_NonconcreteOK;
1552 }
1553
1554
1555 bool isTemplateArg() const {
1556 return TyAndKind.getInt() == FK_TemplateArg;
1557 }
1558
1559
1560 const RecTy *getType() const { return TyAndKind.getPointer(); }
1561
1562
1563 std::string getPrintType() const;
1564
1565
1566 const Init *getValue() const { return Value; }
1567
1568
1569 bool setValue(const Init *V);
1570
1571
1572 bool setValue(const Init *V, SMLoc NewLoc);
1573
1574
1575 void addReferenceLoc(SMRange Loc) { ReferenceLocs.push_back(Loc); }
1576
1577
1578 ArrayRef<SMRange> getReferenceLocs() const { return ReferenceLocs; }
1579
1580
1581
1582 void setUsed(bool Used) { IsUsed = Used; }
1583 bool isUsed() const { return IsUsed; }
1584
1585 void dump() const;
1586
1587
1588 void print(raw_ostream &OS, bool PrintSem = true) const;
1589 };
1590
1591 inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
1592 RV.print(OS << " ");
1593 return OS;
1594 }
1595
1596 class Record {
1597 public:
1598 struct AssertionInfo {
1599 SMLoc Loc;
1600 const Init *Condition;
1601 const Init *Message;
1602
1603
1604
1605 AssertionInfo(SMLoc Loc, const Init *Condition, const Init *Message)
1606 : Loc(Loc), Condition(Condition), Message(Message) {}
1607 };
1608
1609 struct DumpInfo {
1610 SMLoc Loc;
1611 const Init *Message;
1612
1613
1614
1615 DumpInfo(SMLoc Loc, const Init *Message) : Loc(Loc), Message(Message) {}
1616 };
1617
1618 enum RecordKind { RK_Def, RK_AnonymousDef, RK_Class, RK_MultiClass };
1619
1620 private:
1621 const Init *Name;
1622
1623
1624
1625 SmallVector<SMLoc, 4> Locs;
1626 SmallVector<SMLoc, 0> ForwardDeclarationLocs;
1627 mutable SmallVector<SMRange, 0> ReferenceLocs;
1628 SmallVector<const Init *, 0> TemplateArgs;
1629 SmallVector<RecordVal, 0> Values;
1630 SmallVector<AssertionInfo, 0> Assertions;
1631 SmallVector<DumpInfo, 0> Dumps;
1632
1633
1634
1635 SmallVector<std::pair<const Record *, SMRange>, 0> SuperClasses;
1636
1637
1638 RecordKeeper &TrackedRecords;
1639
1640
1641 mutable DefInit *CorrespondingDefInit = nullptr;
1642
1643
1644 unsigned ID;
1645
1646 RecordKind Kind;
1647
1648 void checkName();
1649
1650 public:
1651
1652 explicit Record(const Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
1653 RecordKind Kind = RK_Def)
1654 : Name(N), Locs(locs), TrackedRecords(records),
1655 ID(getNewUID(N->getRecordKeeper())), Kind(Kind) {
1656 checkName();
1657 }
1658
1659 explicit Record(StringRef N, ArrayRef<SMLoc> locs, RecordKeeper &records,
1660 RecordKind Kind = RK_Def)
1661 : Record(StringInit::get(records, N), locs, records, Kind) {}
1662
1663
1664
1665
1666 Record(const Record &O)
1667 : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
1668 Values(O.Values), Assertions(O.Assertions),
1669 SuperClasses(O.SuperClasses), TrackedRecords(O.TrackedRecords),
1670 ID(getNewUID(O.getRecords())), Kind(O.Kind) {}
1671
1672 static unsigned getNewUID(RecordKeeper &RK);
1673
1674 unsigned getID() const { return ID; }
1675
1676 StringRef getName() const { return cast<StringInit>(Name)->getValue(); }
1677
1678 const Init *getNameInit() const { return Name; }
1679
1680 std::string getNameInitAsString() const {
1681 return getNameInit()->getAsUnquotedString();
1682 }
1683
1684 void setName(const Init *Name);
1685
1686 ArrayRef<SMLoc> getLoc() const { return Locs; }
1687 void appendLoc(SMLoc Loc) { Locs.push_back(Loc); }
1688
1689 ArrayRef<SMLoc> getForwardDeclarationLocs() const {
1690 return ForwardDeclarationLocs;
1691 }
1692
1693
1694 void appendReferenceLoc(SMRange Loc) const { ReferenceLocs.push_back(Loc); }
1695
1696
1697 ArrayRef<SMRange> getReferenceLocs() const { return ReferenceLocs; }
1698
1699
1700 void updateClassLoc(SMLoc Loc);
1701
1702
1703 const RecordRecTy *getType() const;
1704
1705
1706 DefInit *getDefInit() const;
1707
1708 bool isClass() const { return Kind == RK_Class; }
1709
1710 bool isMultiClass() const { return Kind == RK_MultiClass; }
1711
1712 bool isAnonymous() const { return Kind == RK_AnonymousDef; }
1713
1714 ArrayRef<const Init *> getTemplateArgs() const { return TemplateArgs; }
1715
1716 ArrayRef<RecordVal> getValues() const { return Values; }
1717
1718 ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
1719 ArrayRef<DumpInfo> getDumps() const { return Dumps; }
1720
1721 ArrayRef<std::pair<const Record *, SMRange>> getSuperClasses() const {
1722 return SuperClasses;
1723 }
1724
1725
1726 bool hasDirectSuperClass(const Record *SuperClass) const;
1727
1728
1729 void getDirectSuperClasses(SmallVectorImpl<const Record *> &Classes) const;
1730
1731 bool isTemplateArg(const Init *Name) const {
1732 return llvm::is_contained(TemplateArgs, Name);
1733 }
1734
1735 const RecordVal *getValue(const Init *Name) const {
1736 for (const RecordVal &Val : Values)
1737 if (Val.Name == Name) return &Val;
1738 return nullptr;
1739 }
1740
1741 const RecordVal *getValue(StringRef Name) const {
1742 return getValue(StringInit::get(getRecords(), Name));
1743 }
1744
1745 RecordVal *getValue(const Init *Name) {
1746 return const_cast<RecordVal *>(
1747 static_cast<const Record *>(this)->getValue(Name));
1748 }
1749
1750 RecordVal *getValue(StringRef Name) {
1751 return const_cast<RecordVal *>(
1752 static_cast<const Record *>(this)->getValue(Name));
1753 }
1754
1755 void addTemplateArg(const Init *Name) {
1756 assert(!isTemplateArg(Name) && "Template arg already defined!");
1757 TemplateArgs.push_back(Name);
1758 }
1759
1760 void addValue(const RecordVal &RV) {
1761 assert(getValue(RV.getNameInit()) == nullptr && "Value already added!");
1762 Values.push_back(RV);
1763 }
1764
1765 void removeValue(const Init *Name) {
1766 for (unsigned i = 0, e = Values.size(); i != e; ++i)
1767 if (Values[i].getNameInit() == Name) {
1768 Values.erase(Values.begin()+i);
1769 return;
1770 }
1771 llvm_unreachable("Cannot remove an entry that does not exist!");
1772 }
1773
1774 void removeValue(StringRef Name) {
1775 removeValue(StringInit::get(getRecords(), Name));
1776 }
1777
1778 void addAssertion(SMLoc Loc, const Init *Condition, const Init *Message) {
1779 Assertions.push_back(AssertionInfo(Loc, Condition, Message));
1780 }
1781
1782 void addDump(SMLoc Loc, const Init *Message) {
1783 Dumps.push_back(DumpInfo(Loc, Message));
1784 }
1785
1786 void appendAssertions(const Record *Rec) {
1787 Assertions.append(Rec->Assertions);
1788 }
1789
1790 void appendDumps(const Record *Rec) { Dumps.append(Rec->Dumps); }
1791
1792 void checkRecordAssertions();
1793 void emitRecordDumps();
1794 void checkUnusedTemplateArgs();
1795
1796 bool isSubClassOf(const Record *R) const {
1797 for (const auto &[SC, _] : SuperClasses)
1798 if (SC == R)
1799 return true;
1800 return false;
1801 }
1802
1803 bool isSubClassOf(StringRef Name) const {
1804 for (const auto &[SC, _] : SuperClasses) {
1805 if (const auto *SI = dyn_cast<StringInit>(SC->getNameInit())) {
1806 if (SI->getValue() == Name)
1807 return true;
1808 } else if (SC->getNameInitAsString() == Name) {
1809 return true;
1810 }
1811 }
1812 return false;
1813 }
1814
1815 void addSuperClass(const Record *R, SMRange Range) {
1816 assert(!CorrespondingDefInit &&
1817 "changing type of record after it has been referenced");
1818 assert(!isSubClassOf(R) && "Already subclassing record!");
1819 SuperClasses.emplace_back(R, Range);
1820 }
1821
1822
1823
1824
1825
1826
1827 void resolveReferences(const Init *NewName = nullptr);
1828
1829
1830
1831
1832
1833
1834 void resolveReferences(Resolver &R, const RecordVal *SkipVal = nullptr);
1835
1836 RecordKeeper &getRecords() const {
1837 return TrackedRecords;
1838 }
1839
1840 void dump() const;
1841
1842
1843
1844
1845
1846
1847 SMLoc getFieldLoc(StringRef FieldName) const;
1848
1849
1850
1851 const Init *getValueInit(StringRef FieldName) const;
1852
1853
1854 bool isValueUnset(StringRef FieldName) const {
1855 return isa<UnsetInit>(getValueInit(FieldName));
1856 }
1857
1858
1859
1860
1861 StringRef getValueAsString(StringRef FieldName) const;
1862
1863
1864
1865
1866 std::optional<StringRef> getValueAsOptionalString(StringRef FieldName) const;
1867
1868
1869
1870
1871 const BitsInit *getValueAsBitsInit(StringRef FieldName) const;
1872
1873
1874
1875
1876 const ListInit *getValueAsListInit(StringRef FieldName) const;
1877
1878
1879
1880
1881 std::vector<const Record *> getValueAsListOfDefs(StringRef FieldName) const;
1882
1883
1884
1885
1886 std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
1887
1888
1889
1890
1891 std::vector<StringRef> getValueAsListOfStrings(StringRef FieldName) const;
1892
1893
1894
1895
1896 const Record *getValueAsDef(StringRef FieldName) const;
1897
1898
1899
1900
1901
1902 const Record *getValueAsOptionalDef(StringRef FieldName) const;
1903
1904
1905
1906
1907 bool getValueAsBit(StringRef FieldName) const;
1908
1909
1910
1911 bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
1912
1913
1914
1915
1916 int64_t getValueAsInt(StringRef FieldName) const;
1917
1918
1919
1920
1921 const DagInit *getValueAsDag(StringRef FieldName) const;
1922 };
1923
1924 raw_ostream &operator<<(raw_ostream &OS, const Record &R);
1925
1926 class RecordKeeper {
1927 using RecordMap = std::map<std::string, std::unique_ptr<Record>, std::less<>>;
1928 using GlobalMap = std::map<std::string, const Init *, std::less<>>;
1929
1930 public:
1931 RecordKeeper();
1932 ~RecordKeeper();
1933
1934
1935 detail::RecordKeeperImpl &getImpl() { return *Impl; }
1936
1937
1938 const std::string getInputFilename() const { return InputFilename; }
1939
1940
1941 const RecordMap &getClasses() const { return Classes; }
1942
1943
1944 const RecordMap &getDefs() const { return Defs; }
1945
1946
1947 const GlobalMap &getGlobals() const { return ExtraGlobals; }
1948
1949
1950 const Record *getClass(StringRef Name) const {
1951 auto I = Classes.find(Name);
1952 return I == Classes.end() ? nullptr : I->second.get();
1953 }
1954
1955
1956 const Record *getDef(StringRef Name) const {
1957 auto I = Defs.find(Name);
1958 return I == Defs.end() ? nullptr : I->second.get();
1959 }
1960
1961
1962 const Init *getGlobal(StringRef Name) const {
1963 if (const Record *R = getDef(Name))
1964 return R->getDefInit();
1965 auto It = ExtraGlobals.find(Name);
1966 return It == ExtraGlobals.end() ? nullptr : It->second;
1967 }
1968
1969 void saveInputFilename(std::string Filename) {
1970 InputFilename = Filename;
1971 }
1972
1973 void addClass(std::unique_ptr<Record> R) {
1974 bool Ins =
1975 Classes.try_emplace(std::string(R->getName()), std::move(R)).second;
1976 (void)Ins;
1977 assert(Ins && "Class already exists");
1978 }
1979
1980 void addDef(std::unique_ptr<Record> R) {
1981 bool Ins = Defs.try_emplace(std::string(R->getName()), std::move(R)).second;
1982 (void)Ins;
1983 assert(Ins && "Record already exists");
1984 }
1985
1986 void addExtraGlobal(StringRef Name, const Init *I) {
1987 bool Ins = ExtraGlobals.try_emplace(std::string(Name), I).second;
1988 (void)Ins;
1989 assert(!getDef(Name));
1990 assert(Ins && "Global already exists");
1991 }
1992
1993 const Init *getNewAnonymousName();
1994
1995 TGTimer &getTimer() const { return *Timer; }
1996
1997
1998
1999
2000
2001
2002 ArrayRef<const Record *> getAllDerivedDefinitions(StringRef ClassName) const;
2003
2004
2005
2006 std::vector<const Record *>
2007 getAllDerivedDefinitions(ArrayRef<StringRef> ClassNames) const;
2008
2009
2010
2011 ArrayRef<const Record *>
2012 getAllDerivedDefinitionsIfDefined(StringRef ClassName) const;
2013
2014 void dump() const;
2015
2016 void dumpAllocationStats(raw_ostream &OS) const;
2017
2018 private:
2019 RecordKeeper(RecordKeeper &&) = delete;
2020 RecordKeeper(const RecordKeeper &) = delete;
2021 RecordKeeper &operator=(RecordKeeper &&) = delete;
2022 RecordKeeper &operator=(const RecordKeeper &) = delete;
2023
2024 std::string InputFilename;
2025 RecordMap Classes, Defs;
2026 mutable std::map<std::string, std::vector<const Record *>> Cache;
2027 GlobalMap ExtraGlobals;
2028
2029
2030 std::unique_ptr<detail::RecordKeeperImpl> Impl;
2031 std::unique_ptr<TGTimer> Timer;
2032 };
2033
2034
2035 struct LessRecord {
2036 bool operator()(const Record *Rec1, const Record *Rec2) const {
2037 return Rec1->getName().compare_numeric(Rec2->getName()) < 0;
2038 }
2039 };
2040
2041
2042
2043
2044
2045 struct LessRecordByID {
2046 bool operator()(const Record *LHS, const Record *RHS) const {
2047 return LHS->getID() < RHS->getID();
2048 }
2049 };
2050
2051
2052 struct LessRecordFieldName {
2053 bool operator()(const Record *Rec1, const Record *Rec2) const {
2054 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
2055 }
2056 };
2057
2058 struct LessRecordRegister {
2059 struct RecordParts {
2060 SmallVector<std::pair< bool, StringRef>, 4> Parts;
2061
2062 RecordParts(StringRef Rec) {
2063 if (Rec.empty())
2064 return;
2065
2066 size_t Len = 0;
2067 const char *Start = Rec.data();
2068 const char *Curr = Start;
2069 bool IsDigitPart = isDigit(Curr[0]);
2070 for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
2071 bool IsDigit = isDigit(Curr[I]);
2072 if (IsDigit != IsDigitPart) {
2073 Parts.emplace_back(IsDigitPart, StringRef(Start, Len));
2074 Len = 0;
2075 Start = &Curr[I];
2076 IsDigitPart = isDigit(Curr[I]);
2077 }
2078 }
2079
2080 Parts.emplace_back(IsDigitPart, StringRef(Start, Len));
2081 }
2082
2083 size_t size() { return Parts.size(); }
2084
2085 std::pair<bool, StringRef> getPart(size_t i) {
2086 assert (i < Parts.size() && "Invalid idx!");
2087 return Parts[i];
2088 }
2089 };
2090
2091 bool operator()(const Record *Rec1, const Record *Rec2) const {
2092 int64_t LHSPositionOrder = Rec1->getValueAsInt("PositionOrder");
2093 int64_t RHSPositionOrder = Rec2->getValueAsInt("PositionOrder");
2094 if (LHSPositionOrder != RHSPositionOrder)
2095 return LHSPositionOrder < RHSPositionOrder;
2096
2097 RecordParts LHSParts(StringRef(Rec1->getName()));
2098 RecordParts RHSParts(StringRef(Rec2->getName()));
2099
2100 size_t LHSNumParts = LHSParts.size();
2101 size_t RHSNumParts = RHSParts.size();
2102 assert (LHSNumParts && RHSNumParts && "Expected at least one part!");
2103
2104 if (LHSNumParts != RHSNumParts)
2105 return LHSNumParts < RHSNumParts;
2106
2107
2108 for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
2109 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
2110 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
2111
2112 assert (LHSPart.first == false && RHSPart.first == false &&
2113 "Expected both parts to be alpha.");
2114 if (int Res = LHSPart.second.compare(RHSPart.second))
2115 return Res < 0;
2116 }
2117 for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
2118 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
2119 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
2120
2121 assert (LHSPart.first == true && RHSPart.first == true &&
2122 "Expected both parts to be numeric.");
2123 if (LHSPart.second.size() != RHSPart.second.size())
2124 return LHSPart.second.size() < RHSPart.second.size();
2125
2126 unsigned LHSVal, RHSVal;
2127
2128 bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
2129 assert(!LHSFailed && "Unable to convert LHS to integer.");
2130 bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
2131 assert(!RHSFailed && "Unable to convert RHS to integer.");
2132
2133 if (LHSVal != RHSVal)
2134 return LHSVal < RHSVal;
2135 }
2136 return LHSNumParts < RHSNumParts;
2137 }
2138 };
2139
2140 raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
2141
2142
2143
2144
2145
2146
2147
2148 class Resolver {
2149 const Record *CurRec;
2150 bool IsFinal = false;
2151
2152 public:
2153 explicit Resolver(const Record *CurRec) : CurRec(CurRec) {}
2154 virtual ~Resolver() = default;
2155
2156 const Record *getCurrentRecord() const { return CurRec; }
2157
2158
2159
2160 virtual const Init *resolve(const Init *VarName) = 0;
2161
2162
2163
2164
2165 virtual bool keepUnsetBits() const { return false; }
2166
2167
2168
2169
2170 bool isFinal() const { return IsFinal; }
2171
2172 void setFinal(bool Final) { IsFinal = Final; }
2173 };
2174
2175
2176 class MapResolver final : public Resolver {
2177 struct MappedValue {
2178 const Init *V;
2179 bool Resolved;
2180
2181 MappedValue() : V(nullptr), Resolved(false) {}
2182 MappedValue(const Init *V, bool Resolved) : V(V), Resolved(Resolved) {}
2183 };
2184
2185 DenseMap<const Init *, MappedValue> Map;
2186
2187 public:
2188 explicit MapResolver(const Record *CurRec = nullptr) : Resolver(CurRec) {}
2189
2190 void set(const Init *Key, const Init *Value) { Map[Key] = {Value, false}; }
2191
2192 bool isComplete(Init *VarName) const {
2193 auto It = Map.find(VarName);
2194 assert(It != Map.end() && "key must be present in map");
2195 return It->second.V->isComplete();
2196 }
2197
2198 const Init *resolve(const Init *VarName) override;
2199 };
2200
2201
2202 class RecordResolver final : public Resolver {
2203 DenseMap<const Init *, const Init *> Cache;
2204 SmallVector<const Init *, 4> Stack;
2205 const Init *Name = nullptr;
2206
2207 public:
2208 explicit RecordResolver(const Record &R) : Resolver(&R) {}
2209
2210 void setName(const Init *NewName) { Name = NewName; }
2211
2212 const Init *resolve(const Init *VarName) override;
2213
2214 bool keepUnsetBits() const override { return true; }
2215 };
2216
2217
2218 class ShadowResolver final : public Resolver {
2219 Resolver &R;
2220 DenseSet<const Init *> Shadowed;
2221
2222 public:
2223 explicit ShadowResolver(Resolver &R)
2224 : Resolver(R.getCurrentRecord()), R(R) {
2225 setFinal(R.isFinal());
2226 }
2227
2228 void addShadow(const Init *Key) { Shadowed.insert(Key); }
2229
2230 const Init *resolve(const Init *VarName) override {
2231 if (Shadowed.count(VarName))
2232 return nullptr;
2233 return R.resolve(VarName);
2234 }
2235 };
2236
2237
2238
2239 class TrackUnresolvedResolver final : public Resolver {
2240 Resolver *R;
2241 bool FoundUnresolved = false;
2242
2243 public:
2244 explicit TrackUnresolvedResolver(Resolver *R = nullptr)
2245 : Resolver(R ? R->getCurrentRecord() : nullptr), R(R) {}
2246
2247 bool foundUnresolved() const { return FoundUnresolved; }
2248
2249 const Init *resolve(const Init *VarName) override;
2250 };
2251
2252
2253
2254 class HasReferenceResolver final : public Resolver {
2255 const Init *VarNameToTrack;
2256 bool Found = false;
2257
2258 public:
2259 explicit HasReferenceResolver(const Init *VarNameToTrack)
2260 : Resolver(nullptr), VarNameToTrack(VarNameToTrack) {}
2261
2262 bool found() const { return Found; }
2263
2264 const Init *resolve(const Init *VarName) override;
2265 };
2266
2267 void EmitDetailedRecords(const RecordKeeper &RK, raw_ostream &OS);
2268 void EmitJSON(const RecordKeeper &RK, raw_ostream &OS);
2269
2270 }
2271
2272 #endif