From 17246b12cf40663197abe95f29ab72bb163924ce Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 30 May 2015 07:34:51 +0000 Subject: [PATCH] [TableGen] Remove all the variations of RecTy::convertValue and just handle the conversions in convertInitializerTo directly. This saves a bunch of vtable entries. NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238646 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/TableGen/Record.h | 126 ++--------- lib/TableGen/Record.cpp | 390 ++++++++++++++++++--------------- 2 files changed, 232 insertions(+), 284 deletions(-) diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h index 8e9705f0f48..cae24d0ef8e 100644 --- a/include/llvm/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -100,25 +100,6 @@ public: /// getListTy - Returns the type representing list. ListRecTy *getListTy(); -public: // These methods should only be called from subclasses of Init - virtual Init *convertValue( UnsetInit *UI) { return nullptr; } - virtual Init *convertValue( BitInit *BI) { return nullptr; } - virtual Init *convertValue( BitsInit *BI) { return nullptr; } - virtual Init *convertValue( IntInit *II) { return nullptr; } - virtual Init *convertValue(StringInit *SI) { return nullptr; } - virtual Init *convertValue( ListInit *LI) { return nullptr; } - virtual Init *convertValue(VarBitInit *VB) { return nullptr; } - virtual Init *convertValue( DefInit *DI) { return nullptr; } - virtual Init *convertValue( DagInit *DI) { return nullptr; } - virtual Init *convertValue( TypedInit *TI) { return nullptr; } - virtual Init *convertValue( VarInit *VI) { - return convertValue((TypedInit*)VI); - } - virtual Init *convertValue( FieldInit *FI) { - return convertValue((TypedInit*)FI); - } - -public: virtual bool baseClassOf(const RecTy*) const; }; @@ -140,14 +121,6 @@ public: static BitRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override { return (Init*)BI; } - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue(VarBitInit *VB) override { return (Init*)VB; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "bit"; } bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -171,13 +144,6 @@ public: unsigned getNumBits() const { return Size; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override; - Init *convertValue( BitInit *UI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -199,13 +165,6 @@ public: static IntRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( BitInit *BI) override; - Init *convertValue( BitsInit *BI) override; - Init *convertValue( IntInit *II) override { return (Init*)II; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "int"; } bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -221,6 +180,7 @@ class StringRecTy : public RecTy { static StringRecTy Shared; StringRecTy() : RecTy(StringRecTyKind) {} + void anchor() override; public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == StringRecTyKind; @@ -228,11 +188,6 @@ public: static StringRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue(StringInit *SI) override { return (Init*)SI; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "string"; } bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -256,11 +211,6 @@ public: static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( ListInit *LI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -276,6 +226,7 @@ class DagRecTy : public RecTy { static DagRecTy Shared; DagRecTy() : RecTy(DagRecTyKind) {} + void anchor() override; public: static bool classof(const RecTy *RT) { return RT->getRecTyKind() == DagRecTyKind; @@ -283,11 +234,6 @@ public: static DagRecTy *get() { return &Shared; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( DagInit *DI) override { return (Init*)DI; } - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override { return "dag"; } bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -312,11 +258,6 @@ public: Record *getRecord() const { return Rec; } - using RecTy::convertValue; - Init *convertValue( UnsetInit *UI) override { return (Init*)UI; } - Init *convertValue( DefInit *DI) override; - Init *convertValue( TypedInit *TI) override; - std::string getAsString() const override; bool typeIsConvertibleTo(const RecTy *RHS) const override { @@ -405,10 +346,8 @@ public: /// invokes print on stderr. void dump() const; - /// convertInitializerTo - This virtual function is a simple call-back - /// function that should be overridden to call the appropriate - /// RecTy::convertValue method. - /// + /// convertInitializerTo - This virtual function converts to the appropriate + /// Init based on the passed in type. virtual Init *convertInitializerTo(RecTy *Ty) const = 0; /// convertInitializerBitRange - This method is used to implement the bitrange @@ -498,6 +437,8 @@ public: } RecTy *getType() const { return Ty; } + Init *convertInitializerTo(RecTy *Ty) const override; + Init * convertInitializerBitRange(const std::vector &Bits) const override; Init * @@ -522,7 +463,6 @@ class UnsetInit : public Init { UnsetInit() : Init(IK_UnsetInit) {} UnsetInit(const UnsetInit &) = delete; UnsetInit &operator=(const UnsetInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -530,9 +470,7 @@ public: } static UnsetInit *get(); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { return const_cast(this); @@ -550,7 +488,6 @@ class BitInit : public Init { explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {} BitInit(const BitInit &Other) = delete; BitInit &operator=(BitInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -560,9 +497,7 @@ public: bool getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBit(unsigned Bit) const override { assert(Bit < 1 && "Bit index out of range!"); @@ -595,9 +530,7 @@ public: unsigned getNumBits() const { return Bits.size(); } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector &Bits) const override; @@ -648,9 +581,7 @@ public: int64_t getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init * convertInitializerBitRange(const std::vector &Bits) const override; @@ -679,7 +610,6 @@ class StringInit : public TypedInit { StringInit(const StringInit &Other) = delete; StringInit &operator=(const StringInit &Other) = delete; - void anchor() override; public: static bool classof(const Init *I) { @@ -689,9 +619,7 @@ public: const std::string &getValue() const { return Value; } - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; std::string getAsString() const override { return "\"" + Value + "\""; } std::string getAsUnquotedString() const override { return Value; } @@ -744,9 +672,7 @@ public: Init * convertInitListSlice(const std::vector &Elements) const override; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; /// resolveReferences - This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. @@ -799,10 +725,6 @@ public: // possible to fold. virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) const override; @@ -991,10 +913,6 @@ public: static VarInit *get(const std::string &VN, RecTy *T); static VarInit *get(Init *VN, RecTy *T); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - const std::string &getName() const; Init *getNameInit() const { return VarName; } std::string getNameInitAsString() const { @@ -1043,9 +961,7 @@ public: } static VarBitInit *get(TypedInit *T, unsigned B); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getBitVar() const override { return TI; } unsigned getBitNum() const override { return Bit; } @@ -1082,10 +998,6 @@ public: } static VarListElementInit *get(TypedInit *T, unsigned E); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } @@ -1118,9 +1030,7 @@ public: } static DefInit *get(Record*); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Record *getDef() const { return Def; } @@ -1166,10 +1076,6 @@ public: static FieldInit *get(Init *R, const std::string &FN); static FieldInit *get(Init *R, const Init *FN); - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } - Init *getBit(unsigned Bit) const override; Init *resolveListElementReference(Record &R, const RecordVal *RV, @@ -1215,9 +1121,7 @@ public: void Profile(FoldingSetNodeID &ID) const; - Init *convertInitializerTo(RecTy *Ty) const override { - return Ty->convertValue(const_cast(this)); - } + Init *convertInitializerTo(RecTy *Ty) const override; Init *getOperator() const { return Val; } diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp index 534411364e9..b050000500e 100644 --- a/lib/TableGen/Record.cpp +++ b/lib/TableGen/Record.cpp @@ -89,6 +89,9 @@ DagRecTy DagRecTy::Shared; void RecTy::anchor() { } void RecTy::dump() const { print(errs()); } +void StringRecTy::anchor() { } +void DagRecTy::anchor() { } + ListRecTy *RecTy::getListTy() { if (!ListTy) ListTy.reset(new ListRecTy(this)); @@ -100,38 +103,6 @@ bool RecTy::baseClassOf(const RecTy *RHS) const { return Kind == RHS->getRecTyKind(); } -Init *BitRecTy::convertValue(BitsInit *BI) { - if (BI->getNumBits() != 1) return nullptr; // Only accept if just one bit! - return BI->getBit(0); -} - -Init *BitRecTy::convertValue(IntInit *II) { - int64_t Val = II->getValue(); - if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! - - return BitInit::get(Val != 0); -} - -Init *BitRecTy::convertValue(TypedInit *TI) { - RecTy *Ty = TI->getType(); - if (isa(Ty)) - return TI; // Accept variable if it is already of bit type! - if (auto *BitsTy = dyn_cast(Ty)) - // Accept only bits<1> expression. - return BitsTy->getNumBits() == 1 ? TI : nullptr; - // Ternary !if can be converted to bit, but only if both sides are - // convertible to a bit. - if (TernOpInit *TOI = dyn_cast(TI)) { - if (TOI->getOpcode() != TernOpInit::TernaryOp::IF) - return nullptr; - if (!TOI->getMHS()->convertInitializerTo(BitRecTy::get()) || - !TOI->getRHS()->convertInitializerTo(BitRecTy::get())) - return nullptr; - return TOI; - } - return nullptr; -} - bool BitRecTy::baseClassOf(const RecTy *RHS) const{ if(RecTy::baseClassOf(RHS) || RHS->getRecTyKind() == IntRecTyKind) return true; @@ -154,67 +125,6 @@ std::string BitsRecTy::getAsString() const { return "bits<" + utostr(Size) + ">"; } -Init *BitsRecTy::convertValue(UnsetInit *UI) { - SmallVector NewBits(Size); - - for (unsigned i = 0; i != Size; ++i) - NewBits[i] = UnsetInit::get(); - - return BitsInit::get(NewBits); -} - -Init *BitsRecTy::convertValue(BitInit *BI) { - if (Size != 1) return nullptr; // Can only convert single bit. - return BitsInit::get(BI); -} - -/// canFitInBitfield - Return true if the number of bits is large enough to hold -/// the integer value. -static bool canFitInBitfield(int64_t Value, unsigned NumBits) { - // For example, with NumBits == 4, we permit Values from [-7 .. 15]. - return (NumBits >= sizeof(Value) * 8) || - (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1); -} - -/// convertValue from Int initializer to bits type: Split the integer up into the -/// appropriate bits. -/// -Init *BitsRecTy::convertValue(IntInit *II) { - int64_t Value = II->getValue(); - // Make sure this bitfield is large enough to hold the integer value. - if (!canFitInBitfield(Value, Size)) - return nullptr; - - SmallVector NewBits(Size); - - for (unsigned i = 0; i != Size; ++i) - NewBits[i] = BitInit::get(Value & (1LL << i)); - - return BitsInit::get(NewBits); -} - -Init *BitsRecTy::convertValue(BitsInit *BI) { - // If the number of bits is right, return it. Otherwise we need to expand or - // truncate. - if (BI->getNumBits() == Size) return BI; - return nullptr; -} - -Init *BitsRecTy::convertValue(TypedInit *TI) { - if (Size == 1 && isa(TI->getType())) - return BitsInit::get(TI); - - if (TI->getType()->typeIsConvertibleTo(this)) { - SmallVector NewBits(Size); - - for (unsigned i = 0; i != Size; ++i) - NewBits[i] = VarBitInit::get(TI, i); - return BitsInit::get(NewBits); - } - - return nullptr; -} - bool BitsRecTy::baseClassOf(const RecTy *RHS) const{ if (RecTy::baseClassOf(RHS)) //argument and the receiver are the same type return cast(RHS)->Size == Size; @@ -222,79 +132,22 @@ bool BitsRecTy::baseClassOf(const RecTy *RHS) const{ return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind); } -Init *IntRecTy::convertValue(BitInit *BI) { - return IntInit::get(BI->getValue()); -} - -Init *IntRecTy::convertValue(BitsInit *BI) { - int64_t Result = 0; - for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) - if (BitInit *Bit = dyn_cast(BI->getBit(i))) - Result |= static_cast(Bit->getValue()) << i; - else - return nullptr; - return IntInit::get(Result); -} - -Init *IntRecTy::convertValue(TypedInit *TI) { - if (TI->getType()->typeIsConvertibleTo(this)) - return TI; // Accept variable if already of the right type! - return nullptr; -} - bool IntRecTy::baseClassOf(const RecTy *RHS) const{ RecTyKind kind = RHS->getRecTyKind(); return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind; } -Init *StringRecTy::convertValue(TypedInit *TI) { - if (isa(TI->getType())) - return TI; // Accept variable if already of the right type! - return nullptr; -} - std::string ListRecTy::getAsString() const { return "list<" + Ty->getAsString() + ">"; } -Init *ListRecTy::convertValue(ListInit *LI) { - std::vector Elements; - - // Verify that all of the elements of the list are subclasses of the - // appropriate class! - for (unsigned i = 0, e = LI->getSize(); i != e; ++i) - if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty)) - Elements.push_back(CI); - else - return nullptr; - - if (!isa(LI->getType())) - return nullptr; - - return ListInit::get(Elements, this); -} - -Init *ListRecTy::convertValue(TypedInit *TI) { - // Ensure that TI is compatible with our class. - if (ListRecTy *LRT = dyn_cast(TI->getType())) - if (LRT->getElementType()->typeIsConvertibleTo(getElementType())) - return TI; - return nullptr; -} - bool ListRecTy::baseClassOf(const RecTy *RHS) const{ if(const ListRecTy* ListTy = dyn_cast(RHS)) return ListTy->getElementType()->typeIsConvertibleTo(Ty); return false; } -Init *DagRecTy::convertValue(TypedInit *TI) { - if (TI->getType()->typeIsConvertibleTo(this)) - return TI; - return nullptr; -} - RecordRecTy *RecordRecTy::get(Record *R) { return dyn_cast(R->getDefInit()->getType()); } @@ -303,22 +156,6 @@ std::string RecordRecTy::getAsString() const { return Rec->getName(); } -Init *RecordRecTy::convertValue(DefInit *DI) { - // Ensure that DI is a subclass of Rec. - if (!DI->getDef()->isSubClassOf(Rec)) - return nullptr; - return DI; -} - -Init *RecordRecTy::convertValue(TypedInit *TI) { - // Ensure that TI is compatible with Rec. - if (RecordRecTy *RRT = dyn_cast(TI->getType())) - if (RRT->getRecord()->isSubClassOf(getRecord()) || - RRT->getRecord() == getRecord()) - return TI; - return nullptr; -} - bool RecordRecTy::baseClassOf(const RecTy *RHS) const{ const RecordRecTy *RTy = dyn_cast(RHS); if (!RTy) @@ -374,14 +211,24 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { void Init::anchor() { } void Init::dump() const { return print(errs()); } -void UnsetInit::anchor() { } - UnsetInit *UnsetInit::get() { static UnsetInit TheInit; return &TheInit; } -void BitInit::anchor() { } +Init *UnsetInit::convertInitializerTo(RecTy *Ty) const { + if (auto *BRT = dyn_cast(Ty)) { + SmallVector NewBits(BRT->getNumBits()); + + for (unsigned i = 0; i != BRT->getNumBits(); ++i) + NewBits[i] = UnsetInit::get(); + + return BitsInit::get(NewBits); + } + + // All other types can just be returned. + return const_cast(this); +} BitInit *BitInit::get(bool V) { static BitInit True(true); @@ -390,6 +237,22 @@ BitInit *BitInit::get(bool V) { return V ? &True : &False; } +Init *BitInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) + return const_cast(this); + + if (isa(Ty)) + return IntInit::get(getValue()); + + if (auto *BRT = dyn_cast(Ty)) { + // Can only convert single bit. + if (BRT->getNumBits() == 1) + return BitsInit::get(const_cast(this)); + } + + return nullptr; +} + static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef Range) { ID.AddInteger(Range.size()); @@ -419,6 +282,32 @@ void BitsInit::Profile(FoldingSetNodeID &ID) const { ProfileBitsInit(ID, Bits); } +Init *BitsInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) { + if (getNumBits() != 1) return nullptr; // Only accept if just one bit! + return getBit(0); + } + + if (auto *BRT = dyn_cast(Ty)) { + // If the number of bits is right, return it. Otherwise we need to expand + // or truncate. + if (getNumBits() != BRT->getNumBits()) return nullptr; + return const_cast(this); + } + + if (isa(Ty)) { + int64_t Result = 0; + for (unsigned i = 0, e = getNumBits(); i != e; ++i) + if (auto *Bit = dyn_cast(getBit(i))) + Result |= static_cast(Bit->getValue()) << i; + else + return nullptr; + return IntInit::get(Result); + } + + return nullptr; +} + Init * BitsInit::convertInitializerBitRange(const std::vector &Bits) const { SmallVector NewBits(Bits.size()); @@ -512,6 +401,40 @@ std::string IntInit::getAsString() const { return itostr(Value); } +/// canFitInBitfield - Return true if the number of bits is large enough to hold +/// the integer value. +static bool canFitInBitfield(int64_t Value, unsigned NumBits) { + // For example, with NumBits == 4, we permit Values from [-7 .. 15]. + return (NumBits >= sizeof(Value) * 8) || + (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1); +} + +Init *IntInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) + return const_cast(this); + + if (isa(Ty)) { + int64_t Val = getValue(); + if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! + return BitInit::get(Val != 0); + } + + if (auto *BRT = dyn_cast(Ty)) { + int64_t Value = getValue(); + // Make sure this bitfield is large enough to hold the integer value. + if (!canFitInBitfield(Value, BRT->getNumBits())) + return nullptr; + + SmallVector NewBits(BRT->getNumBits()); + for (unsigned i = 0; i != BRT->getNumBits(); ++i) + NewBits[i] = BitInit::get(Value & (1LL << i)); + + return BitsInit::get(NewBits); + } + + return nullptr; +} + Init * IntInit::convertInitializerBitRange(const std::vector &Bits) const { SmallVector NewBits(Bits.size()); @@ -525,8 +448,6 @@ IntInit::convertInitializerBitRange(const std::vector &Bits) const { return BitsInit::get(NewBits); } -void StringInit::anchor() { } - StringInit *StringInit::get(StringRef V) { static StringMap> ThePool; @@ -535,6 +456,13 @@ StringInit *StringInit::get(StringRef V) { return I.get(); } +Init *StringInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) + return const_cast(this); + + return nullptr; +} + static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef Range, RecTy *EltTy) { @@ -568,6 +496,25 @@ void ListInit::Profile(FoldingSetNodeID &ID) const { ProfileListInit(ID, Values, EltTy); } +Init *ListInit::convertInitializerTo(RecTy *Ty) const { + if (auto *LRT = dyn_cast(Ty)) { + std::vector Elements; + + // Verify that all of the elements of the list are subclasses of the + // appropriate class! + for (unsigned i = 0, e = getSize(); i != e; ++i) + if (Init *CI = getElement(i)->convertInitializerTo(LRT->getElementType())) + Elements.push_back(CI); + else + return nullptr; + + if (isa(getType())) + return ListInit::get(Elements, Ty); + } + + return nullptr; +} + Init * ListInit::convertInitListSlice(const std::vector &Elements) const { std::vector Vals; @@ -1147,6 +1094,82 @@ RecTy *TypedInit::getFieldType(const std::string &FieldName) const { return nullptr; } +Init * +TypedInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) { + if (getType()->typeIsConvertibleTo(Ty)) + return const_cast(this); + return nullptr; + } + + if (isa(Ty)) { + if (isa(getType())) + return const_cast(this); + return nullptr; + } + + if (isa(Ty)) { + // Accept variable if it is already of bit type! + if (isa(getType())) + return const_cast(this); + if (auto *BitsTy = dyn_cast(getType())) { + // Accept only bits<1> expression. + if (BitsTy->getNumBits() == 1) + return const_cast(this); + return nullptr; + } + // Ternary !if can be converted to bit, but only if both sides are + // convertible to a bit. + if (const auto *TOI = dyn_cast(this)) { + if (TOI->getOpcode() == TernOpInit::TernaryOp::IF && + TOI->getMHS()->convertInitializerTo(BitRecTy::get()) && + TOI->getRHS()->convertInitializerTo(BitRecTy::get())) + return const_cast(this); + return nullptr; + } + return nullptr; + } + + if (auto *BRT = dyn_cast(Ty)) { + if (BRT->getNumBits() == 1 && isa(getType())) + return BitsInit::get(const_cast(this)); + + if (getType()->typeIsConvertibleTo(BRT)) { + SmallVector NewBits(BRT->getNumBits()); + + for (unsigned i = 0; i != BRT->getNumBits(); ++i) + NewBits[i] = VarBitInit::get(const_cast(this), i); + return BitsInit::get(NewBits); + } + + return nullptr; + } + + if (auto *DLRT = dyn_cast(Ty)) { + if (auto *SLRT = dyn_cast(getType())) + if (SLRT->getElementType()->typeIsConvertibleTo(DLRT->getElementType())) + return const_cast(this); + return nullptr; + } + + if (auto *DRT = dyn_cast(Ty)) { + if (getType()->typeIsConvertibleTo(DRT)) + return const_cast(this); + return nullptr; + } + + if (auto *SRRT = dyn_cast(Ty)) { + // Ensure that this is compatible with Rec. + if (RecordRecTy *DRRT = dyn_cast(getType())) + if (DRRT->getRecord()->isSubClassOf(SRRT->getRecord()) || + DRRT->getRecord() == SRRT->getRecord()) + return const_cast(this); + return nullptr; + } + + return nullptr; +} + Init * TypedInit::convertInitializerBitRange(const std::vector &Bits) const { BitsRecTy *T = dyn_cast(getType()); @@ -1276,6 +1299,13 @@ VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { return I.get(); } +Init *VarBitInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) + return const_cast(this); + + return nullptr; +} + std::string VarBitInit::getAsString() const { return TI->getAsString() + "{" + utostr(Bit) + "}"; } @@ -1337,6 +1367,13 @@ DefInit *DefInit::get(Record *R) { return R->getDefInit(); } +Init *DefInit::convertInitializerTo(RecTy *Ty) const { + if (auto *RRT = dyn_cast(Ty)) + if (getDef()->isSubClassOf(RRT->getRecord())) + return const_cast(this); + return nullptr; +} + RecTy *DefInit::getFieldType(const std::string &FieldName) const { if (const RecordVal *RV = Def->getValue(FieldName)) return RV->getType(); @@ -1453,6 +1490,13 @@ void DagInit::Profile(FoldingSetNodeID &ID) const { ProfileDagInit(ID, Val, ValName, Args, ArgNames); } +Init *DagInit::convertInitializerTo(RecTy *Ty) const { + if (isa(Ty)) + return const_cast(this); + + return nullptr; +} + Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const { std::vector NewArgs; for (unsigned i = 0, e = Args.size(); i != e; ++i) @@ -1489,13 +1533,13 @@ std::string DagInit::getAsString() const { RecordVal::RecordVal(Init *N, RecTy *T, unsigned P) : Name(N), Ty(T), Prefix(P) { - Value = Ty->convertValue(UnsetInit::get()); + Value = UnsetInit::get()->convertInitializerTo(Ty); assert(Value && "Cannot create unset value for current type!"); } RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P) : Name(StringInit::get(N)), Ty(T), Prefix(P) { - Value = Ty->convertValue(UnsetInit::get()); + Value = UnsetInit::get()->convertInitializerTo(Ty); assert(Value && "Cannot create unset value for current type!"); } -- 2.34.1