Record.cpp revision 280031
1226584Sdim//===- Record.cpp - Record implementation ---------------------------------===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// Implement the tablegen record classes. 11226584Sdim// 12226584Sdim//===----------------------------------------------------------------------===// 13226584Sdim 14226584Sdim#include "llvm/TableGen/Record.h" 15226584Sdim#include "llvm/ADT/DenseMap.h" 16226584Sdim#include "llvm/ADT/FoldingSet.h" 17234353Sdim#include "llvm/ADT/Hashing.h" 18249423Sdim#include "llvm/ADT/STLExtras.h" 19226584Sdim#include "llvm/ADT/SmallVector.h" 20226584Sdim#include "llvm/ADT/StringExtras.h" 21226584Sdim#include "llvm/ADT/StringMap.h" 22249423Sdim#include "llvm/Support/DataTypes.h" 23249423Sdim#include "llvm/Support/ErrorHandling.h" 24249423Sdim#include "llvm/Support/Format.h" 25249423Sdim#include "llvm/TableGen/Error.h" 26226584Sdim 27226584Sdimusing namespace llvm; 28226584Sdim 29226584Sdim//===----------------------------------------------------------------------===// 30226584Sdim// std::string wrapper for DenseMap purposes 31226584Sdim//===----------------------------------------------------------------------===// 32226584Sdim 33234353Sdimnamespace llvm { 34234353Sdim 35226584Sdim/// TableGenStringKey - This is a wrapper for std::string suitable for 36226584Sdim/// using as a key to a DenseMap. Because there isn't a particularly 37226584Sdim/// good way to indicate tombstone or empty keys for strings, we want 38226584Sdim/// to wrap std::string to indicate that this is a "special" string 39226584Sdim/// not expected to take on certain values (those of the tombstone and 40226584Sdim/// empty keys). This makes things a little safer as it clarifies 41226584Sdim/// that DenseMap is really not appropriate for general strings. 42226584Sdim 43226584Sdimclass TableGenStringKey { 44226584Sdimpublic: 45226584Sdim TableGenStringKey(const std::string &str) : data(str) {} 46226584Sdim TableGenStringKey(const char *str) : data(str) {} 47226584Sdim 48226584Sdim const std::string &str() const { return data; } 49234353Sdim 50234353Sdim friend hash_code hash_value(const TableGenStringKey &Value) { 51234353Sdim using llvm::hash_value; 52234353Sdim return hash_value(Value.str()); 53234353Sdim } 54226584Sdimprivate: 55226584Sdim std::string data; 56226584Sdim}; 57226584Sdim 58226584Sdim/// Specialize DenseMapInfo for TableGenStringKey. 59226584Sdimtemplate<> struct DenseMapInfo<TableGenStringKey> { 60226584Sdim static inline TableGenStringKey getEmptyKey() { 61226584Sdim TableGenStringKey Empty("<<<EMPTY KEY>>>"); 62226584Sdim return Empty; 63226584Sdim } 64226584Sdim static inline TableGenStringKey getTombstoneKey() { 65226584Sdim TableGenStringKey Tombstone("<<<TOMBSTONE KEY>>>"); 66226584Sdim return Tombstone; 67226584Sdim } 68226584Sdim static unsigned getHashValue(const TableGenStringKey& Val) { 69234353Sdim using llvm::hash_value; 70234353Sdim return hash_value(Val); 71226584Sdim } 72226584Sdim static bool isEqual(const TableGenStringKey& LHS, 73226584Sdim const TableGenStringKey& RHS) { 74226584Sdim return LHS.str() == RHS.str(); 75226584Sdim } 76226584Sdim}; 77226584Sdim 78234353Sdim} // namespace llvm 79226584Sdim 80226584Sdim//===----------------------------------------------------------------------===// 81226584Sdim// Type implementations 82226584Sdim//===----------------------------------------------------------------------===// 83226584Sdim 84226584SdimBitRecTy BitRecTy::Shared; 85226584SdimIntRecTy IntRecTy::Shared; 86226584SdimStringRecTy StringRecTy::Shared; 87226584SdimDagRecTy DagRecTy::Shared; 88226584Sdim 89234353Sdimvoid RecTy::anchor() { } 90226584Sdimvoid RecTy::dump() const { print(errs()); } 91226584Sdim 92226584SdimListRecTy *RecTy::getListTy() { 93226584Sdim if (!ListTy) 94226584Sdim ListTy = new ListRecTy(this); 95226584Sdim return ListTy; 96226584Sdim} 97226584Sdim 98249423Sdimbool RecTy::baseClassOf(const RecTy *RHS) const{ 99249423Sdim assert (RHS && "NULL pointer"); 100249423Sdim return Kind == RHS->getRecTyKind(); 101249423Sdim} 102249423Sdim 103226584SdimInit *BitRecTy::convertValue(BitsInit *BI) { 104276479Sdim if (BI->getNumBits() != 1) return nullptr; // Only accept if just one bit! 105226584Sdim return BI->getBit(0); 106226584Sdim} 107226584Sdim 108226584SdimInit *BitRecTy::convertValue(IntInit *II) { 109226584Sdim int64_t Val = II->getValue(); 110276479Sdim if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! 111226584Sdim 112226584Sdim return BitInit::get(Val != 0); 113226584Sdim} 114226584Sdim 115226584SdimInit *BitRecTy::convertValue(TypedInit *VI) { 116243830Sdim RecTy *Ty = VI->getType(); 117280031Sdim if (isa<BitRecTy>(Ty)) 118226584Sdim return VI; // Accept variable if it is already of bit type! 119280031Sdim if (auto *BitsTy = dyn_cast<BitsRecTy>(Ty)) 120280031Sdim // Accept only bits<1> expression. 121280031Sdim return BitsTy->getNumBits() == 1 ? VI : nullptr; 122280031Sdim // Ternary !if can be converted to bit, but only if both sides are 123280031Sdim // convertible to a bit. 124280031Sdim if (TernOpInit *TOI = dyn_cast<TernOpInit>(VI)) { 125280031Sdim if (TOI->getOpcode() != TernOpInit::TernaryOp::IF) 126280031Sdim return nullptr; 127280031Sdim if (!TOI->getMHS()->convertInitializerTo(BitRecTy::get()) || 128280031Sdim !TOI->getRHS()->convertInitializerTo(BitRecTy::get())) 129280031Sdim return nullptr; 130280031Sdim return TOI; 131280031Sdim } 132276479Sdim return nullptr; 133226584Sdim} 134226584Sdim 135249423Sdimbool BitRecTy::baseClassOf(const RecTy *RHS) const{ 136249423Sdim if(RecTy::baseClassOf(RHS) || getRecTyKind() == IntRecTyKind) 137249423Sdim return true; 138249423Sdim if(const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS)) 139249423Sdim return BitsTy->getNumBits() == 1; 140249423Sdim return false; 141249423Sdim} 142249423Sdim 143226584SdimBitsRecTy *BitsRecTy::get(unsigned Sz) { 144226584Sdim static std::vector<BitsRecTy*> Shared; 145226584Sdim if (Sz >= Shared.size()) 146226584Sdim Shared.resize(Sz + 1); 147226584Sdim BitsRecTy *&Ty = Shared[Sz]; 148226584Sdim if (!Ty) 149226584Sdim Ty = new BitsRecTy(Sz); 150226584Sdim return Ty; 151226584Sdim} 152226584Sdim 153226584Sdimstd::string BitsRecTy::getAsString() const { 154226584Sdim return "bits<" + utostr(Size) + ">"; 155226584Sdim} 156226584Sdim 157226584SdimInit *BitsRecTy::convertValue(UnsetInit *UI) { 158226584Sdim SmallVector<Init *, 16> NewBits(Size); 159226584Sdim 160226584Sdim for (unsigned i = 0; i != Size; ++i) 161226584Sdim NewBits[i] = UnsetInit::get(); 162226584Sdim 163226584Sdim return BitsInit::get(NewBits); 164226584Sdim} 165226584Sdim 166226584SdimInit *BitsRecTy::convertValue(BitInit *UI) { 167276479Sdim if (Size != 1) return nullptr; // Can only convert single bit. 168276479Sdim return BitsInit::get(UI); 169226584Sdim} 170226584Sdim 171226584Sdim/// canFitInBitfield - Return true if the number of bits is large enough to hold 172226584Sdim/// the integer value. 173226584Sdimstatic bool canFitInBitfield(int64_t Value, unsigned NumBits) { 174226584Sdim // For example, with NumBits == 4, we permit Values from [-7 .. 15]. 175226584Sdim return (NumBits >= sizeof(Value) * 8) || 176226584Sdim (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1); 177226584Sdim} 178226584Sdim 179226584Sdim/// convertValue from Int initializer to bits type: Split the integer up into the 180226584Sdim/// appropriate bits. 181226584Sdim/// 182226584SdimInit *BitsRecTy::convertValue(IntInit *II) { 183226584Sdim int64_t Value = II->getValue(); 184226584Sdim // Make sure this bitfield is large enough to hold the integer value. 185226584Sdim if (!canFitInBitfield(Value, Size)) 186276479Sdim return nullptr; 187226584Sdim 188226584Sdim SmallVector<Init *, 16> NewBits(Size); 189226584Sdim 190226584Sdim for (unsigned i = 0; i != Size; ++i) 191226584Sdim NewBits[i] = BitInit::get(Value & (1LL << i)); 192226584Sdim 193226584Sdim return BitsInit::get(NewBits); 194226584Sdim} 195226584Sdim 196226584SdimInit *BitsRecTy::convertValue(BitsInit *BI) { 197226584Sdim // If the number of bits is right, return it. Otherwise we need to expand or 198226584Sdim // truncate. 199226584Sdim if (BI->getNumBits() == Size) return BI; 200276479Sdim return nullptr; 201226584Sdim} 202226584Sdim 203226584SdimInit *BitsRecTy::convertValue(TypedInit *VI) { 204243830Sdim if (Size == 1 && isa<BitRecTy>(VI->getType())) 205226584Sdim return BitsInit::get(VI); 206226584Sdim 207243830Sdim if (VI->getType()->typeIsConvertibleTo(this)) { 208243830Sdim SmallVector<Init *, 16> NewBits(Size); 209226584Sdim 210243830Sdim for (unsigned i = 0; i != Size; ++i) 211243830Sdim NewBits[i] = VarBitInit::get(VI, i); 212243830Sdim return BitsInit::get(NewBits); 213226584Sdim } 214226584Sdim 215276479Sdim return nullptr; 216226584Sdim} 217226584Sdim 218249423Sdimbool BitsRecTy::baseClassOf(const RecTy *RHS) const{ 219249423Sdim if (RecTy::baseClassOf(RHS)) //argument and the receiver are the same type 220249423Sdim return cast<BitsRecTy>(RHS)->Size == Size; 221249423Sdim RecTyKind kind = RHS->getRecTyKind(); 222249423Sdim return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind); 223249423Sdim} 224249423Sdim 225226584SdimInit *IntRecTy::convertValue(BitInit *BI) { 226226584Sdim return IntInit::get(BI->getValue()); 227226584Sdim} 228226584Sdim 229226584SdimInit *IntRecTy::convertValue(BitsInit *BI) { 230226584Sdim int64_t Result = 0; 231226584Sdim for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 232243830Sdim if (BitInit *Bit = dyn_cast<BitInit>(BI->getBit(i))) { 233226584Sdim Result |= Bit->getValue() << i; 234226584Sdim } else { 235276479Sdim return nullptr; 236226584Sdim } 237226584Sdim return IntInit::get(Result); 238226584Sdim} 239226584Sdim 240226584SdimInit *IntRecTy::convertValue(TypedInit *TI) { 241226584Sdim if (TI->getType()->typeIsConvertibleTo(this)) 242226584Sdim return TI; // Accept variable if already of the right type! 243276479Sdim return nullptr; 244226584Sdim} 245226584Sdim 246249423Sdimbool IntRecTy::baseClassOf(const RecTy *RHS) const{ 247249423Sdim RecTyKind kind = RHS->getRecTyKind(); 248249423Sdim return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind; 249249423Sdim} 250249423Sdim 251226584SdimInit *StringRecTy::convertValue(UnOpInit *BO) { 252226584Sdim if (BO->getOpcode() == UnOpInit::CAST) { 253226584Sdim Init *L = BO->getOperand()->convertInitializerTo(this); 254276479Sdim if (!L) return nullptr; 255226584Sdim if (L != BO->getOperand()) 256226584Sdim return UnOpInit::get(UnOpInit::CAST, L, new StringRecTy); 257226584Sdim return BO; 258226584Sdim } 259226584Sdim 260226584Sdim return convertValue((TypedInit*)BO); 261226584Sdim} 262226584Sdim 263226584SdimInit *StringRecTy::convertValue(BinOpInit *BO) { 264226584Sdim if (BO->getOpcode() == BinOpInit::STRCONCAT) { 265226584Sdim Init *L = BO->getLHS()->convertInitializerTo(this); 266226584Sdim Init *R = BO->getRHS()->convertInitializerTo(this); 267276479Sdim if (!L || !R) return nullptr; 268226584Sdim if (L != BO->getLHS() || R != BO->getRHS()) 269226584Sdim return BinOpInit::get(BinOpInit::STRCONCAT, L, R, new StringRecTy); 270226584Sdim return BO; 271226584Sdim } 272226584Sdim 273226584Sdim return convertValue((TypedInit*)BO); 274226584Sdim} 275226584Sdim 276226584Sdim 277226584SdimInit *StringRecTy::convertValue(TypedInit *TI) { 278243830Sdim if (isa<StringRecTy>(TI->getType())) 279226584Sdim return TI; // Accept variable if already of the right type! 280276479Sdim return nullptr; 281226584Sdim} 282226584Sdim 283226584Sdimstd::string ListRecTy::getAsString() const { 284226584Sdim return "list<" + Ty->getAsString() + ">"; 285226584Sdim} 286226584Sdim 287226584SdimInit *ListRecTy::convertValue(ListInit *LI) { 288226584Sdim std::vector<Init*> Elements; 289226584Sdim 290226584Sdim // Verify that all of the elements of the list are subclasses of the 291226584Sdim // appropriate class! 292226584Sdim for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 293226584Sdim if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty)) 294226584Sdim Elements.push_back(CI); 295226584Sdim else 296276479Sdim return nullptr; 297226584Sdim 298243830Sdim if (!isa<ListRecTy>(LI->getType())) 299276479Sdim return nullptr; 300226584Sdim 301226584Sdim return ListInit::get(Elements, this); 302226584Sdim} 303226584Sdim 304226584SdimInit *ListRecTy::convertValue(TypedInit *TI) { 305226584Sdim // Ensure that TI is compatible with our class. 306243830Sdim if (ListRecTy *LRT = dyn_cast<ListRecTy>(TI->getType())) 307226584Sdim if (LRT->getElementType()->typeIsConvertibleTo(getElementType())) 308226584Sdim return TI; 309276479Sdim return nullptr; 310226584Sdim} 311226584Sdim 312249423Sdimbool ListRecTy::baseClassOf(const RecTy *RHS) const{ 313249423Sdim if(const ListRecTy* ListTy = dyn_cast<ListRecTy>(RHS)) 314249423Sdim return ListTy->getElementType()->typeIsConvertibleTo(Ty); 315249423Sdim return false; 316249423Sdim} 317249423Sdim 318226584SdimInit *DagRecTy::convertValue(TypedInit *TI) { 319226584Sdim if (TI->getType()->typeIsConvertibleTo(this)) 320226584Sdim return TI; 321276479Sdim return nullptr; 322226584Sdim} 323226584Sdim 324226584SdimInit *DagRecTy::convertValue(UnOpInit *BO) { 325226584Sdim if (BO->getOpcode() == UnOpInit::CAST) { 326226584Sdim Init *L = BO->getOperand()->convertInitializerTo(this); 327276479Sdim if (!L) return nullptr; 328226584Sdim if (L != BO->getOperand()) 329226584Sdim return UnOpInit::get(UnOpInit::CAST, L, new DagRecTy); 330226584Sdim return BO; 331226584Sdim } 332276479Sdim return nullptr; 333226584Sdim} 334226584Sdim 335226584SdimInit *DagRecTy::convertValue(BinOpInit *BO) { 336226584Sdim if (BO->getOpcode() == BinOpInit::CONCAT) { 337226584Sdim Init *L = BO->getLHS()->convertInitializerTo(this); 338226584Sdim Init *R = BO->getRHS()->convertInitializerTo(this); 339276479Sdim if (!L || !R) return nullptr; 340226584Sdim if (L != BO->getLHS() || R != BO->getRHS()) 341226584Sdim return BinOpInit::get(BinOpInit::CONCAT, L, R, new DagRecTy); 342226584Sdim return BO; 343226584Sdim } 344276479Sdim return nullptr; 345226584Sdim} 346226584Sdim 347226584SdimRecordRecTy *RecordRecTy::get(Record *R) { 348243830Sdim return dyn_cast<RecordRecTy>(R->getDefInit()->getType()); 349226584Sdim} 350226584Sdim 351226584Sdimstd::string RecordRecTy::getAsString() const { 352226584Sdim return Rec->getName(); 353226584Sdim} 354226584Sdim 355226584SdimInit *RecordRecTy::convertValue(DefInit *DI) { 356226584Sdim // Ensure that DI is a subclass of Rec. 357226584Sdim if (!DI->getDef()->isSubClassOf(Rec)) 358276479Sdim return nullptr; 359226584Sdim return DI; 360226584Sdim} 361226584Sdim 362226584SdimInit *RecordRecTy::convertValue(TypedInit *TI) { 363226584Sdim // Ensure that TI is compatible with Rec. 364243830Sdim if (RecordRecTy *RRT = dyn_cast<RecordRecTy>(TI->getType())) 365226584Sdim if (RRT->getRecord()->isSubClassOf(getRecord()) || 366226584Sdim RRT->getRecord() == getRecord()) 367226584Sdim return TI; 368276479Sdim return nullptr; 369226584Sdim} 370226584Sdim 371249423Sdimbool RecordRecTy::baseClassOf(const RecTy *RHS) const{ 372249423Sdim const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS); 373249423Sdim if (!RTy) 374249423Sdim return false; 375249423Sdim 376249423Sdim if (Rec == RTy->getRecord() || RTy->getRecord()->isSubClassOf(Rec)) 377226584Sdim return true; 378226584Sdim 379226584Sdim const std::vector<Record*> &SC = Rec->getSuperClasses(); 380226584Sdim for (unsigned i = 0, e = SC.size(); i != e; ++i) 381249423Sdim if (RTy->getRecord()->isSubClassOf(SC[i])) 382226584Sdim return true; 383226584Sdim 384226584Sdim return false; 385226584Sdim} 386226584Sdim 387226584Sdim/// resolveTypes - Find a common type that T1 and T2 convert to. 388226584Sdim/// Return 0 if no such type exists. 389226584Sdim/// 390226584SdimRecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { 391243830Sdim if (T1->typeIsConvertibleTo(T2)) 392243830Sdim return T2; 393243830Sdim if (T2->typeIsConvertibleTo(T1)) 394243830Sdim return T1; 395243830Sdim 396243830Sdim // If one is a Record type, check superclasses 397243830Sdim if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) { 398243830Sdim // See if T2 inherits from a type T1 also inherits from 399243830Sdim const std::vector<Record *> &T1SuperClasses = 400243830Sdim RecTy1->getRecord()->getSuperClasses(); 401243830Sdim for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(), 402243830Sdim iend = T1SuperClasses.end(); 403243830Sdim i != iend; 404243830Sdim ++i) { 405243830Sdim RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i); 406243830Sdim RecTy *NewType1 = resolveTypes(SuperRecTy1, T2); 407276479Sdim if (NewType1) { 408243830Sdim if (NewType1 != SuperRecTy1) { 409243830Sdim delete SuperRecTy1; 410226584Sdim } 411243830Sdim return NewType1; 412226584Sdim } 413243830Sdim } 414243830Sdim } 415243830Sdim if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) { 416243830Sdim // See if T1 inherits from a type T2 also inherits from 417243830Sdim const std::vector<Record *> &T2SuperClasses = 418243830Sdim RecTy2->getRecord()->getSuperClasses(); 419243830Sdim for (std::vector<Record *>::const_iterator i = T2SuperClasses.begin(), 420243830Sdim iend = T2SuperClasses.end(); 421243830Sdim i != iend; 422243830Sdim ++i) { 423243830Sdim RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i); 424243830Sdim RecTy *NewType2 = resolveTypes(T1, SuperRecTy2); 425276479Sdim if (NewType2) { 426243830Sdim if (NewType2 != SuperRecTy2) { 427243830Sdim delete SuperRecTy2; 428226584Sdim } 429243830Sdim return NewType2; 430226584Sdim } 431226584Sdim } 432226584Sdim } 433276479Sdim return nullptr; 434226584Sdim} 435226584Sdim 436226584Sdim 437226584Sdim//===----------------------------------------------------------------------===// 438226584Sdim// Initializer implementations 439226584Sdim//===----------------------------------------------------------------------===// 440226584Sdim 441234353Sdimvoid Init::anchor() { } 442226584Sdimvoid Init::dump() const { return print(errs()); } 443226584Sdim 444234353Sdimvoid UnsetInit::anchor() { } 445234353Sdim 446226584SdimUnsetInit *UnsetInit::get() { 447226584Sdim static UnsetInit TheInit; 448226584Sdim return &TheInit; 449226584Sdim} 450226584Sdim 451234353Sdimvoid BitInit::anchor() { } 452234353Sdim 453226584SdimBitInit *BitInit::get(bool V) { 454226584Sdim static BitInit True(true); 455226584Sdim static BitInit False(false); 456226584Sdim 457226584Sdim return V ? &True : &False; 458226584Sdim} 459226584Sdim 460226584Sdimstatic void 461226584SdimProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) { 462226584Sdim ID.AddInteger(Range.size()); 463226584Sdim 464226584Sdim for (ArrayRef<Init *>::iterator i = Range.begin(), 465226584Sdim iend = Range.end(); 466226584Sdim i != iend; 467226584Sdim ++i) 468226584Sdim ID.AddPointer(*i); 469226584Sdim} 470226584Sdim 471226584SdimBitsInit *BitsInit::get(ArrayRef<Init *> Range) { 472226584Sdim typedef FoldingSet<BitsInit> Pool; 473226584Sdim static Pool ThePool; 474226584Sdim 475226584Sdim FoldingSetNodeID ID; 476226584Sdim ProfileBitsInit(ID, Range); 477226584Sdim 478276479Sdim void *IP = nullptr; 479226584Sdim if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 480226584Sdim return I; 481226584Sdim 482226584Sdim BitsInit *I = new BitsInit(Range); 483226584Sdim ThePool.InsertNode(I, IP); 484226584Sdim 485226584Sdim return I; 486226584Sdim} 487226584Sdim 488226584Sdimvoid BitsInit::Profile(FoldingSetNodeID &ID) const { 489226584Sdim ProfileBitsInit(ID, Bits); 490226584Sdim} 491226584Sdim 492226584SdimInit * 493226584SdimBitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 494226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 495226584Sdim 496226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 497226584Sdim if (Bits[i] >= getNumBits()) 498276479Sdim return nullptr; 499226584Sdim NewBits[i] = getBit(Bits[i]); 500226584Sdim } 501226584Sdim return BitsInit::get(NewBits); 502226584Sdim} 503226584Sdim 504226584Sdimstd::string BitsInit::getAsString() const { 505226584Sdim std::string Result = "{ "; 506226584Sdim for (unsigned i = 0, e = getNumBits(); i != e; ++i) { 507226584Sdim if (i) Result += ", "; 508226584Sdim if (Init *Bit = getBit(e-i-1)) 509226584Sdim Result += Bit->getAsString(); 510226584Sdim else 511226584Sdim Result += "*"; 512226584Sdim } 513226584Sdim return Result + " }"; 514226584Sdim} 515226584Sdim 516243830Sdim// Fix bit initializer to preserve the behavior that bit reference from a unset 517243830Sdim// bits initializer will resolve into VarBitInit to keep the field name and bit 518243830Sdim// number used in targets with fixed insn length. 519243830Sdimstatic Init *fixBitInit(const RecordVal *RV, Init *Before, Init *After) { 520243830Sdim if (RV || After != UnsetInit::get()) 521243830Sdim return After; 522243830Sdim return Before; 523243830Sdim} 524243830Sdim 525226584Sdim// resolveReferences - If there are any field references that refer to fields 526226584Sdim// that have been filled in, we can propagate the values now. 527226584Sdim// 528226584SdimInit *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const { 529226584Sdim bool Changed = false; 530226584Sdim SmallVector<Init *, 16> NewBits(getNumBits()); 531226584Sdim 532276479Sdim Init *CachedInit = nullptr; 533276479Sdim Init *CachedBitVar = nullptr; 534243830Sdim bool CachedBitVarChanged = false; 535243830Sdim 536243830Sdim for (unsigned i = 0, e = getNumBits(); i != e; ++i) { 537243830Sdim Init *CurBit = Bits[i]; 538243830Sdim Init *CurBitVar = CurBit->getBitVar(); 539243830Sdim 540243830Sdim NewBits[i] = CurBit; 541243830Sdim 542243830Sdim if (CurBitVar == CachedBitVar) { 543243830Sdim if (CachedBitVarChanged) { 544243830Sdim Init *Bit = CachedInit->getBit(CurBit->getBitNum()); 545243830Sdim NewBits[i] = fixBitInit(RV, CurBit, Bit); 546243830Sdim } 547243830Sdim continue; 548243830Sdim } 549243830Sdim CachedBitVar = CurBitVar; 550243830Sdim CachedBitVarChanged = false; 551243830Sdim 552226584Sdim Init *B; 553243830Sdim do { 554243830Sdim B = CurBitVar; 555243830Sdim CurBitVar = CurBitVar->resolveReferences(R, RV); 556243830Sdim CachedBitVarChanged |= B != CurBitVar; 557243830Sdim Changed |= B != CurBitVar; 558243830Sdim } while (B != CurBitVar); 559243830Sdim CachedInit = CurBitVar; 560226584Sdim 561243830Sdim if (CachedBitVarChanged) { 562243830Sdim Init *Bit = CurBitVar->getBit(CurBit->getBitNum()); 563243830Sdim NewBits[i] = fixBitInit(RV, CurBit, Bit); 564243830Sdim } 565226584Sdim } 566226584Sdim 567226584Sdim if (Changed) 568226584Sdim return BitsInit::get(NewBits); 569226584Sdim 570226584Sdim return const_cast<BitsInit *>(this); 571226584Sdim} 572226584Sdim 573261991Sdimnamespace { 574261991Sdim template<typename T> 575261991Sdim class Pool : public T { 576261991Sdim public: 577261991Sdim ~Pool(); 578261991Sdim }; 579261991Sdim template<typename T> 580261991Sdim Pool<T>::~Pool() { 581261991Sdim for (typename T::iterator I = this->begin(), E = this->end(); I != E; ++I) { 582261991Sdim typename T::value_type &Item = *I; 583261991Sdim delete Item.second; 584261991Sdim } 585261991Sdim } 586261991Sdim} 587261991Sdim 588226584SdimIntInit *IntInit::get(int64_t V) { 589261991Sdim static Pool<DenseMap<int64_t, IntInit *> > ThePool; 590226584Sdim 591226584Sdim IntInit *&I = ThePool[V]; 592226584Sdim if (!I) I = new IntInit(V); 593226584Sdim return I; 594226584Sdim} 595226584Sdim 596226584Sdimstd::string IntInit::getAsString() const { 597226584Sdim return itostr(Value); 598226584Sdim} 599226584Sdim 600226584SdimInit * 601226584SdimIntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 602226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 603226584Sdim 604226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 605226584Sdim if (Bits[i] >= 64) 606276479Sdim return nullptr; 607226584Sdim 608226584Sdim NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i])); 609226584Sdim } 610226584Sdim return BitsInit::get(NewBits); 611226584Sdim} 612226584Sdim 613234353Sdimvoid StringInit::anchor() { } 614234353Sdim 615234353SdimStringInit *StringInit::get(StringRef V) { 616261991Sdim static Pool<StringMap<StringInit *> > ThePool; 617226584Sdim 618226584Sdim StringInit *&I = ThePool[V]; 619226584Sdim if (!I) I = new StringInit(V); 620226584Sdim return I; 621226584Sdim} 622226584Sdim 623226584Sdimstatic void ProfileListInit(FoldingSetNodeID &ID, 624226584Sdim ArrayRef<Init *> Range, 625226584Sdim RecTy *EltTy) { 626226584Sdim ID.AddInteger(Range.size()); 627226584Sdim ID.AddPointer(EltTy); 628226584Sdim 629226584Sdim for (ArrayRef<Init *>::iterator i = Range.begin(), 630226584Sdim iend = Range.end(); 631226584Sdim i != iend; 632226584Sdim ++i) 633226584Sdim ID.AddPointer(*i); 634226584Sdim} 635226584Sdim 636226584SdimListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { 637226584Sdim typedef FoldingSet<ListInit> Pool; 638226584Sdim static Pool ThePool; 639276479Sdim static std::vector<std::unique_ptr<ListInit>> TheActualPool; 640226584Sdim 641226584Sdim FoldingSetNodeID ID; 642226584Sdim ProfileListInit(ID, Range, EltTy); 643226584Sdim 644276479Sdim void *IP = nullptr; 645226584Sdim if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 646226584Sdim return I; 647226584Sdim 648226584Sdim ListInit *I = new ListInit(Range, EltTy); 649226584Sdim ThePool.InsertNode(I, IP); 650276479Sdim TheActualPool.push_back(std::unique_ptr<ListInit>(I)); 651226584Sdim return I; 652226584Sdim} 653226584Sdim 654226584Sdimvoid ListInit::Profile(FoldingSetNodeID &ID) const { 655243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(getType()); 656226584Sdim assert(ListType && "Bad type for ListInit!"); 657226584Sdim RecTy *EltTy = ListType->getElementType(); 658226584Sdim 659226584Sdim ProfileListInit(ID, Values, EltTy); 660226584Sdim} 661226584Sdim 662226584SdimInit * 663226584SdimListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { 664226584Sdim std::vector<Init*> Vals; 665226584Sdim for (unsigned i = 0, e = Elements.size(); i != e; ++i) { 666226584Sdim if (Elements[i] >= getSize()) 667276479Sdim return nullptr; 668226584Sdim Vals.push_back(getElement(Elements[i])); 669226584Sdim } 670226584Sdim return ListInit::get(Vals, getType()); 671226584Sdim} 672226584Sdim 673226584SdimRecord *ListInit::getElementAsRecord(unsigned i) const { 674226584Sdim assert(i < Values.size() && "List element index out of range!"); 675243830Sdim DefInit *DI = dyn_cast<DefInit>(Values[i]); 676276479Sdim if (!DI) 677243830Sdim PrintFatalError("Expected record in list!"); 678226584Sdim return DI->getDef(); 679226584Sdim} 680226584Sdim 681226584SdimInit *ListInit::resolveReferences(Record &R, const RecordVal *RV) const { 682226584Sdim std::vector<Init*> Resolved; 683226584Sdim Resolved.reserve(getSize()); 684226584Sdim bool Changed = false; 685226584Sdim 686226584Sdim for (unsigned i = 0, e = getSize(); i != e; ++i) { 687226584Sdim Init *E; 688226584Sdim Init *CurElt = getElement(i); 689226584Sdim 690226584Sdim do { 691226584Sdim E = CurElt; 692226584Sdim CurElt = CurElt->resolveReferences(R, RV); 693226584Sdim Changed |= E != CurElt; 694226584Sdim } while (E != CurElt); 695226584Sdim Resolved.push_back(E); 696226584Sdim } 697226584Sdim 698226584Sdim if (Changed) 699226584Sdim return ListInit::get(Resolved, getType()); 700226584Sdim return const_cast<ListInit *>(this); 701226584Sdim} 702226584Sdim 703226584SdimInit *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV, 704226584Sdim unsigned Elt) const { 705226584Sdim if (Elt >= getSize()) 706276479Sdim return nullptr; // Out of range reference. 707226584Sdim Init *E = getElement(Elt); 708226584Sdim // If the element is set to some value, or if we are resolving a reference 709226584Sdim // to a specific variable and that variable is explicitly unset, then 710226584Sdim // replace the VarListElementInit with it. 711243830Sdim if (IRV || !isa<UnsetInit>(E)) 712226584Sdim return E; 713276479Sdim return nullptr; 714226584Sdim} 715226584Sdim 716226584Sdimstd::string ListInit::getAsString() const { 717226584Sdim std::string Result = "["; 718226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) { 719226584Sdim if (i) Result += ", "; 720226584Sdim Result += Values[i]->getAsString(); 721226584Sdim } 722226584Sdim return Result + "]"; 723226584Sdim} 724226584Sdim 725226584SdimInit *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV, 726226584Sdim unsigned Elt) const { 727226584Sdim Init *Resolved = resolveReferences(R, IRV); 728243830Sdim OpInit *OResolved = dyn_cast<OpInit>(Resolved); 729226584Sdim if (OResolved) { 730276479Sdim Resolved = OResolved->Fold(&R, nullptr); 731226584Sdim } 732226584Sdim 733226584Sdim if (Resolved != this) { 734243830Sdim TypedInit *Typed = dyn_cast<TypedInit>(Resolved); 735226584Sdim assert(Typed && "Expected typed init for list reference"); 736226584Sdim if (Typed) { 737226584Sdim Init *New = Typed->resolveListElementReference(R, IRV, Elt); 738226584Sdim if (New) 739226584Sdim return New; 740226584Sdim return VarListElementInit::get(Typed, Elt); 741226584Sdim } 742226584Sdim } 743226584Sdim 744276479Sdim return nullptr; 745226584Sdim} 746226584Sdim 747243830SdimInit *OpInit::getBit(unsigned Bit) const { 748243830Sdim if (getType() == BitRecTy::get()) 749243830Sdim return const_cast<OpInit*>(this); 750243830Sdim return VarBitInit::get(const_cast<OpInit*>(this), Bit); 751243830Sdim} 752243830Sdim 753226584SdimUnOpInit *UnOpInit::get(UnaryOp opc, Init *lhs, RecTy *Type) { 754226584Sdim typedef std::pair<std::pair<unsigned, Init *>, RecTy *> Key; 755261991Sdim static Pool<DenseMap<Key, UnOpInit *> > ThePool; 756226584Sdim 757226584Sdim Key TheKey(std::make_pair(std::make_pair(opc, lhs), Type)); 758226584Sdim 759226584Sdim UnOpInit *&I = ThePool[TheKey]; 760226584Sdim if (!I) I = new UnOpInit(opc, lhs, Type); 761226584Sdim return I; 762226584Sdim} 763226584Sdim 764226584SdimInit *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 765226584Sdim switch (getOpcode()) { 766226584Sdim case CAST: { 767226584Sdim if (getType()->getAsString() == "string") { 768243830Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) 769226584Sdim return LHSs; 770226584Sdim 771243830Sdim if (DefInit *LHSd = dyn_cast<DefInit>(LHS)) 772226584Sdim return StringInit::get(LHSd->getDef()->getName()); 773234353Sdim 774243830Sdim if (IntInit *LHSi = dyn_cast<IntInit>(LHS)) 775234353Sdim return StringInit::get(LHSi->getAsString()); 776226584Sdim } else { 777243830Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) { 778226584Sdim std::string Name = LHSs->getValue(); 779226584Sdim 780226584Sdim // From TGParser::ParseIDValue 781226584Sdim if (CurRec) { 782226584Sdim if (const RecordVal *RV = CurRec->getValue(Name)) { 783226584Sdim if (RV->getType() != getType()) 784243830Sdim PrintFatalError("type mismatch in cast"); 785226584Sdim return VarInit::get(Name, RV->getType()); 786226584Sdim } 787226584Sdim 788234353Sdim Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, 789234353Sdim ":"); 790234353Sdim 791226584Sdim if (CurRec->isTemplateArg(TemplateArgName)) { 792226584Sdim const RecordVal *RV = CurRec->getValue(TemplateArgName); 793226584Sdim assert(RV && "Template arg doesn't exist??"); 794226584Sdim 795226584Sdim if (RV->getType() != getType()) 796243830Sdim PrintFatalError("type mismatch in cast"); 797226584Sdim 798226584Sdim return VarInit::get(TemplateArgName, RV->getType()); 799226584Sdim } 800226584Sdim } 801226584Sdim 802226584Sdim if (CurMultiClass) { 803234353Sdim Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); 804234353Sdim 805226584Sdim if (CurMultiClass->Rec.isTemplateArg(MCName)) { 806226584Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); 807226584Sdim assert(RV && "Template arg doesn't exist??"); 808226584Sdim 809226584Sdim if (RV->getType() != getType()) 810243830Sdim PrintFatalError("type mismatch in cast"); 811226584Sdim 812226584Sdim return VarInit::get(MCName, RV->getType()); 813226584Sdim } 814226584Sdim } 815280031Sdim assert(CurRec && "NULL pointer"); 816226584Sdim if (Record *D = (CurRec->getRecords()).getDef(Name)) 817226584Sdim return DefInit::get(D); 818226584Sdim 819243830Sdim PrintFatalError(CurRec->getLoc(), 820243830Sdim "Undefined reference:'" + Name + "'\n"); 821226584Sdim } 822226584Sdim } 823226584Sdim break; 824226584Sdim } 825226584Sdim case HEAD: { 826243830Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { 827276479Sdim assert(LHSl->getSize() != 0 && "Empty list in car"); 828226584Sdim return LHSl->getElement(0); 829226584Sdim } 830226584Sdim break; 831226584Sdim } 832226584Sdim case TAIL: { 833243830Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { 834276479Sdim assert(LHSl->getSize() != 0 && "Empty list in cdr"); 835226584Sdim // Note the +1. We can't just pass the result of getValues() 836226584Sdim // directly. 837226584Sdim ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1; 838226584Sdim ArrayRef<Init *>::iterator end = LHSl->getValues().end(); 839226584Sdim ListInit *Result = 840226584Sdim ListInit::get(ArrayRef<Init *>(begin, end - begin), 841226584Sdim LHSl->getType()); 842226584Sdim return Result; 843226584Sdim } 844226584Sdim break; 845226584Sdim } 846226584Sdim case EMPTY: { 847243830Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { 848226584Sdim if (LHSl->getSize() == 0) { 849226584Sdim return IntInit::get(1); 850226584Sdim } else { 851226584Sdim return IntInit::get(0); 852226584Sdim } 853226584Sdim } 854243830Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) { 855226584Sdim if (LHSs->getValue().empty()) { 856226584Sdim return IntInit::get(1); 857226584Sdim } else { 858226584Sdim return IntInit::get(0); 859226584Sdim } 860226584Sdim } 861226584Sdim 862226584Sdim break; 863226584Sdim } 864226584Sdim } 865226584Sdim return const_cast<UnOpInit *>(this); 866226584Sdim} 867226584Sdim 868226584SdimInit *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const { 869226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 870226584Sdim 871226584Sdim if (LHS != lhs) 872276479Sdim return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, nullptr); 873276479Sdim return Fold(&R, nullptr); 874226584Sdim} 875226584Sdim 876226584Sdimstd::string UnOpInit::getAsString() const { 877226584Sdim std::string Result; 878226584Sdim switch (Opc) { 879226584Sdim case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break; 880226584Sdim case HEAD: Result = "!head"; break; 881226584Sdim case TAIL: Result = "!tail"; break; 882226584Sdim case EMPTY: Result = "!empty"; break; 883226584Sdim } 884226584Sdim return Result + "(" + LHS->getAsString() + ")"; 885226584Sdim} 886226584Sdim 887226584SdimBinOpInit *BinOpInit::get(BinaryOp opc, Init *lhs, 888226584Sdim Init *rhs, RecTy *Type) { 889226584Sdim typedef std::pair< 890226584Sdim std::pair<std::pair<unsigned, Init *>, Init *>, 891226584Sdim RecTy * 892226584Sdim > Key; 893226584Sdim 894261991Sdim static Pool<DenseMap<Key, BinOpInit *> > ThePool; 895226584Sdim 896226584Sdim Key TheKey(std::make_pair(std::make_pair(std::make_pair(opc, lhs), rhs), 897226584Sdim Type)); 898226584Sdim 899226584Sdim BinOpInit *&I = ThePool[TheKey]; 900226584Sdim if (!I) I = new BinOpInit(opc, lhs, rhs, Type); 901226584Sdim return I; 902226584Sdim} 903226584Sdim 904226584SdimInit *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 905226584Sdim switch (getOpcode()) { 906226584Sdim case CONCAT: { 907243830Sdim DagInit *LHSs = dyn_cast<DagInit>(LHS); 908243830Sdim DagInit *RHSs = dyn_cast<DagInit>(RHS); 909226584Sdim if (LHSs && RHSs) { 910243830Sdim DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator()); 911243830Sdim DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator()); 912276479Sdim if (!LOp || !ROp || LOp->getDef() != ROp->getDef()) 913243830Sdim PrintFatalError("Concated Dag operators do not match!"); 914226584Sdim std::vector<Init*> Args; 915226584Sdim std::vector<std::string> ArgNames; 916226584Sdim for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) { 917226584Sdim Args.push_back(LHSs->getArg(i)); 918226584Sdim ArgNames.push_back(LHSs->getArgName(i)); 919226584Sdim } 920226584Sdim for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) { 921226584Sdim Args.push_back(RHSs->getArg(i)); 922226584Sdim ArgNames.push_back(RHSs->getArgName(i)); 923226584Sdim } 924226584Sdim return DagInit::get(LHSs->getOperator(), "", Args, ArgNames); 925226584Sdim } 926226584Sdim break; 927226584Sdim } 928276479Sdim case LISTCONCAT: { 929276479Sdim ListInit *LHSs = dyn_cast<ListInit>(LHS); 930276479Sdim ListInit *RHSs = dyn_cast<ListInit>(RHS); 931276479Sdim if (LHSs && RHSs) { 932276479Sdim std::vector<Init *> Args; 933276479Sdim Args.insert(Args.end(), LHSs->begin(), LHSs->end()); 934276479Sdim Args.insert(Args.end(), RHSs->begin(), RHSs->end()); 935276479Sdim return ListInit::get( 936276479Sdim Args, static_cast<ListRecTy *>(LHSs->getType())->getElementType()); 937276479Sdim } 938276479Sdim break; 939276479Sdim } 940226584Sdim case STRCONCAT: { 941243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 942243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 943226584Sdim if (LHSs && RHSs) 944226584Sdim return StringInit::get(LHSs->getValue() + RHSs->getValue()); 945226584Sdim break; 946226584Sdim } 947226584Sdim case EQ: { 948226584Sdim // try to fold eq comparison for 'bit' and 'int', otherwise fallback 949226584Sdim // to string objects. 950243830Sdim IntInit *L = 951243830Sdim dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); 952243830Sdim IntInit *R = 953243830Sdim dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); 954226584Sdim 955226584Sdim if (L && R) 956226584Sdim return IntInit::get(L->getValue() == R->getValue()); 957226584Sdim 958243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 959243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 960226584Sdim 961226584Sdim // Make sure we've resolved 962226584Sdim if (LHSs && RHSs) 963226584Sdim return IntInit::get(LHSs->getValue() == RHSs->getValue()); 964226584Sdim 965226584Sdim break; 966226584Sdim } 967249423Sdim case ADD: 968280031Sdim case AND: 969226584Sdim case SHL: 970226584Sdim case SRA: 971226584Sdim case SRL: { 972276479Sdim IntInit *LHSi = 973276479Sdim dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); 974276479Sdim IntInit *RHSi = 975276479Sdim dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); 976226584Sdim if (LHSi && RHSi) { 977226584Sdim int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); 978226584Sdim int64_t Result; 979226584Sdim switch (getOpcode()) { 980234353Sdim default: llvm_unreachable("Bad opcode!"); 981249423Sdim case ADD: Result = LHSv + RHSv; break; 982280031Sdim case AND: Result = LHSv & RHSv; break; 983226584Sdim case SHL: Result = LHSv << RHSv; break; 984226584Sdim case SRA: Result = LHSv >> RHSv; break; 985226584Sdim case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; 986226584Sdim } 987226584Sdim return IntInit::get(Result); 988226584Sdim } 989226584Sdim break; 990226584Sdim } 991226584Sdim } 992226584Sdim return const_cast<BinOpInit *>(this); 993226584Sdim} 994226584Sdim 995226584SdimInit *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const { 996226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 997226584Sdim Init *rhs = RHS->resolveReferences(R, RV); 998226584Sdim 999226584Sdim if (LHS != lhs || RHS != rhs) 1000276479Sdim return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R,nullptr); 1001276479Sdim return Fold(&R, nullptr); 1002226584Sdim} 1003226584Sdim 1004226584Sdimstd::string BinOpInit::getAsString() const { 1005226584Sdim std::string Result; 1006226584Sdim switch (Opc) { 1007226584Sdim case CONCAT: Result = "!con"; break; 1008249423Sdim case ADD: Result = "!add"; break; 1009280031Sdim case AND: Result = "!and"; break; 1010226584Sdim case SHL: Result = "!shl"; break; 1011226584Sdim case SRA: Result = "!sra"; break; 1012226584Sdim case SRL: Result = "!srl"; break; 1013226584Sdim case EQ: Result = "!eq"; break; 1014276479Sdim case LISTCONCAT: Result = "!listconcat"; break; 1015226584Sdim case STRCONCAT: Result = "!strconcat"; break; 1016226584Sdim } 1017226584Sdim return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; 1018226584Sdim} 1019226584Sdim 1020226584SdimTernOpInit *TernOpInit::get(TernaryOp opc, Init *lhs, 1021226584Sdim Init *mhs, Init *rhs, 1022226584Sdim RecTy *Type) { 1023226584Sdim typedef std::pair< 1024226584Sdim std::pair< 1025226584Sdim std::pair<std::pair<unsigned, RecTy *>, Init *>, 1026226584Sdim Init * 1027226584Sdim >, 1028226584Sdim Init * 1029226584Sdim > Key; 1030226584Sdim 1031226584Sdim typedef DenseMap<Key, TernOpInit *> Pool; 1032226584Sdim static Pool ThePool; 1033226584Sdim 1034226584Sdim Key TheKey(std::make_pair(std::make_pair(std::make_pair(std::make_pair(opc, 1035226584Sdim Type), 1036226584Sdim lhs), 1037226584Sdim mhs), 1038226584Sdim rhs)); 1039226584Sdim 1040226584Sdim TernOpInit *&I = ThePool[TheKey]; 1041226584Sdim if (!I) I = new TernOpInit(opc, lhs, mhs, rhs, Type); 1042226584Sdim return I; 1043226584Sdim} 1044226584Sdim 1045226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, 1046226584Sdim Record *CurRec, MultiClass *CurMultiClass); 1047226584Sdim 1048226584Sdimstatic Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg, 1049226584Sdim RecTy *Type, Record *CurRec, 1050226584Sdim MultiClass *CurMultiClass) { 1051226584Sdim std::vector<Init *> NewOperands; 1052226584Sdim 1053243830Sdim TypedInit *TArg = dyn_cast<TypedInit>(Arg); 1054226584Sdim 1055226584Sdim // If this is a dag, recurse 1056226584Sdim if (TArg && TArg->getType()->getAsString() == "dag") { 1057226584Sdim Init *Result = ForeachHelper(LHS, Arg, RHSo, Type, 1058226584Sdim CurRec, CurMultiClass); 1059276479Sdim return Result; 1060226584Sdim } 1061226584Sdim 1062226584Sdim for (int i = 0; i < RHSo->getNumOperands(); ++i) { 1063243830Sdim OpInit *RHSoo = dyn_cast<OpInit>(RHSo->getOperand(i)); 1064226584Sdim 1065226584Sdim if (RHSoo) { 1066226584Sdim Init *Result = EvaluateOperation(RHSoo, LHS, Arg, 1067226584Sdim Type, CurRec, CurMultiClass); 1068276479Sdim if (Result) { 1069226584Sdim NewOperands.push_back(Result); 1070226584Sdim } else { 1071226584Sdim NewOperands.push_back(Arg); 1072226584Sdim } 1073226584Sdim } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) { 1074226584Sdim NewOperands.push_back(Arg); 1075226584Sdim } else { 1076226584Sdim NewOperands.push_back(RHSo->getOperand(i)); 1077226584Sdim } 1078226584Sdim } 1079226584Sdim 1080226584Sdim // Now run the operator and use its result as the new leaf 1081226584Sdim const OpInit *NewOp = RHSo->clone(NewOperands); 1082226584Sdim Init *NewVal = NewOp->Fold(CurRec, CurMultiClass); 1083276479Sdim return (NewVal != NewOp) ? NewVal : nullptr; 1084226584Sdim} 1085226584Sdim 1086226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, 1087226584Sdim Record *CurRec, MultiClass *CurMultiClass) { 1088243830Sdim DagInit *MHSd = dyn_cast<DagInit>(MHS); 1089243830Sdim ListInit *MHSl = dyn_cast<ListInit>(MHS); 1090226584Sdim 1091243830Sdim OpInit *RHSo = dyn_cast<OpInit>(RHS); 1092226584Sdim 1093226584Sdim if (!RHSo) { 1094243830Sdim PrintFatalError(CurRec->getLoc(), "!foreach requires an operator\n"); 1095226584Sdim } 1096226584Sdim 1097243830Sdim TypedInit *LHSt = dyn_cast<TypedInit>(LHS); 1098226584Sdim 1099243830Sdim if (!LHSt) 1100243830Sdim PrintFatalError(CurRec->getLoc(), "!foreach requires typed variable\n"); 1101226584Sdim 1102243830Sdim if ((MHSd && isa<DagRecTy>(Type)) || (MHSl && isa<ListRecTy>(Type))) { 1103226584Sdim if (MHSd) { 1104226584Sdim Init *Val = MHSd->getOperator(); 1105226584Sdim Init *Result = EvaluateOperation(RHSo, LHS, Val, 1106226584Sdim Type, CurRec, CurMultiClass); 1107276479Sdim if (Result) { 1108226584Sdim Val = Result; 1109226584Sdim } 1110226584Sdim 1111226584Sdim std::vector<std::pair<Init *, std::string> > args; 1112226584Sdim for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) { 1113226584Sdim Init *Arg; 1114226584Sdim std::string ArgName; 1115226584Sdim Arg = MHSd->getArg(i); 1116226584Sdim ArgName = MHSd->getArgName(i); 1117226584Sdim 1118226584Sdim // Process args 1119226584Sdim Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type, 1120226584Sdim CurRec, CurMultiClass); 1121276479Sdim if (Result) { 1122226584Sdim Arg = Result; 1123226584Sdim } 1124226584Sdim 1125226584Sdim // TODO: Process arg names 1126226584Sdim args.push_back(std::make_pair(Arg, ArgName)); 1127226584Sdim } 1128226584Sdim 1129226584Sdim return DagInit::get(Val, "", args); 1130226584Sdim } 1131226584Sdim if (MHSl) { 1132226584Sdim std::vector<Init *> NewOperands; 1133226584Sdim std::vector<Init *> NewList(MHSl->begin(), MHSl->end()); 1134226584Sdim 1135226584Sdim for (std::vector<Init *>::iterator li = NewList.begin(), 1136226584Sdim liend = NewList.end(); 1137226584Sdim li != liend; 1138226584Sdim ++li) { 1139226584Sdim Init *Item = *li; 1140226584Sdim NewOperands.clear(); 1141226584Sdim for(int i = 0; i < RHSo->getNumOperands(); ++i) { 1142226584Sdim // First, replace the foreach variable with the list item 1143226584Sdim if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) { 1144226584Sdim NewOperands.push_back(Item); 1145226584Sdim } else { 1146226584Sdim NewOperands.push_back(RHSo->getOperand(i)); 1147226584Sdim } 1148226584Sdim } 1149226584Sdim 1150226584Sdim // Now run the operator and use its result as the new list item 1151226584Sdim const OpInit *NewOp = RHSo->clone(NewOperands); 1152226584Sdim Init *NewItem = NewOp->Fold(CurRec, CurMultiClass); 1153226584Sdim if (NewItem != NewOp) 1154226584Sdim *li = NewItem; 1155226584Sdim } 1156226584Sdim return ListInit::get(NewList, MHSl->getType()); 1157226584Sdim } 1158226584Sdim } 1159276479Sdim return nullptr; 1160226584Sdim} 1161226584Sdim 1162226584SdimInit *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 1163226584Sdim switch (getOpcode()) { 1164226584Sdim case SUBST: { 1165243830Sdim DefInit *LHSd = dyn_cast<DefInit>(LHS); 1166243830Sdim VarInit *LHSv = dyn_cast<VarInit>(LHS); 1167243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 1168226584Sdim 1169243830Sdim DefInit *MHSd = dyn_cast<DefInit>(MHS); 1170243830Sdim VarInit *MHSv = dyn_cast<VarInit>(MHS); 1171243830Sdim StringInit *MHSs = dyn_cast<StringInit>(MHS); 1172226584Sdim 1173243830Sdim DefInit *RHSd = dyn_cast<DefInit>(RHS); 1174243830Sdim VarInit *RHSv = dyn_cast<VarInit>(RHS); 1175243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 1176226584Sdim 1177226584Sdim if ((LHSd && MHSd && RHSd) 1178226584Sdim || (LHSv && MHSv && RHSv) 1179226584Sdim || (LHSs && MHSs && RHSs)) { 1180226584Sdim if (RHSd) { 1181226584Sdim Record *Val = RHSd->getDef(); 1182226584Sdim if (LHSd->getAsString() == RHSd->getAsString()) { 1183226584Sdim Val = MHSd->getDef(); 1184226584Sdim } 1185226584Sdim return DefInit::get(Val); 1186226584Sdim } 1187226584Sdim if (RHSv) { 1188226584Sdim std::string Val = RHSv->getName(); 1189226584Sdim if (LHSv->getAsString() == RHSv->getAsString()) { 1190226584Sdim Val = MHSv->getName(); 1191226584Sdim } 1192226584Sdim return VarInit::get(Val, getType()); 1193226584Sdim } 1194226584Sdim if (RHSs) { 1195226584Sdim std::string Val = RHSs->getValue(); 1196226584Sdim 1197226584Sdim std::string::size_type found; 1198226584Sdim std::string::size_type idx = 0; 1199226584Sdim do { 1200226584Sdim found = Val.find(LHSs->getValue(), idx); 1201226584Sdim if (found != std::string::npos) { 1202226584Sdim Val.replace(found, LHSs->getValue().size(), MHSs->getValue()); 1203226584Sdim } 1204226584Sdim idx = found + MHSs->getValue().size(); 1205226584Sdim } while (found != std::string::npos); 1206226584Sdim 1207226584Sdim return StringInit::get(Val); 1208226584Sdim } 1209226584Sdim } 1210226584Sdim break; 1211226584Sdim } 1212226584Sdim 1213226584Sdim case FOREACH: { 1214226584Sdim Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), 1215226584Sdim CurRec, CurMultiClass); 1216276479Sdim if (Result) { 1217226584Sdim return Result; 1218226584Sdim } 1219226584Sdim break; 1220226584Sdim } 1221226584Sdim 1222226584Sdim case IF: { 1223243830Sdim IntInit *LHSi = dyn_cast<IntInit>(LHS); 1224226584Sdim if (Init *I = LHS->convertInitializerTo(IntRecTy::get())) 1225243830Sdim LHSi = dyn_cast<IntInit>(I); 1226226584Sdim if (LHSi) { 1227226584Sdim if (LHSi->getValue()) { 1228226584Sdim return MHS; 1229226584Sdim } else { 1230226584Sdim return RHS; 1231226584Sdim } 1232226584Sdim } 1233226584Sdim break; 1234226584Sdim } 1235226584Sdim } 1236226584Sdim 1237226584Sdim return const_cast<TernOpInit *>(this); 1238226584Sdim} 1239226584Sdim 1240226584SdimInit *TernOpInit::resolveReferences(Record &R, 1241226584Sdim const RecordVal *RV) const { 1242226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 1243226584Sdim 1244226584Sdim if (Opc == IF && lhs != LHS) { 1245243830Sdim IntInit *Value = dyn_cast<IntInit>(lhs); 1246226584Sdim if (Init *I = lhs->convertInitializerTo(IntRecTy::get())) 1247243830Sdim Value = dyn_cast<IntInit>(I); 1248276479Sdim if (Value) { 1249226584Sdim // Short-circuit 1250226584Sdim if (Value->getValue()) { 1251226584Sdim Init *mhs = MHS->resolveReferences(R, RV); 1252226584Sdim return (TernOpInit::get(getOpcode(), lhs, mhs, 1253276479Sdim RHS, getType()))->Fold(&R, nullptr); 1254226584Sdim } else { 1255226584Sdim Init *rhs = RHS->resolveReferences(R, RV); 1256226584Sdim return (TernOpInit::get(getOpcode(), lhs, MHS, 1257276479Sdim rhs, getType()))->Fold(&R, nullptr); 1258226584Sdim } 1259226584Sdim } 1260226584Sdim } 1261226584Sdim 1262226584Sdim Init *mhs = MHS->resolveReferences(R, RV); 1263226584Sdim Init *rhs = RHS->resolveReferences(R, RV); 1264226584Sdim 1265226584Sdim if (LHS != lhs || MHS != mhs || RHS != rhs) 1266226584Sdim return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, 1267276479Sdim getType()))->Fold(&R, nullptr); 1268276479Sdim return Fold(&R, nullptr); 1269226584Sdim} 1270226584Sdim 1271226584Sdimstd::string TernOpInit::getAsString() const { 1272226584Sdim std::string Result; 1273226584Sdim switch (Opc) { 1274226584Sdim case SUBST: Result = "!subst"; break; 1275226584Sdim case FOREACH: Result = "!foreach"; break; 1276226584Sdim case IF: Result = "!if"; break; 1277226584Sdim } 1278226584Sdim return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " 1279226584Sdim + RHS->getAsString() + ")"; 1280226584Sdim} 1281226584Sdim 1282226584SdimRecTy *TypedInit::getFieldType(const std::string &FieldName) const { 1283243830Sdim if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) 1284243830Sdim if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName)) 1285226584Sdim return Field->getType(); 1286276479Sdim return nullptr; 1287226584Sdim} 1288226584Sdim 1289226584SdimInit * 1290226584SdimTypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 1291243830Sdim BitsRecTy *T = dyn_cast<BitsRecTy>(getType()); 1292276479Sdim if (!T) return nullptr; // Cannot subscript a non-bits variable. 1293226584Sdim unsigned NumBits = T->getNumBits(); 1294226584Sdim 1295226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 1296226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 1297226584Sdim if (Bits[i] >= NumBits) 1298276479Sdim return nullptr; 1299226584Sdim 1300226584Sdim NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]); 1301226584Sdim } 1302226584Sdim return BitsInit::get(NewBits); 1303226584Sdim} 1304226584Sdim 1305226584SdimInit * 1306226584SdimTypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { 1307243830Sdim ListRecTy *T = dyn_cast<ListRecTy>(getType()); 1308276479Sdim if (!T) return nullptr; // Cannot subscript a non-list variable. 1309226584Sdim 1310226584Sdim if (Elements.size() == 1) 1311226584Sdim return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]); 1312226584Sdim 1313226584Sdim std::vector<Init*> ListInits; 1314226584Sdim ListInits.reserve(Elements.size()); 1315226584Sdim for (unsigned i = 0, e = Elements.size(); i != e; ++i) 1316226584Sdim ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this), 1317226584Sdim Elements[i])); 1318226584Sdim return ListInit::get(ListInits, T); 1319226584Sdim} 1320226584Sdim 1321226584Sdim 1322226584SdimVarInit *VarInit::get(const std::string &VN, RecTy *T) { 1323234353Sdim Init *Value = StringInit::get(VN); 1324234353Sdim return VarInit::get(Value, T); 1325234353Sdim} 1326234353Sdim 1327234353SdimVarInit *VarInit::get(Init *VN, RecTy *T) { 1328234353Sdim typedef std::pair<RecTy *, Init *> Key; 1329261991Sdim static Pool<DenseMap<Key, VarInit *> > ThePool; 1330226584Sdim 1331226584Sdim Key TheKey(std::make_pair(T, VN)); 1332226584Sdim 1333226584Sdim VarInit *&I = ThePool[TheKey]; 1334226584Sdim if (!I) I = new VarInit(VN, T); 1335226584Sdim return I; 1336226584Sdim} 1337226584Sdim 1338234353Sdimconst std::string &VarInit::getName() const { 1339243830Sdim StringInit *NameString = dyn_cast<StringInit>(getNameInit()); 1340234353Sdim assert(NameString && "VarInit name is not a string!"); 1341234353Sdim return NameString->getValue(); 1342234353Sdim} 1343234353Sdim 1344243830SdimInit *VarInit::getBit(unsigned Bit) const { 1345243830Sdim if (getType() == BitRecTy::get()) 1346243830Sdim return const_cast<VarInit*>(this); 1347243830Sdim return VarBitInit::get(const_cast<VarInit*>(this), Bit); 1348226584Sdim} 1349226584Sdim 1350226584SdimInit *VarInit::resolveListElementReference(Record &R, 1351226584Sdim const RecordVal *IRV, 1352226584Sdim unsigned Elt) const { 1353276479Sdim if (R.isTemplateArg(getNameInit())) return nullptr; 1354276479Sdim if (IRV && IRV->getNameInit() != getNameInit()) return nullptr; 1355226584Sdim 1356234353Sdim RecordVal *RV = R.getValue(getNameInit()); 1357226584Sdim assert(RV && "Reference to a non-existent variable?"); 1358243830Sdim ListInit *LI = dyn_cast<ListInit>(RV->getValue()); 1359226584Sdim if (!LI) { 1360243830Sdim TypedInit *VI = dyn_cast<TypedInit>(RV->getValue()); 1361226584Sdim assert(VI && "Invalid list element!"); 1362226584Sdim return VarListElementInit::get(VI, Elt); 1363226584Sdim } 1364226584Sdim 1365226584Sdim if (Elt >= LI->getSize()) 1366276479Sdim return nullptr; // Out of range reference. 1367226584Sdim Init *E = LI->getElement(Elt); 1368226584Sdim // If the element is set to some value, or if we are resolving a reference 1369226584Sdim // to a specific variable and that variable is explicitly unset, then 1370226584Sdim // replace the VarListElementInit with it. 1371243830Sdim if (IRV || !isa<UnsetInit>(E)) 1372226584Sdim return E; 1373276479Sdim return nullptr; 1374226584Sdim} 1375226584Sdim 1376226584Sdim 1377226584SdimRecTy *VarInit::getFieldType(const std::string &FieldName) const { 1378243830Sdim if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType())) 1379226584Sdim if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) 1380226584Sdim return RV->getType(); 1381276479Sdim return nullptr; 1382226584Sdim} 1383226584Sdim 1384226584SdimInit *VarInit::getFieldInit(Record &R, const RecordVal *RV, 1385226584Sdim const std::string &FieldName) const { 1386243830Sdim if (isa<RecordRecTy>(getType())) 1387226584Sdim if (const RecordVal *Val = R.getValue(VarName)) { 1388243830Sdim if (RV != Val && (RV || isa<UnsetInit>(Val->getValue()))) 1389276479Sdim return nullptr; 1390226584Sdim Init *TheInit = Val->getValue(); 1391226584Sdim assert(TheInit != this && "Infinite loop detected!"); 1392226584Sdim if (Init *I = TheInit->getFieldInit(R, RV, FieldName)) 1393226584Sdim return I; 1394226584Sdim else 1395276479Sdim return nullptr; 1396226584Sdim } 1397276479Sdim return nullptr; 1398226584Sdim} 1399226584Sdim 1400226584Sdim/// resolveReferences - This method is used by classes that refer to other 1401226584Sdim/// variables which may not be defined at the time the expression is formed. 1402226584Sdim/// If a value is set for the variable later, this method will be called on 1403226584Sdim/// users of the value to allow the value to propagate out. 1404226584Sdim/// 1405226584SdimInit *VarInit::resolveReferences(Record &R, const RecordVal *RV) const { 1406226584Sdim if (RecordVal *Val = R.getValue(VarName)) 1407276479Sdim if (RV == Val || (!RV && !isa<UnsetInit>(Val->getValue()))) 1408226584Sdim return Val->getValue(); 1409226584Sdim return const_cast<VarInit *>(this); 1410226584Sdim} 1411226584Sdim 1412226584SdimVarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { 1413226584Sdim typedef std::pair<TypedInit *, unsigned> Key; 1414226584Sdim typedef DenseMap<Key, VarBitInit *> Pool; 1415226584Sdim 1416226584Sdim static Pool ThePool; 1417226584Sdim 1418226584Sdim Key TheKey(std::make_pair(T, B)); 1419226584Sdim 1420226584Sdim VarBitInit *&I = ThePool[TheKey]; 1421226584Sdim if (!I) I = new VarBitInit(T, B); 1422226584Sdim return I; 1423226584Sdim} 1424226584Sdim 1425226584Sdimstd::string VarBitInit::getAsString() const { 1426226584Sdim return TI->getAsString() + "{" + utostr(Bit) + "}"; 1427226584Sdim} 1428226584Sdim 1429226584SdimInit *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const { 1430243830Sdim Init *I = TI->resolveReferences(R, RV); 1431243830Sdim if (TI != I) 1432243830Sdim return I->getBit(getBitNum()); 1433243830Sdim 1434243830Sdim return const_cast<VarBitInit*>(this); 1435226584Sdim} 1436226584Sdim 1437226584SdimVarListElementInit *VarListElementInit::get(TypedInit *T, 1438226584Sdim unsigned E) { 1439226584Sdim typedef std::pair<TypedInit *, unsigned> Key; 1440226584Sdim typedef DenseMap<Key, VarListElementInit *> Pool; 1441226584Sdim 1442226584Sdim static Pool ThePool; 1443226584Sdim 1444226584Sdim Key TheKey(std::make_pair(T, E)); 1445226584Sdim 1446226584Sdim VarListElementInit *&I = ThePool[TheKey]; 1447226584Sdim if (!I) I = new VarListElementInit(T, E); 1448226584Sdim return I; 1449226584Sdim} 1450226584Sdim 1451226584Sdimstd::string VarListElementInit::getAsString() const { 1452226584Sdim return TI->getAsString() + "[" + utostr(Element) + "]"; 1453226584Sdim} 1454226584Sdim 1455226584SdimInit * 1456226584SdimVarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const { 1457226584Sdim if (Init *I = getVariable()->resolveListElementReference(R, RV, 1458226584Sdim getElementNum())) 1459226584Sdim return I; 1460226584Sdim return const_cast<VarListElementInit *>(this); 1461226584Sdim} 1462226584Sdim 1463243830SdimInit *VarListElementInit::getBit(unsigned Bit) const { 1464243830Sdim if (getType() == BitRecTy::get()) 1465243830Sdim return const_cast<VarListElementInit*>(this); 1466243830Sdim return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit); 1467226584Sdim} 1468226584Sdim 1469226584SdimInit *VarListElementInit:: resolveListElementReference(Record &R, 1470226584Sdim const RecordVal *RV, 1471226584Sdim unsigned Elt) const { 1472226584Sdim Init *Result = TI->resolveListElementReference(R, RV, Element); 1473226584Sdim 1474226584Sdim if (Result) { 1475243830Sdim if (TypedInit *TInit = dyn_cast<TypedInit>(Result)) { 1476226584Sdim Init *Result2 = TInit->resolveListElementReference(R, RV, Elt); 1477226584Sdim if (Result2) return Result2; 1478226584Sdim return new VarListElementInit(TInit, Elt); 1479226584Sdim } 1480226584Sdim return Result; 1481226584Sdim } 1482226584Sdim 1483276479Sdim return nullptr; 1484226584Sdim} 1485226584Sdim 1486226584SdimDefInit *DefInit::get(Record *R) { 1487226584Sdim return R->getDefInit(); 1488226584Sdim} 1489226584Sdim 1490226584SdimRecTy *DefInit::getFieldType(const std::string &FieldName) const { 1491226584Sdim if (const RecordVal *RV = Def->getValue(FieldName)) 1492226584Sdim return RV->getType(); 1493276479Sdim return nullptr; 1494226584Sdim} 1495226584Sdim 1496226584SdimInit *DefInit::getFieldInit(Record &R, const RecordVal *RV, 1497226584Sdim const std::string &FieldName) const { 1498226584Sdim return Def->getValue(FieldName)->getValue(); 1499226584Sdim} 1500226584Sdim 1501226584Sdim 1502226584Sdimstd::string DefInit::getAsString() const { 1503226584Sdim return Def->getName(); 1504226584Sdim} 1505226584Sdim 1506226584SdimFieldInit *FieldInit::get(Init *R, const std::string &FN) { 1507226584Sdim typedef std::pair<Init *, TableGenStringKey> Key; 1508226584Sdim typedef DenseMap<Key, FieldInit *> Pool; 1509226584Sdim static Pool ThePool; 1510226584Sdim 1511226584Sdim Key TheKey(std::make_pair(R, FN)); 1512226584Sdim 1513226584Sdim FieldInit *&I = ThePool[TheKey]; 1514226584Sdim if (!I) I = new FieldInit(R, FN); 1515226584Sdim return I; 1516226584Sdim} 1517226584Sdim 1518243830SdimInit *FieldInit::getBit(unsigned Bit) const { 1519243830Sdim if (getType() == BitRecTy::get()) 1520243830Sdim return const_cast<FieldInit*>(this); 1521243830Sdim return VarBitInit::get(const_cast<FieldInit*>(this), Bit); 1522226584Sdim} 1523226584Sdim 1524226584SdimInit *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV, 1525226584Sdim unsigned Elt) const { 1526226584Sdim if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName)) 1527243830Sdim if (ListInit *LI = dyn_cast<ListInit>(ListVal)) { 1528276479Sdim if (Elt >= LI->getSize()) return nullptr; 1529226584Sdim Init *E = LI->getElement(Elt); 1530226584Sdim 1531226584Sdim // If the element is set to some value, or if we are resolving a 1532226584Sdim // reference to a specific variable and that variable is explicitly 1533226584Sdim // unset, then replace the VarListElementInit with it. 1534243830Sdim if (RV || !isa<UnsetInit>(E)) 1535226584Sdim return E; 1536226584Sdim } 1537276479Sdim return nullptr; 1538226584Sdim} 1539226584Sdim 1540226584SdimInit *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const { 1541226584Sdim Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec; 1542226584Sdim 1543226584Sdim Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName); 1544226584Sdim if (BitsVal) { 1545226584Sdim Init *BVR = BitsVal->resolveReferences(R, RV); 1546226584Sdim return BVR->isComplete() ? BVR : const_cast<FieldInit *>(this); 1547226584Sdim } 1548226584Sdim 1549226584Sdim if (NewRec != Rec) { 1550226584Sdim return FieldInit::get(NewRec, FieldName); 1551226584Sdim } 1552226584Sdim return const_cast<FieldInit *>(this); 1553226584Sdim} 1554226584Sdim 1555249423Sdimstatic void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN, 1556249423Sdim ArrayRef<Init *> ArgRange, 1557249423Sdim ArrayRef<std::string> NameRange) { 1558226584Sdim ID.AddPointer(V); 1559226584Sdim ID.AddString(VN); 1560226584Sdim 1561226584Sdim ArrayRef<Init *>::iterator Arg = ArgRange.begin(); 1562226584Sdim ArrayRef<std::string>::iterator Name = NameRange.begin(); 1563226584Sdim while (Arg != ArgRange.end()) { 1564226584Sdim assert(Name != NameRange.end() && "Arg name underflow!"); 1565226584Sdim ID.AddPointer(*Arg++); 1566226584Sdim ID.AddString(*Name++); 1567226584Sdim } 1568226584Sdim assert(Name == NameRange.end() && "Arg name overflow!"); 1569226584Sdim} 1570226584Sdim 1571226584SdimDagInit * 1572226584SdimDagInit::get(Init *V, const std::string &VN, 1573226584Sdim ArrayRef<Init *> ArgRange, 1574226584Sdim ArrayRef<std::string> NameRange) { 1575226584Sdim typedef FoldingSet<DagInit> Pool; 1576226584Sdim static Pool ThePool; 1577226584Sdim 1578226584Sdim FoldingSetNodeID ID; 1579226584Sdim ProfileDagInit(ID, V, VN, ArgRange, NameRange); 1580226584Sdim 1581276479Sdim void *IP = nullptr; 1582226584Sdim if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 1583226584Sdim return I; 1584226584Sdim 1585226584Sdim DagInit *I = new DagInit(V, VN, ArgRange, NameRange); 1586226584Sdim ThePool.InsertNode(I, IP); 1587226584Sdim 1588226584Sdim return I; 1589226584Sdim} 1590226584Sdim 1591226584SdimDagInit * 1592226584SdimDagInit::get(Init *V, const std::string &VN, 1593226584Sdim const std::vector<std::pair<Init*, std::string> > &args) { 1594226584Sdim typedef std::pair<Init*, std::string> PairType; 1595226584Sdim 1596226584Sdim std::vector<Init *> Args; 1597226584Sdim std::vector<std::string> Names; 1598226584Sdim 1599226584Sdim for (std::vector<PairType>::const_iterator i = args.begin(), 1600226584Sdim iend = args.end(); 1601226584Sdim i != iend; 1602226584Sdim ++i) { 1603226584Sdim Args.push_back(i->first); 1604226584Sdim Names.push_back(i->second); 1605226584Sdim } 1606226584Sdim 1607226584Sdim return DagInit::get(V, VN, Args, Names); 1608226584Sdim} 1609226584Sdim 1610226584Sdimvoid DagInit::Profile(FoldingSetNodeID &ID) const { 1611226584Sdim ProfileDagInit(ID, Val, ValName, Args, ArgNames); 1612226584Sdim} 1613226584Sdim 1614226584SdimInit *DagInit::resolveReferences(Record &R, const RecordVal *RV) const { 1615226584Sdim std::vector<Init*> NewArgs; 1616226584Sdim for (unsigned i = 0, e = Args.size(); i != e; ++i) 1617226584Sdim NewArgs.push_back(Args[i]->resolveReferences(R, RV)); 1618226584Sdim 1619226584Sdim Init *Op = Val->resolveReferences(R, RV); 1620226584Sdim 1621226584Sdim if (Args != NewArgs || Op != Val) 1622226584Sdim return DagInit::get(Op, ValName, NewArgs, ArgNames); 1623226584Sdim 1624226584Sdim return const_cast<DagInit *>(this); 1625226584Sdim} 1626226584Sdim 1627226584Sdim 1628226584Sdimstd::string DagInit::getAsString() const { 1629226584Sdim std::string Result = "(" + Val->getAsString(); 1630226584Sdim if (!ValName.empty()) 1631226584Sdim Result += ":" + ValName; 1632226584Sdim if (Args.size()) { 1633226584Sdim Result += " " + Args[0]->getAsString(); 1634226584Sdim if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0]; 1635226584Sdim for (unsigned i = 1, e = Args.size(); i != e; ++i) { 1636226584Sdim Result += ", " + Args[i]->getAsString(); 1637226584Sdim if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i]; 1638226584Sdim } 1639226584Sdim } 1640226584Sdim return Result + ")"; 1641226584Sdim} 1642226584Sdim 1643226584Sdim 1644226584Sdim//===----------------------------------------------------------------------===// 1645226584Sdim// Other implementations 1646226584Sdim//===----------------------------------------------------------------------===// 1647226584Sdim 1648226584SdimRecordVal::RecordVal(Init *N, RecTy *T, unsigned P) 1649226584Sdim : Name(N), Ty(T), Prefix(P) { 1650226584Sdim Value = Ty->convertValue(UnsetInit::get()); 1651226584Sdim assert(Value && "Cannot create unset value for current type!"); 1652226584Sdim} 1653226584Sdim 1654226584SdimRecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P) 1655226584Sdim : Name(StringInit::get(N)), Ty(T), Prefix(P) { 1656226584Sdim Value = Ty->convertValue(UnsetInit::get()); 1657226584Sdim assert(Value && "Cannot create unset value for current type!"); 1658226584Sdim} 1659226584Sdim 1660226584Sdimconst std::string &RecordVal::getName() const { 1661243830Sdim StringInit *NameString = dyn_cast<StringInit>(Name); 1662226584Sdim assert(NameString && "RecordVal name is not a string!"); 1663226584Sdim return NameString->getValue(); 1664226584Sdim} 1665226584Sdim 1666226584Sdimvoid RecordVal::dump() const { errs() << *this; } 1667226584Sdim 1668226584Sdimvoid RecordVal::print(raw_ostream &OS, bool PrintSem) const { 1669226584Sdim if (getPrefix()) OS << "field "; 1670234353Sdim OS << *getType() << " " << getNameInitAsString(); 1671226584Sdim 1672226584Sdim if (getValue()) 1673226584Sdim OS << " = " << *getValue(); 1674226584Sdim 1675226584Sdim if (PrintSem) OS << ";\n"; 1676226584Sdim} 1677226584Sdim 1678226584Sdimunsigned Record::LastID = 0; 1679226584Sdim 1680234353Sdimvoid Record::init() { 1681234353Sdim checkName(); 1682234353Sdim 1683234353Sdim // Every record potentially has a def at the top. This value is 1684234353Sdim // replaced with the top-level def name at instantiation time. 1685234353Sdim RecordVal DN("NAME", StringRecTy::get(), 0); 1686234353Sdim addValue(DN); 1687234353Sdim} 1688234353Sdim 1689226584Sdimvoid Record::checkName() { 1690226584Sdim // Ensure the record name has string type. 1691243830Sdim const TypedInit *TypedName = dyn_cast<const TypedInit>(Name); 1692226584Sdim assert(TypedName && "Record name is not typed!"); 1693226584Sdim RecTy *Type = TypedName->getType(); 1694243830Sdim if (!isa<StringRecTy>(Type)) 1695243830Sdim PrintFatalError(getLoc(), "Record name is not a string!"); 1696226584Sdim} 1697226584Sdim 1698226584SdimDefInit *Record::getDefInit() { 1699226584Sdim if (!TheInit) 1700226584Sdim TheInit = new DefInit(this, new RecordRecTy(this)); 1701226584Sdim return TheInit; 1702226584Sdim} 1703226584Sdim 1704226584Sdimconst std::string &Record::getName() const { 1705243830Sdim const StringInit *NameString = dyn_cast<StringInit>(Name); 1706226584Sdim assert(NameString && "Record name is not a string!"); 1707226584Sdim return NameString->getValue(); 1708226584Sdim} 1709226584Sdim 1710226584Sdimvoid Record::setName(Init *NewName) { 1711234353Sdim Name = NewName; 1712226584Sdim checkName(); 1713226584Sdim // DO NOT resolve record values to the name at this point because 1714226584Sdim // there might be default values for arguments of this def. Those 1715226584Sdim // arguments might not have been resolved yet so we don't want to 1716226584Sdim // prematurely assume values for those arguments were not passed to 1717226584Sdim // this def. 1718226584Sdim // 1719226584Sdim // Nonetheless, it may be that some of this Record's values 1720226584Sdim // reference the record name. Indeed, the reason for having the 1721226584Sdim // record name be an Init is to provide this flexibility. The extra 1722226584Sdim // resolve steps after completely instantiating defs takes care of 1723226584Sdim // this. See TGParser::ParseDef and TGParser::ParseDefm. 1724226584Sdim} 1725226584Sdim 1726226584Sdimvoid Record::setName(const std::string &Name) { 1727226584Sdim setName(StringInit::get(Name)); 1728226584Sdim} 1729226584Sdim 1730226584Sdim/// resolveReferencesTo - If anything in this record refers to RV, replace the 1731226584Sdim/// reference to RV with the RHS of RV. If RV is null, we resolve all possible 1732226584Sdim/// references. 1733226584Sdimvoid Record::resolveReferencesTo(const RecordVal *RV) { 1734226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) { 1735234353Sdim if (RV == &Values[i]) // Skip resolve the same field as the given one 1736234353Sdim continue; 1737226584Sdim if (Init *V = Values[i].getValue()) 1738243830Sdim if (Values[i].setValue(V->resolveReferences(*this, RV))) 1739243830Sdim PrintFatalError(getLoc(), "Invalid value is found when setting '" 1740243830Sdim + Values[i].getNameInitAsString() 1741243830Sdim + "' after resolving references" 1742243830Sdim + (RV ? " against '" + RV->getNameInitAsString() 1743243830Sdim + "' of (" 1744243830Sdim + RV->getValue()->getAsUnquotedString() + ")" 1745243830Sdim : "") 1746243830Sdim + "\n"); 1747226584Sdim } 1748234353Sdim Init *OldName = getNameInit(); 1749234353Sdim Init *NewName = Name->resolveReferences(*this, RV); 1750234353Sdim if (NewName != OldName) { 1751234353Sdim // Re-register with RecordKeeper. 1752234353Sdim setName(NewName); 1753234353Sdim } 1754226584Sdim} 1755226584Sdim 1756226584Sdimvoid Record::dump() const { errs() << *this; } 1757226584Sdim 1758226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) { 1759234353Sdim OS << R.getNameInitAsString(); 1760226584Sdim 1761234353Sdim const std::vector<Init *> &TArgs = R.getTemplateArgs(); 1762226584Sdim if (!TArgs.empty()) { 1763226584Sdim OS << "<"; 1764226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 1765226584Sdim if (i) OS << ", "; 1766226584Sdim const RecordVal *RV = R.getValue(TArgs[i]); 1767226584Sdim assert(RV && "Template argument record not found??"); 1768226584Sdim RV->print(OS, false); 1769226584Sdim } 1770226584Sdim OS << ">"; 1771226584Sdim } 1772226584Sdim 1773226584Sdim OS << " {"; 1774226584Sdim const std::vector<Record*> &SC = R.getSuperClasses(); 1775226584Sdim if (!SC.empty()) { 1776226584Sdim OS << "\t//"; 1777226584Sdim for (unsigned i = 0, e = SC.size(); i != e; ++i) 1778234353Sdim OS << " " << SC[i]->getNameInitAsString(); 1779226584Sdim } 1780226584Sdim OS << "\n"; 1781226584Sdim 1782226584Sdim const std::vector<RecordVal> &Vals = R.getValues(); 1783226584Sdim for (unsigned i = 0, e = Vals.size(); i != e; ++i) 1784226584Sdim if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName())) 1785226584Sdim OS << Vals[i]; 1786226584Sdim for (unsigned i = 0, e = Vals.size(); i != e; ++i) 1787226584Sdim if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName())) 1788226584Sdim OS << Vals[i]; 1789226584Sdim 1790226584Sdim return OS << "}\n"; 1791226584Sdim} 1792226584Sdim 1793226584Sdim/// getValueInit - Return the initializer for a value with the specified name, 1794243830Sdim/// or abort if the field does not exist. 1795226584Sdim/// 1796226584SdimInit *Record::getValueInit(StringRef FieldName) const { 1797226584Sdim const RecordVal *R = getValue(FieldName); 1798276479Sdim if (!R || !R->getValue()) 1799243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1800276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1801226584Sdim return R->getValue(); 1802226584Sdim} 1803226584Sdim 1804226584Sdim 1805226584Sdim/// getValueAsString - This method looks up the specified field and returns its 1806243830Sdim/// value as a string, aborts if the field does not exist or if 1807226584Sdim/// the value is not a string. 1808226584Sdim/// 1809226584Sdimstd::string Record::getValueAsString(StringRef FieldName) const { 1810226584Sdim const RecordVal *R = getValue(FieldName); 1811276479Sdim if (!R || !R->getValue()) 1812243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1813276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1814226584Sdim 1815243830Sdim if (StringInit *SI = dyn_cast<StringInit>(R->getValue())) 1816226584Sdim return SI->getValue(); 1817243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1818276479Sdim FieldName + "' does not have a string initializer!"); 1819226584Sdim} 1820226584Sdim 1821226584Sdim/// getValueAsBitsInit - This method looks up the specified field and returns 1822243830Sdim/// its value as a BitsInit, aborts if the field does not exist or if 1823243830Sdim/// the value is not the right type. 1824226584Sdim/// 1825226584SdimBitsInit *Record::getValueAsBitsInit(StringRef FieldName) const { 1826226584Sdim const RecordVal *R = getValue(FieldName); 1827276479Sdim if (!R || !R->getValue()) 1828243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1829276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1830226584Sdim 1831243830Sdim if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue())) 1832226584Sdim return BI; 1833243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1834276479Sdim FieldName + "' does not have a BitsInit initializer!"); 1835226584Sdim} 1836226584Sdim 1837226584Sdim/// getValueAsListInit - This method looks up the specified field and returns 1838243830Sdim/// its value as a ListInit, aborting if the field does not exist or if 1839243830Sdim/// the value is not the right type. 1840226584Sdim/// 1841226584SdimListInit *Record::getValueAsListInit(StringRef FieldName) const { 1842226584Sdim const RecordVal *R = getValue(FieldName); 1843276479Sdim if (!R || !R->getValue()) 1844243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1845276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1846226584Sdim 1847243830Sdim if (ListInit *LI = dyn_cast<ListInit>(R->getValue())) 1848226584Sdim return LI; 1849243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1850276479Sdim FieldName + "' does not have a list initializer!"); 1851226584Sdim} 1852226584Sdim 1853226584Sdim/// getValueAsListOfDefs - This method looks up the specified field and returns 1854243830Sdim/// its value as a vector of records, aborting if the field does not exist 1855243830Sdim/// or if the value is not the right type. 1856226584Sdim/// 1857226584Sdimstd::vector<Record*> 1858226584SdimRecord::getValueAsListOfDefs(StringRef FieldName) const { 1859226584Sdim ListInit *List = getValueAsListInit(FieldName); 1860226584Sdim std::vector<Record*> Defs; 1861226584Sdim for (unsigned i = 0; i < List->getSize(); i++) { 1862243830Sdim if (DefInit *DI = dyn_cast<DefInit>(List->getElement(i))) { 1863226584Sdim Defs.push_back(DI->getDef()); 1864226584Sdim } else { 1865243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1866276479Sdim FieldName + "' list is not entirely DefInit!"); 1867226584Sdim } 1868226584Sdim } 1869226584Sdim return Defs; 1870226584Sdim} 1871226584Sdim 1872226584Sdim/// getValueAsInt - This method looks up the specified field and returns its 1873243830Sdim/// value as an int64_t, aborting if the field does not exist or if the value 1874243830Sdim/// is not the right type. 1875226584Sdim/// 1876226584Sdimint64_t Record::getValueAsInt(StringRef FieldName) const { 1877226584Sdim const RecordVal *R = getValue(FieldName); 1878276479Sdim if (!R || !R->getValue()) 1879243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1880276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1881226584Sdim 1882243830Sdim if (IntInit *II = dyn_cast<IntInit>(R->getValue())) 1883226584Sdim return II->getValue(); 1884243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1885276479Sdim FieldName + "' does not have an int initializer!"); 1886226584Sdim} 1887226584Sdim 1888226584Sdim/// getValueAsListOfInts - This method looks up the specified field and returns 1889243830Sdim/// its value as a vector of integers, aborting if the field does not exist or 1890243830Sdim/// if the value is not the right type. 1891226584Sdim/// 1892226584Sdimstd::vector<int64_t> 1893226584SdimRecord::getValueAsListOfInts(StringRef FieldName) const { 1894226584Sdim ListInit *List = getValueAsListInit(FieldName); 1895226584Sdim std::vector<int64_t> Ints; 1896226584Sdim for (unsigned i = 0; i < List->getSize(); i++) { 1897243830Sdim if (IntInit *II = dyn_cast<IntInit>(List->getElement(i))) { 1898226584Sdim Ints.push_back(II->getValue()); 1899226584Sdim } else { 1900243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1901276479Sdim FieldName + "' does not have a list of ints initializer!"); 1902226584Sdim } 1903226584Sdim } 1904226584Sdim return Ints; 1905226584Sdim} 1906226584Sdim 1907226584Sdim/// getValueAsListOfStrings - This method looks up the specified field and 1908243830Sdim/// returns its value as a vector of strings, aborting if the field does not 1909243830Sdim/// exist or if the value is not the right type. 1910226584Sdim/// 1911226584Sdimstd::vector<std::string> 1912226584SdimRecord::getValueAsListOfStrings(StringRef FieldName) const { 1913226584Sdim ListInit *List = getValueAsListInit(FieldName); 1914226584Sdim std::vector<std::string> Strings; 1915226584Sdim for (unsigned i = 0; i < List->getSize(); i++) { 1916243830Sdim if (StringInit *II = dyn_cast<StringInit>(List->getElement(i))) { 1917226584Sdim Strings.push_back(II->getValue()); 1918226584Sdim } else { 1919243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1920276479Sdim FieldName + "' does not have a list of strings initializer!"); 1921226584Sdim } 1922226584Sdim } 1923226584Sdim return Strings; 1924226584Sdim} 1925226584Sdim 1926226584Sdim/// getValueAsDef - This method looks up the specified field and returns its 1927243830Sdim/// value as a Record, aborting if the field does not exist or if the value 1928243830Sdim/// is not the right type. 1929226584Sdim/// 1930226584SdimRecord *Record::getValueAsDef(StringRef FieldName) const { 1931226584Sdim const RecordVal *R = getValue(FieldName); 1932276479Sdim if (!R || !R->getValue()) 1933243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1934276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1935226584Sdim 1936243830Sdim if (DefInit *DI = dyn_cast<DefInit>(R->getValue())) 1937226584Sdim return DI->getDef(); 1938243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1939276479Sdim FieldName + "' does not have a def initializer!"); 1940226584Sdim} 1941226584Sdim 1942226584Sdim/// getValueAsBit - This method looks up the specified field and returns its 1943243830Sdim/// value as a bit, aborting if the field does not exist or if the value is 1944243830Sdim/// not the right type. 1945226584Sdim/// 1946226584Sdimbool Record::getValueAsBit(StringRef FieldName) const { 1947226584Sdim const RecordVal *R = getValue(FieldName); 1948276479Sdim if (!R || !R->getValue()) 1949243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1950276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1951226584Sdim 1952243830Sdim if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) 1953226584Sdim return BI->getValue(); 1954243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1955276479Sdim FieldName + "' does not have a bit initializer!"); 1956226584Sdim} 1957226584Sdim 1958243830Sdimbool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const { 1959243830Sdim const RecordVal *R = getValue(FieldName); 1960276479Sdim if (!R || !R->getValue()) 1961243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1962243830Sdim "' does not have a field named `" + FieldName.str() + "'!\n"); 1963243830Sdim 1964243830Sdim if (R->getValue() == UnsetInit::get()) { 1965243830Sdim Unset = true; 1966243830Sdim return false; 1967243830Sdim } 1968243830Sdim Unset = false; 1969243830Sdim if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) 1970243830Sdim return BI->getValue(); 1971243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1972276479Sdim FieldName + "' does not have a bit initializer!"); 1973243830Sdim} 1974243830Sdim 1975226584Sdim/// getValueAsDag - This method looks up the specified field and returns its 1976243830Sdim/// value as an Dag, aborting if the field does not exist or if the value is 1977243830Sdim/// not the right type. 1978226584Sdim/// 1979226584SdimDagInit *Record::getValueAsDag(StringRef FieldName) const { 1980226584Sdim const RecordVal *R = getValue(FieldName); 1981276479Sdim if (!R || !R->getValue()) 1982243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1983276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1984226584Sdim 1985243830Sdim if (DagInit *DI = dyn_cast<DagInit>(R->getValue())) 1986226584Sdim return DI; 1987243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1988276479Sdim FieldName + "' does not have a dag initializer!"); 1989226584Sdim} 1990226584Sdim 1991226584Sdim 1992226584Sdimvoid MultiClass::dump() const { 1993226584Sdim errs() << "Record:\n"; 1994226584Sdim Rec.dump(); 1995226584Sdim 1996226584Sdim errs() << "Defs:\n"; 1997226584Sdim for (RecordVector::const_iterator r = DefPrototypes.begin(), 1998226584Sdim rend = DefPrototypes.end(); 1999226584Sdim r != rend; 2000226584Sdim ++r) { 2001226584Sdim (*r)->dump(); 2002226584Sdim } 2003226584Sdim} 2004226584Sdim 2005226584Sdim 2006226584Sdimvoid RecordKeeper::dump() const { errs() << *this; } 2007226584Sdim 2008226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { 2009226584Sdim OS << "------------- Classes -----------------\n"; 2010280031Sdim const auto &Classes = RK.getClasses(); 2011280031Sdim for (const auto &C : Classes) 2012280031Sdim OS << "class " << *C.second; 2013226584Sdim 2014226584Sdim OS << "------------- Defs -----------------\n"; 2015280031Sdim const auto &Defs = RK.getDefs(); 2016280031Sdim for (const auto &D : Defs) 2017280031Sdim OS << "def " << *D.second; 2018226584Sdim return OS; 2019226584Sdim} 2020226584Sdim 2021226584Sdim 2022226584Sdim/// getAllDerivedDefinitions - This method returns all concrete definitions 2023226584Sdim/// that derive from the specified class name. If a class with the specified 2024226584Sdim/// name does not exist, an error is printed and true is returned. 2025226584Sdimstd::vector<Record*> 2026226584SdimRecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const { 2027226584Sdim Record *Class = getClass(ClassName); 2028226584Sdim if (!Class) 2029243830Sdim PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); 2030226584Sdim 2031226584Sdim std::vector<Record*> Defs; 2032280031Sdim for (const auto &D : getDefs()) 2033280031Sdim if (D.second->isSubClassOf(Class)) 2034280031Sdim Defs.push_back(D.second.get()); 2035226584Sdim 2036226584Sdim return Defs; 2037226584Sdim} 2038226584Sdim 2039234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 2040234353Sdim/// to CurRec's name. 2041234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, 2042234353Sdim Init *Name, const std::string &Scoper) { 2043243830Sdim RecTy *Type = dyn_cast<TypedInit>(Name)->getType(); 2044234353Sdim 2045234353Sdim BinOpInit *NewName = 2046234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2047234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2048234353Sdim CurRec.getNameInit(), 2049234353Sdim StringInit::get(Scoper), 2050234353Sdim Type)->Fold(&CurRec, CurMultiClass), 2051234353Sdim Name, 2052234353Sdim Type); 2053234353Sdim 2054234353Sdim if (CurMultiClass && Scoper != "::") { 2055234353Sdim NewName = 2056234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2057234353Sdim BinOpInit::get(BinOpInit::STRCONCAT, 2058234353Sdim CurMultiClass->Rec.getNameInit(), 2059234353Sdim StringInit::get("::"), 2060234353Sdim Type)->Fold(&CurRec, CurMultiClass), 2061234353Sdim NewName->Fold(&CurRec, CurMultiClass), 2062234353Sdim Type); 2063234353Sdim } 2064234353Sdim 2065234353Sdim return NewName->Fold(&CurRec, CurMultiClass); 2066234353Sdim} 2067234353Sdim 2068234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 2069234353Sdim/// to CurRec's name. 2070234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, 2071234353Sdim const std::string &Name, 2072234353Sdim const std::string &Scoper) { 2073234353Sdim return QualifyName(CurRec, CurMultiClass, StringInit::get(Name), Scoper); 2074234353Sdim} 2075