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 89226584Sdimvoid RecTy::dump() const { print(errs()); } 90226584Sdim 91226584SdimListRecTy *RecTy::getListTy() { 92226584Sdim if (!ListTy) 93288943Sdim ListTy.reset(new ListRecTy(this)); 94288943Sdim return ListTy.get(); 95226584Sdim} 96226584Sdim 97288943Sdimbool RecTy::typeIsConvertibleTo(const RecTy *RHS) const { 98288943Sdim assert(RHS && "NULL pointer"); 99249423Sdim return Kind == RHS->getRecTyKind(); 100249423Sdim} 101249423Sdim 102288943Sdimbool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{ 103288943Sdim if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind) 104249423Sdim return true; 105288943Sdim if (const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS)) 106249423Sdim return BitsTy->getNumBits() == 1; 107249423Sdim return false; 108249423Sdim} 109249423Sdim 110226584SdimBitsRecTy *BitsRecTy::get(unsigned Sz) { 111288943Sdim static std::vector<std::unique_ptr<BitsRecTy>> Shared; 112226584Sdim if (Sz >= Shared.size()) 113226584Sdim Shared.resize(Sz + 1); 114288943Sdim std::unique_ptr<BitsRecTy> &Ty = Shared[Sz]; 115226584Sdim if (!Ty) 116288943Sdim Ty.reset(new BitsRecTy(Sz)); 117288943Sdim return Ty.get(); 118226584Sdim} 119226584Sdim 120226584Sdimstd::string BitsRecTy::getAsString() const { 121226584Sdim return "bits<" + utostr(Size) + ">"; 122226584Sdim} 123226584Sdim 124288943Sdimbool BitsRecTy::typeIsConvertibleTo(const RecTy *RHS) const { 125288943Sdim if (RecTy::typeIsConvertibleTo(RHS)) //argument and the sender are same type 126249423Sdim return cast<BitsRecTy>(RHS)->Size == Size; 127249423Sdim RecTyKind kind = RHS->getRecTyKind(); 128249423Sdim return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind); 129249423Sdim} 130249423Sdim 131288943Sdimbool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const { 132249423Sdim RecTyKind kind = RHS->getRecTyKind(); 133249423Sdim return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind; 134249423Sdim} 135249423Sdim 136288943Sdimstd::string StringRecTy::getAsString() const { 137288943Sdim return "string"; 138226584Sdim} 139226584Sdim 140226584Sdimstd::string ListRecTy::getAsString() const { 141226584Sdim return "list<" + Ty->getAsString() + ">"; 142226584Sdim} 143226584Sdim 144288943Sdimbool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const { 145288943Sdim if (const auto *ListTy = dyn_cast<ListRecTy>(RHS)) 146288943Sdim return Ty->typeIsConvertibleTo(ListTy->getElementType()); 147249423Sdim return false; 148249423Sdim} 149249423Sdim 150288943Sdimstd::string DagRecTy::getAsString() const { 151288943Sdim return "dag"; 152226584Sdim} 153226584Sdim 154226584SdimRecordRecTy *RecordRecTy::get(Record *R) { 155243830Sdim return dyn_cast<RecordRecTy>(R->getDefInit()->getType()); 156226584Sdim} 157226584Sdim 158226584Sdimstd::string RecordRecTy::getAsString() const { 159226584Sdim return Rec->getName(); 160226584Sdim} 161226584Sdim 162288943Sdimbool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const { 163249423Sdim const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS); 164249423Sdim if (!RTy) 165249423Sdim return false; 166249423Sdim 167288943Sdim if (RTy->getRecord() == Rec || Rec->isSubClassOf(RTy->getRecord())) 168226584Sdim return true; 169226584Sdim 170288943Sdim for (Record *SC : RTy->getRecord()->getSuperClasses()) 171288943Sdim if (Rec->isSubClassOf(SC)) 172226584Sdim return true; 173226584Sdim 174226584Sdim return false; 175226584Sdim} 176226584Sdim 177226584Sdim/// resolveTypes - Find a common type that T1 and T2 convert to. 178288943Sdim/// Return null if no such type exists. 179226584Sdim/// 180226584SdimRecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { 181243830Sdim if (T1->typeIsConvertibleTo(T2)) 182243830Sdim return T2; 183243830Sdim if (T2->typeIsConvertibleTo(T1)) 184243830Sdim return T1; 185243830Sdim 186243830Sdim // If one is a Record type, check superclasses 187243830Sdim if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) { 188243830Sdim // See if T2 inherits from a type T1 also inherits from 189288943Sdim for (Record *SuperRec1 : RecTy1->getRecord()->getSuperClasses()) { 190288943Sdim RecordRecTy *SuperRecTy1 = RecordRecTy::get(SuperRec1); 191243830Sdim RecTy *NewType1 = resolveTypes(SuperRecTy1, T2); 192288943Sdim if (NewType1) 193243830Sdim return NewType1; 194243830Sdim } 195243830Sdim } 196243830Sdim if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) { 197243830Sdim // See if T1 inherits from a type T2 also inherits from 198288943Sdim for (Record *SuperRec2 : RecTy2->getRecord()->getSuperClasses()) { 199288943Sdim RecordRecTy *SuperRecTy2 = RecordRecTy::get(SuperRec2); 200243830Sdim RecTy *NewType2 = resolveTypes(T1, SuperRecTy2); 201288943Sdim if (NewType2) 202243830Sdim return NewType2; 203226584Sdim } 204226584Sdim } 205276479Sdim return nullptr; 206226584Sdim} 207226584Sdim 208226584Sdim 209226584Sdim//===----------------------------------------------------------------------===// 210226584Sdim// Initializer implementations 211226584Sdim//===----------------------------------------------------------------------===// 212226584Sdim 213234353Sdimvoid Init::anchor() { } 214226584Sdimvoid Init::dump() const { return print(errs()); } 215226584Sdim 216226584SdimUnsetInit *UnsetInit::get() { 217226584Sdim static UnsetInit TheInit; 218226584Sdim return &TheInit; 219226584Sdim} 220226584Sdim 221288943SdimInit *UnsetInit::convertInitializerTo(RecTy *Ty) const { 222288943Sdim if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { 223288943Sdim SmallVector<Init *, 16> NewBits(BRT->getNumBits()); 224234353Sdim 225288943Sdim for (unsigned i = 0; i != BRT->getNumBits(); ++i) 226288943Sdim NewBits[i] = UnsetInit::get(); 227288943Sdim 228288943Sdim return BitsInit::get(NewBits); 229288943Sdim } 230288943Sdim 231288943Sdim // All other types can just be returned. 232288943Sdim return const_cast<UnsetInit *>(this); 233288943Sdim} 234288943Sdim 235226584SdimBitInit *BitInit::get(bool V) { 236226584Sdim static BitInit True(true); 237226584Sdim static BitInit False(false); 238226584Sdim 239226584Sdim return V ? &True : &False; 240226584Sdim} 241226584Sdim 242288943SdimInit *BitInit::convertInitializerTo(RecTy *Ty) const { 243288943Sdim if (isa<BitRecTy>(Ty)) 244288943Sdim return const_cast<BitInit *>(this); 245288943Sdim 246288943Sdim if (isa<IntRecTy>(Ty)) 247288943Sdim return IntInit::get(getValue()); 248288943Sdim 249288943Sdim if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { 250288943Sdim // Can only convert single bit. 251288943Sdim if (BRT->getNumBits() == 1) 252288943Sdim return BitsInit::get(const_cast<BitInit *>(this)); 253288943Sdim } 254288943Sdim 255288943Sdim return nullptr; 256288943Sdim} 257288943Sdim 258226584Sdimstatic void 259226584SdimProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) { 260226584Sdim ID.AddInteger(Range.size()); 261226584Sdim 262288943Sdim for (Init *I : Range) 263288943Sdim ID.AddPointer(I); 264226584Sdim} 265226584Sdim 266226584SdimBitsInit *BitsInit::get(ArrayRef<Init *> Range) { 267288943Sdim static FoldingSet<BitsInit> ThePool; 268288943Sdim static std::vector<std::unique_ptr<BitsInit>> TheActualPool; 269226584Sdim 270226584Sdim FoldingSetNodeID ID; 271226584Sdim ProfileBitsInit(ID, Range); 272226584Sdim 273276479Sdim void *IP = nullptr; 274226584Sdim if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 275226584Sdim return I; 276226584Sdim 277226584Sdim BitsInit *I = new BitsInit(Range); 278226584Sdim ThePool.InsertNode(I, IP); 279288943Sdim TheActualPool.push_back(std::unique_ptr<BitsInit>(I)); 280226584Sdim return I; 281226584Sdim} 282226584Sdim 283226584Sdimvoid BitsInit::Profile(FoldingSetNodeID &ID) const { 284226584Sdim ProfileBitsInit(ID, Bits); 285226584Sdim} 286226584Sdim 287288943SdimInit *BitsInit::convertInitializerTo(RecTy *Ty) const { 288288943Sdim if (isa<BitRecTy>(Ty)) { 289288943Sdim if (getNumBits() != 1) return nullptr; // Only accept if just one bit! 290288943Sdim return getBit(0); 291288943Sdim } 292288943Sdim 293288943Sdim if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { 294288943Sdim // If the number of bits is right, return it. Otherwise we need to expand 295288943Sdim // or truncate. 296288943Sdim if (getNumBits() != BRT->getNumBits()) return nullptr; 297288943Sdim return const_cast<BitsInit *>(this); 298288943Sdim } 299288943Sdim 300288943Sdim if (isa<IntRecTy>(Ty)) { 301288943Sdim int64_t Result = 0; 302288943Sdim for (unsigned i = 0, e = getNumBits(); i != e; ++i) 303288943Sdim if (auto *Bit = dyn_cast<BitInit>(getBit(i))) 304288943Sdim Result |= static_cast<int64_t>(Bit->getValue()) << i; 305288943Sdim else 306288943Sdim return nullptr; 307288943Sdim return IntInit::get(Result); 308288943Sdim } 309288943Sdim 310288943Sdim return nullptr; 311288943Sdim} 312288943Sdim 313226584SdimInit * 314226584SdimBitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 315226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 316226584Sdim 317226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 318226584Sdim if (Bits[i] >= getNumBits()) 319276479Sdim return nullptr; 320226584Sdim NewBits[i] = getBit(Bits[i]); 321226584Sdim } 322226584Sdim return BitsInit::get(NewBits); 323226584Sdim} 324226584Sdim 325226584Sdimstd::string BitsInit::getAsString() const { 326226584Sdim std::string Result = "{ "; 327226584Sdim for (unsigned i = 0, e = getNumBits(); i != e; ++i) { 328226584Sdim if (i) Result += ", "; 329226584Sdim if (Init *Bit = getBit(e-i-1)) 330226584Sdim Result += Bit->getAsString(); 331226584Sdim else 332226584Sdim Result += "*"; 333226584Sdim } 334226584Sdim return Result + " }"; 335226584Sdim} 336226584Sdim 337243830Sdim// Fix bit initializer to preserve the behavior that bit reference from a unset 338243830Sdim// bits initializer will resolve into VarBitInit to keep the field name and bit 339243830Sdim// number used in targets with fixed insn length. 340243830Sdimstatic Init *fixBitInit(const RecordVal *RV, Init *Before, Init *After) { 341288943Sdim if (RV || !isa<UnsetInit>(After)) 342243830Sdim return After; 343243830Sdim return Before; 344243830Sdim} 345243830Sdim 346226584Sdim// resolveReferences - If there are any field references that refer to fields 347226584Sdim// that have been filled in, we can propagate the values now. 348226584Sdim// 349226584SdimInit *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const { 350226584Sdim bool Changed = false; 351226584Sdim SmallVector<Init *, 16> NewBits(getNumBits()); 352226584Sdim 353276479Sdim Init *CachedInit = nullptr; 354276479Sdim Init *CachedBitVar = nullptr; 355243830Sdim bool CachedBitVarChanged = false; 356243830Sdim 357243830Sdim for (unsigned i = 0, e = getNumBits(); i != e; ++i) { 358243830Sdim Init *CurBit = Bits[i]; 359243830Sdim Init *CurBitVar = CurBit->getBitVar(); 360243830Sdim 361243830Sdim NewBits[i] = CurBit; 362243830Sdim 363243830Sdim if (CurBitVar == CachedBitVar) { 364243830Sdim if (CachedBitVarChanged) { 365243830Sdim Init *Bit = CachedInit->getBit(CurBit->getBitNum()); 366243830Sdim NewBits[i] = fixBitInit(RV, CurBit, Bit); 367243830Sdim } 368243830Sdim continue; 369243830Sdim } 370243830Sdim CachedBitVar = CurBitVar; 371243830Sdim CachedBitVarChanged = false; 372243830Sdim 373226584Sdim Init *B; 374243830Sdim do { 375243830Sdim B = CurBitVar; 376243830Sdim CurBitVar = CurBitVar->resolveReferences(R, RV); 377243830Sdim CachedBitVarChanged |= B != CurBitVar; 378243830Sdim Changed |= B != CurBitVar; 379243830Sdim } while (B != CurBitVar); 380243830Sdim CachedInit = CurBitVar; 381226584Sdim 382243830Sdim if (CachedBitVarChanged) { 383243830Sdim Init *Bit = CurBitVar->getBit(CurBit->getBitNum()); 384243830Sdim NewBits[i] = fixBitInit(RV, CurBit, Bit); 385243830Sdim } 386226584Sdim } 387226584Sdim 388226584Sdim if (Changed) 389226584Sdim return BitsInit::get(NewBits); 390226584Sdim 391226584Sdim return const_cast<BitsInit *>(this); 392226584Sdim} 393226584Sdim 394226584SdimIntInit *IntInit::get(int64_t V) { 395288943Sdim static DenseMap<int64_t, std::unique_ptr<IntInit>> ThePool; 396226584Sdim 397288943Sdim std::unique_ptr<IntInit> &I = ThePool[V]; 398288943Sdim if (!I) I.reset(new IntInit(V)); 399288943Sdim return I.get(); 400226584Sdim} 401226584Sdim 402226584Sdimstd::string IntInit::getAsString() const { 403226584Sdim return itostr(Value); 404226584Sdim} 405226584Sdim 406288943Sdim/// canFitInBitfield - Return true if the number of bits is large enough to hold 407288943Sdim/// the integer value. 408288943Sdimstatic bool canFitInBitfield(int64_t Value, unsigned NumBits) { 409288943Sdim // For example, with NumBits == 4, we permit Values from [-7 .. 15]. 410288943Sdim return (NumBits >= sizeof(Value) * 8) || 411288943Sdim (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1); 412288943Sdim} 413288943Sdim 414288943SdimInit *IntInit::convertInitializerTo(RecTy *Ty) const { 415288943Sdim if (isa<IntRecTy>(Ty)) 416288943Sdim return const_cast<IntInit *>(this); 417288943Sdim 418288943Sdim if (isa<BitRecTy>(Ty)) { 419288943Sdim int64_t Val = getValue(); 420288943Sdim if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! 421288943Sdim return BitInit::get(Val != 0); 422288943Sdim } 423288943Sdim 424288943Sdim if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { 425288943Sdim int64_t Value = getValue(); 426288943Sdim // Make sure this bitfield is large enough to hold the integer value. 427288943Sdim if (!canFitInBitfield(Value, BRT->getNumBits())) 428288943Sdim return nullptr; 429288943Sdim 430288943Sdim SmallVector<Init *, 16> NewBits(BRT->getNumBits()); 431288943Sdim for (unsigned i = 0; i != BRT->getNumBits(); ++i) 432288943Sdim NewBits[i] = BitInit::get(Value & (1LL << i)); 433288943Sdim 434288943Sdim return BitsInit::get(NewBits); 435288943Sdim } 436288943Sdim 437288943Sdim return nullptr; 438288943Sdim} 439288943Sdim 440226584SdimInit * 441226584SdimIntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 442226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 443226584Sdim 444226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 445226584Sdim if (Bits[i] >= 64) 446276479Sdim return nullptr; 447226584Sdim 448226584Sdim NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i])); 449226584Sdim } 450226584Sdim return BitsInit::get(NewBits); 451226584Sdim} 452226584Sdim 453234353SdimStringInit *StringInit::get(StringRef V) { 454288943Sdim static StringMap<std::unique_ptr<StringInit>> ThePool; 455226584Sdim 456288943Sdim std::unique_ptr<StringInit> &I = ThePool[V]; 457288943Sdim if (!I) I.reset(new StringInit(V)); 458288943Sdim return I.get(); 459226584Sdim} 460226584Sdim 461288943SdimInit *StringInit::convertInitializerTo(RecTy *Ty) const { 462288943Sdim if (isa<StringRecTy>(Ty)) 463288943Sdim return const_cast<StringInit *>(this); 464288943Sdim 465288943Sdim return nullptr; 466288943Sdim} 467288943Sdim 468226584Sdimstatic void ProfileListInit(FoldingSetNodeID &ID, 469226584Sdim ArrayRef<Init *> Range, 470226584Sdim RecTy *EltTy) { 471226584Sdim ID.AddInteger(Range.size()); 472226584Sdim ID.AddPointer(EltTy); 473226584Sdim 474288943Sdim for (Init *I : Range) 475288943Sdim ID.AddPointer(I); 476226584Sdim} 477226584Sdim 478226584SdimListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { 479288943Sdim static FoldingSet<ListInit> ThePool; 480276479Sdim static std::vector<std::unique_ptr<ListInit>> TheActualPool; 481226584Sdim 482226584Sdim FoldingSetNodeID ID; 483226584Sdim ProfileListInit(ID, Range, EltTy); 484226584Sdim 485276479Sdim void *IP = nullptr; 486226584Sdim if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 487226584Sdim return I; 488226584Sdim 489226584Sdim ListInit *I = new ListInit(Range, EltTy); 490226584Sdim ThePool.InsertNode(I, IP); 491276479Sdim TheActualPool.push_back(std::unique_ptr<ListInit>(I)); 492226584Sdim return I; 493226584Sdim} 494226584Sdim 495226584Sdimvoid ListInit::Profile(FoldingSetNodeID &ID) const { 496288943Sdim RecTy *EltTy = cast<ListRecTy>(getType())->getElementType(); 497226584Sdim 498226584Sdim ProfileListInit(ID, Values, EltTy); 499226584Sdim} 500226584Sdim 501288943SdimInit *ListInit::convertInitializerTo(RecTy *Ty) const { 502288943Sdim if (auto *LRT = dyn_cast<ListRecTy>(Ty)) { 503288943Sdim std::vector<Init*> Elements; 504288943Sdim 505288943Sdim // Verify that all of the elements of the list are subclasses of the 506288943Sdim // appropriate class! 507288943Sdim for (Init *I : getValues()) 508288943Sdim if (Init *CI = I->convertInitializerTo(LRT->getElementType())) 509288943Sdim Elements.push_back(CI); 510288943Sdim else 511288943Sdim return nullptr; 512288943Sdim 513288943Sdim if (isa<ListRecTy>(getType())) 514288943Sdim return ListInit::get(Elements, Ty); 515288943Sdim } 516288943Sdim 517288943Sdim return nullptr; 518288943Sdim} 519288943Sdim 520226584SdimInit * 521226584SdimListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { 522226584Sdim std::vector<Init*> Vals; 523226584Sdim for (unsigned i = 0, e = Elements.size(); i != e; ++i) { 524288943Sdim if (Elements[i] >= size()) 525276479Sdim return nullptr; 526226584Sdim Vals.push_back(getElement(Elements[i])); 527226584Sdim } 528226584Sdim return ListInit::get(Vals, getType()); 529226584Sdim} 530226584Sdim 531226584SdimRecord *ListInit::getElementAsRecord(unsigned i) const { 532226584Sdim assert(i < Values.size() && "List element index out of range!"); 533243830Sdim DefInit *DI = dyn_cast<DefInit>(Values[i]); 534276479Sdim if (!DI) 535243830Sdim PrintFatalError("Expected record in list!"); 536226584Sdim return DI->getDef(); 537226584Sdim} 538226584Sdim 539226584SdimInit *ListInit::resolveReferences(Record &R, const RecordVal *RV) const { 540226584Sdim std::vector<Init*> Resolved; 541288943Sdim Resolved.reserve(size()); 542226584Sdim bool Changed = false; 543226584Sdim 544288943Sdim for (Init *CurElt : getValues()) { 545226584Sdim Init *E; 546226584Sdim 547226584Sdim do { 548226584Sdim E = CurElt; 549226584Sdim CurElt = CurElt->resolveReferences(R, RV); 550226584Sdim Changed |= E != CurElt; 551226584Sdim } while (E != CurElt); 552226584Sdim Resolved.push_back(E); 553226584Sdim } 554226584Sdim 555226584Sdim if (Changed) 556226584Sdim return ListInit::get(Resolved, getType()); 557226584Sdim return const_cast<ListInit *>(this); 558226584Sdim} 559226584Sdim 560226584SdimInit *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV, 561226584Sdim unsigned Elt) const { 562288943Sdim if (Elt >= size()) 563276479Sdim return nullptr; // Out of range reference. 564226584Sdim Init *E = getElement(Elt); 565226584Sdim // If the element is set to some value, or if we are resolving a reference 566226584Sdim // to a specific variable and that variable is explicitly unset, then 567226584Sdim // replace the VarListElementInit with it. 568243830Sdim if (IRV || !isa<UnsetInit>(E)) 569226584Sdim return E; 570276479Sdim return nullptr; 571226584Sdim} 572226584Sdim 573226584Sdimstd::string ListInit::getAsString() const { 574226584Sdim std::string Result = "["; 575226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) { 576226584Sdim if (i) Result += ", "; 577226584Sdim Result += Values[i]->getAsString(); 578226584Sdim } 579226584Sdim return Result + "]"; 580226584Sdim} 581226584Sdim 582226584SdimInit *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV, 583226584Sdim unsigned Elt) const { 584226584Sdim Init *Resolved = resolveReferences(R, IRV); 585243830Sdim OpInit *OResolved = dyn_cast<OpInit>(Resolved); 586226584Sdim if (OResolved) { 587276479Sdim Resolved = OResolved->Fold(&R, nullptr); 588226584Sdim } 589226584Sdim 590226584Sdim if (Resolved != this) { 591288943Sdim TypedInit *Typed = cast<TypedInit>(Resolved); 592288943Sdim if (Init *New = Typed->resolveListElementReference(R, IRV, Elt)) 593288943Sdim return New; 594288943Sdim return VarListElementInit::get(Typed, Elt); 595226584Sdim } 596226584Sdim 597276479Sdim return nullptr; 598226584Sdim} 599226584Sdim 600243830SdimInit *OpInit::getBit(unsigned Bit) const { 601243830Sdim if (getType() == BitRecTy::get()) 602243830Sdim return const_cast<OpInit*>(this); 603243830Sdim return VarBitInit::get(const_cast<OpInit*>(this), Bit); 604243830Sdim} 605243830Sdim 606226584SdimUnOpInit *UnOpInit::get(UnaryOp opc, Init *lhs, RecTy *Type) { 607226584Sdim typedef std::pair<std::pair<unsigned, Init *>, RecTy *> Key; 608288943Sdim static DenseMap<Key, std::unique_ptr<UnOpInit>> ThePool; 609226584Sdim 610226584Sdim Key TheKey(std::make_pair(std::make_pair(opc, lhs), Type)); 611226584Sdim 612288943Sdim std::unique_ptr<UnOpInit> &I = ThePool[TheKey]; 613288943Sdim if (!I) I.reset(new UnOpInit(opc, lhs, Type)); 614288943Sdim return I.get(); 615226584Sdim} 616226584Sdim 617226584SdimInit *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 618226584Sdim switch (getOpcode()) { 619226584Sdim case CAST: { 620288943Sdim if (isa<StringRecTy>(getType())) { 621243830Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) 622226584Sdim return LHSs; 623226584Sdim 624243830Sdim if (DefInit *LHSd = dyn_cast<DefInit>(LHS)) 625288943Sdim return StringInit::get(LHSd->getAsString()); 626234353Sdim 627243830Sdim if (IntInit *LHSi = dyn_cast<IntInit>(LHS)) 628234353Sdim return StringInit::get(LHSi->getAsString()); 629226584Sdim } else { 630243830Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) { 631226584Sdim std::string Name = LHSs->getValue(); 632226584Sdim 633226584Sdim // From TGParser::ParseIDValue 634226584Sdim if (CurRec) { 635226584Sdim if (const RecordVal *RV = CurRec->getValue(Name)) { 636226584Sdim if (RV->getType() != getType()) 637243830Sdim PrintFatalError("type mismatch in cast"); 638226584Sdim return VarInit::get(Name, RV->getType()); 639226584Sdim } 640226584Sdim 641234353Sdim Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, 642234353Sdim ":"); 643288943Sdim 644226584Sdim if (CurRec->isTemplateArg(TemplateArgName)) { 645226584Sdim const RecordVal *RV = CurRec->getValue(TemplateArgName); 646226584Sdim assert(RV && "Template arg doesn't exist??"); 647226584Sdim 648226584Sdim if (RV->getType() != getType()) 649243830Sdim PrintFatalError("type mismatch in cast"); 650226584Sdim 651226584Sdim return VarInit::get(TemplateArgName, RV->getType()); 652226584Sdim } 653226584Sdim } 654226584Sdim 655226584Sdim if (CurMultiClass) { 656288943Sdim Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, 657288943Sdim "::"); 658234353Sdim 659226584Sdim if (CurMultiClass->Rec.isTemplateArg(MCName)) { 660226584Sdim const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); 661226584Sdim assert(RV && "Template arg doesn't exist??"); 662226584Sdim 663226584Sdim if (RV->getType() != getType()) 664243830Sdim PrintFatalError("type mismatch in cast"); 665226584Sdim 666226584Sdim return VarInit::get(MCName, RV->getType()); 667226584Sdim } 668226584Sdim } 669280031Sdim assert(CurRec && "NULL pointer"); 670226584Sdim if (Record *D = (CurRec->getRecords()).getDef(Name)) 671226584Sdim return DefInit::get(D); 672226584Sdim 673243830Sdim PrintFatalError(CurRec->getLoc(), 674243830Sdim "Undefined reference:'" + Name + "'\n"); 675226584Sdim } 676296417Sdim 677296417Sdim if (isa<IntRecTy>(getType())) { 678296417Sdim if (BitsInit *BI = dyn_cast<BitsInit>(LHS)) { 679296417Sdim if (Init *NewInit = BI->convertInitializerTo(IntRecTy::get())) 680296417Sdim return NewInit; 681296417Sdim break; 682296417Sdim } 683296417Sdim } 684226584Sdim } 685226584Sdim break; 686226584Sdim } 687226584Sdim case HEAD: { 688243830Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { 689288943Sdim assert(!LHSl->empty() && "Empty list in head"); 690226584Sdim return LHSl->getElement(0); 691226584Sdim } 692226584Sdim break; 693226584Sdim } 694226584Sdim case TAIL: { 695243830Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { 696288943Sdim assert(!LHSl->empty() && "Empty list in tail"); 697226584Sdim // Note the +1. We can't just pass the result of getValues() 698226584Sdim // directly. 699288943Sdim return ListInit::get(LHSl->getValues().slice(1), LHSl->getType()); 700226584Sdim } 701226584Sdim break; 702226584Sdim } 703226584Sdim case EMPTY: { 704288943Sdim if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) 705288943Sdim return IntInit::get(LHSl->empty()); 706288943Sdim if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) 707288943Sdim return IntInit::get(LHSs->getValue().empty()); 708226584Sdim 709226584Sdim break; 710226584Sdim } 711226584Sdim } 712226584Sdim return const_cast<UnOpInit *>(this); 713226584Sdim} 714226584Sdim 715226584SdimInit *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const { 716226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 717226584Sdim 718226584Sdim if (LHS != lhs) 719276479Sdim return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, nullptr); 720276479Sdim return Fold(&R, nullptr); 721226584Sdim} 722226584Sdim 723226584Sdimstd::string UnOpInit::getAsString() const { 724226584Sdim std::string Result; 725296417Sdim switch (getOpcode()) { 726226584Sdim case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break; 727226584Sdim case HEAD: Result = "!head"; break; 728226584Sdim case TAIL: Result = "!tail"; break; 729226584Sdim case EMPTY: Result = "!empty"; break; 730226584Sdim } 731226584Sdim return Result + "(" + LHS->getAsString() + ")"; 732226584Sdim} 733226584Sdim 734226584SdimBinOpInit *BinOpInit::get(BinaryOp opc, Init *lhs, 735226584Sdim Init *rhs, RecTy *Type) { 736226584Sdim typedef std::pair< 737226584Sdim std::pair<std::pair<unsigned, Init *>, Init *>, 738226584Sdim RecTy * 739226584Sdim > Key; 740226584Sdim 741288943Sdim static DenseMap<Key, std::unique_ptr<BinOpInit>> ThePool; 742226584Sdim 743226584Sdim Key TheKey(std::make_pair(std::make_pair(std::make_pair(opc, lhs), rhs), 744226584Sdim Type)); 745226584Sdim 746288943Sdim std::unique_ptr<BinOpInit> &I = ThePool[TheKey]; 747288943Sdim if (!I) I.reset(new BinOpInit(opc, lhs, rhs, Type)); 748288943Sdim return I.get(); 749226584Sdim} 750226584Sdim 751226584SdimInit *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 752226584Sdim switch (getOpcode()) { 753226584Sdim case CONCAT: { 754243830Sdim DagInit *LHSs = dyn_cast<DagInit>(LHS); 755243830Sdim DagInit *RHSs = dyn_cast<DagInit>(RHS); 756226584Sdim if (LHSs && RHSs) { 757243830Sdim DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator()); 758243830Sdim DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator()); 759276479Sdim if (!LOp || !ROp || LOp->getDef() != ROp->getDef()) 760243830Sdim PrintFatalError("Concated Dag operators do not match!"); 761226584Sdim std::vector<Init*> Args; 762226584Sdim std::vector<std::string> ArgNames; 763226584Sdim for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) { 764226584Sdim Args.push_back(LHSs->getArg(i)); 765226584Sdim ArgNames.push_back(LHSs->getArgName(i)); 766226584Sdim } 767226584Sdim for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) { 768226584Sdim Args.push_back(RHSs->getArg(i)); 769226584Sdim ArgNames.push_back(RHSs->getArgName(i)); 770226584Sdim } 771226584Sdim return DagInit::get(LHSs->getOperator(), "", Args, ArgNames); 772226584Sdim } 773226584Sdim break; 774226584Sdim } 775276479Sdim case LISTCONCAT: { 776276479Sdim ListInit *LHSs = dyn_cast<ListInit>(LHS); 777276479Sdim ListInit *RHSs = dyn_cast<ListInit>(RHS); 778276479Sdim if (LHSs && RHSs) { 779276479Sdim std::vector<Init *> Args; 780276479Sdim Args.insert(Args.end(), LHSs->begin(), LHSs->end()); 781276479Sdim Args.insert(Args.end(), RHSs->begin(), RHSs->end()); 782276479Sdim return ListInit::get( 783288943Sdim Args, cast<ListRecTy>(LHSs->getType())->getElementType()); 784276479Sdim } 785276479Sdim break; 786276479Sdim } 787226584Sdim case STRCONCAT: { 788243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 789243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 790226584Sdim if (LHSs && RHSs) 791226584Sdim return StringInit::get(LHSs->getValue() + RHSs->getValue()); 792226584Sdim break; 793226584Sdim } 794226584Sdim case EQ: { 795226584Sdim // try to fold eq comparison for 'bit' and 'int', otherwise fallback 796226584Sdim // to string objects. 797243830Sdim IntInit *L = 798243830Sdim dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); 799243830Sdim IntInit *R = 800243830Sdim dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); 801226584Sdim 802226584Sdim if (L && R) 803226584Sdim return IntInit::get(L->getValue() == R->getValue()); 804226584Sdim 805243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 806243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 807226584Sdim 808226584Sdim // Make sure we've resolved 809226584Sdim if (LHSs && RHSs) 810226584Sdim return IntInit::get(LHSs->getValue() == RHSs->getValue()); 811226584Sdim 812226584Sdim break; 813226584Sdim } 814249423Sdim case ADD: 815280031Sdim case AND: 816226584Sdim case SHL: 817226584Sdim case SRA: 818226584Sdim case SRL: { 819276479Sdim IntInit *LHSi = 820276479Sdim dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); 821276479Sdim IntInit *RHSi = 822276479Sdim dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); 823226584Sdim if (LHSi && RHSi) { 824226584Sdim int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); 825226584Sdim int64_t Result; 826226584Sdim switch (getOpcode()) { 827234353Sdim default: llvm_unreachable("Bad opcode!"); 828249423Sdim case ADD: Result = LHSv + RHSv; break; 829280031Sdim case AND: Result = LHSv & RHSv; break; 830226584Sdim case SHL: Result = LHSv << RHSv; break; 831226584Sdim case SRA: Result = LHSv >> RHSv; break; 832226584Sdim case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; 833226584Sdim } 834226584Sdim return IntInit::get(Result); 835226584Sdim } 836226584Sdim break; 837226584Sdim } 838226584Sdim } 839226584Sdim return const_cast<BinOpInit *>(this); 840226584Sdim} 841226584Sdim 842226584SdimInit *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const { 843226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 844226584Sdim Init *rhs = RHS->resolveReferences(R, RV); 845226584Sdim 846226584Sdim if (LHS != lhs || RHS != rhs) 847276479Sdim return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R,nullptr); 848276479Sdim return Fold(&R, nullptr); 849226584Sdim} 850226584Sdim 851226584Sdimstd::string BinOpInit::getAsString() const { 852226584Sdim std::string Result; 853296417Sdim switch (getOpcode()) { 854226584Sdim case CONCAT: Result = "!con"; break; 855249423Sdim case ADD: Result = "!add"; break; 856280031Sdim case AND: Result = "!and"; break; 857226584Sdim case SHL: Result = "!shl"; break; 858226584Sdim case SRA: Result = "!sra"; break; 859226584Sdim case SRL: Result = "!srl"; break; 860226584Sdim case EQ: Result = "!eq"; break; 861276479Sdim case LISTCONCAT: Result = "!listconcat"; break; 862226584Sdim case STRCONCAT: Result = "!strconcat"; break; 863226584Sdim } 864226584Sdim return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; 865226584Sdim} 866226584Sdim 867288943SdimTernOpInit *TernOpInit::get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, 868288943Sdim RecTy *Type) { 869226584Sdim typedef std::pair< 870226584Sdim std::pair< 871226584Sdim std::pair<std::pair<unsigned, RecTy *>, Init *>, 872226584Sdim Init * 873226584Sdim >, 874226584Sdim Init * 875226584Sdim > Key; 876226584Sdim 877288943Sdim static DenseMap<Key, std::unique_ptr<TernOpInit>> ThePool; 878226584Sdim 879226584Sdim Key TheKey(std::make_pair(std::make_pair(std::make_pair(std::make_pair(opc, 880226584Sdim Type), 881226584Sdim lhs), 882226584Sdim mhs), 883226584Sdim rhs)); 884226584Sdim 885288943Sdim std::unique_ptr<TernOpInit> &I = ThePool[TheKey]; 886288943Sdim if (!I) I.reset(new TernOpInit(opc, lhs, mhs, rhs, Type)); 887288943Sdim return I.get(); 888226584Sdim} 889226584Sdim 890226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, 891226584Sdim Record *CurRec, MultiClass *CurMultiClass); 892226584Sdim 893226584Sdimstatic Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg, 894226584Sdim RecTy *Type, Record *CurRec, 895226584Sdim MultiClass *CurMultiClass) { 896226584Sdim // If this is a dag, recurse 897288943Sdim if (auto *TArg = dyn_cast<TypedInit>(Arg)) 898288943Sdim if (isa<DagRecTy>(TArg->getType())) 899288943Sdim return ForeachHelper(LHS, Arg, RHSo, Type, CurRec, CurMultiClass); 900226584Sdim 901288943Sdim std::vector<Init *> NewOperands; 902288943Sdim for (unsigned i = 0; i < RHSo->getNumOperands(); ++i) { 903288943Sdim if (auto *RHSoo = dyn_cast<OpInit>(RHSo->getOperand(i))) { 904288943Sdim if (Init *Result = EvaluateOperation(RHSoo, LHS, Arg, 905288943Sdim Type, CurRec, CurMultiClass)) 906226584Sdim NewOperands.push_back(Result); 907288943Sdim else 908226584Sdim NewOperands.push_back(Arg); 909226584Sdim } else if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) { 910226584Sdim NewOperands.push_back(Arg); 911226584Sdim } else { 912226584Sdim NewOperands.push_back(RHSo->getOperand(i)); 913226584Sdim } 914226584Sdim } 915226584Sdim 916226584Sdim // Now run the operator and use its result as the new leaf 917226584Sdim const OpInit *NewOp = RHSo->clone(NewOperands); 918226584Sdim Init *NewVal = NewOp->Fold(CurRec, CurMultiClass); 919276479Sdim return (NewVal != NewOp) ? NewVal : nullptr; 920226584Sdim} 921226584Sdim 922226584Sdimstatic Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, 923226584Sdim Record *CurRec, MultiClass *CurMultiClass) { 924226584Sdim 925243830Sdim OpInit *RHSo = dyn_cast<OpInit>(RHS); 926226584Sdim 927288943Sdim if (!RHSo) 928243830Sdim PrintFatalError(CurRec->getLoc(), "!foreach requires an operator\n"); 929226584Sdim 930243830Sdim TypedInit *LHSt = dyn_cast<TypedInit>(LHS); 931226584Sdim 932243830Sdim if (!LHSt) 933243830Sdim PrintFatalError(CurRec->getLoc(), "!foreach requires typed variable\n"); 934226584Sdim 935288943Sdim DagInit *MHSd = dyn_cast<DagInit>(MHS); 936288943Sdim if (MHSd && isa<DagRecTy>(Type)) { 937288943Sdim Init *Val = MHSd->getOperator(); 938288943Sdim if (Init *Result = EvaluateOperation(RHSo, LHS, Val, 939288943Sdim Type, CurRec, CurMultiClass)) 940288943Sdim Val = Result; 941226584Sdim 942288943Sdim std::vector<std::pair<Init *, std::string> > args; 943288943Sdim for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) { 944288943Sdim Init *Arg = MHSd->getArg(i); 945288943Sdim std::string ArgName = MHSd->getArgName(i); 946226584Sdim 947288943Sdim // Process args 948288943Sdim if (Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type, 949288943Sdim CurRec, CurMultiClass)) 950288943Sdim Arg = Result; 951226584Sdim 952288943Sdim // TODO: Process arg names 953288943Sdim args.push_back(std::make_pair(Arg, ArgName)); 954226584Sdim } 955226584Sdim 956288943Sdim return DagInit::get(Val, "", args); 957288943Sdim } 958226584Sdim 959288943Sdim ListInit *MHSl = dyn_cast<ListInit>(MHS); 960288943Sdim if (MHSl && isa<ListRecTy>(Type)) { 961288943Sdim std::vector<Init *> NewOperands; 962288943Sdim std::vector<Init *> NewList(MHSl->begin(), MHSl->end()); 963288943Sdim 964288943Sdim for (Init *&Item : NewList) { 965288943Sdim NewOperands.clear(); 966288943Sdim for(unsigned i = 0; i < RHSo->getNumOperands(); ++i) { 967288943Sdim // First, replace the foreach variable with the list item 968288943Sdim if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) 969288943Sdim NewOperands.push_back(Item); 970288943Sdim else 971288943Sdim NewOperands.push_back(RHSo->getOperand(i)); 972226584Sdim } 973288943Sdim 974288943Sdim // Now run the operator and use its result as the new list item 975288943Sdim const OpInit *NewOp = RHSo->clone(NewOperands); 976288943Sdim Init *NewItem = NewOp->Fold(CurRec, CurMultiClass); 977288943Sdim if (NewItem != NewOp) 978288943Sdim Item = NewItem; 979226584Sdim } 980288943Sdim return ListInit::get(NewList, MHSl->getType()); 981226584Sdim } 982276479Sdim return nullptr; 983226584Sdim} 984226584Sdim 985226584SdimInit *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { 986226584Sdim switch (getOpcode()) { 987226584Sdim case SUBST: { 988243830Sdim DefInit *LHSd = dyn_cast<DefInit>(LHS); 989243830Sdim VarInit *LHSv = dyn_cast<VarInit>(LHS); 990243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 991226584Sdim 992243830Sdim DefInit *MHSd = dyn_cast<DefInit>(MHS); 993243830Sdim VarInit *MHSv = dyn_cast<VarInit>(MHS); 994243830Sdim StringInit *MHSs = dyn_cast<StringInit>(MHS); 995226584Sdim 996243830Sdim DefInit *RHSd = dyn_cast<DefInit>(RHS); 997243830Sdim VarInit *RHSv = dyn_cast<VarInit>(RHS); 998243830Sdim StringInit *RHSs = dyn_cast<StringInit>(RHS); 999226584Sdim 1000288943Sdim if (LHSd && MHSd && RHSd) { 1001288943Sdim Record *Val = RHSd->getDef(); 1002288943Sdim if (LHSd->getAsString() == RHSd->getAsString()) 1003288943Sdim Val = MHSd->getDef(); 1004288943Sdim return DefInit::get(Val); 1005288943Sdim } 1006288943Sdim if (LHSv && MHSv && RHSv) { 1007288943Sdim std::string Val = RHSv->getName(); 1008288943Sdim if (LHSv->getAsString() == RHSv->getAsString()) 1009288943Sdim Val = MHSv->getName(); 1010288943Sdim return VarInit::get(Val, getType()); 1011288943Sdim } 1012288943Sdim if (LHSs && MHSs && RHSs) { 1013288943Sdim std::string Val = RHSs->getValue(); 1014288943Sdim 1015288943Sdim std::string::size_type found; 1016288943Sdim std::string::size_type idx = 0; 1017288943Sdim while (true) { 1018288943Sdim found = Val.find(LHSs->getValue(), idx); 1019288943Sdim if (found == std::string::npos) 1020288943Sdim break; 1021288943Sdim Val.replace(found, LHSs->getValue().size(), MHSs->getValue()); 1022288943Sdim idx = found + MHSs->getValue().size(); 1023226584Sdim } 1024226584Sdim 1025288943Sdim return StringInit::get(Val); 1026226584Sdim } 1027226584Sdim break; 1028226584Sdim } 1029226584Sdim 1030226584Sdim case FOREACH: { 1031288943Sdim if (Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), 1032288943Sdim CurRec, CurMultiClass)) 1033226584Sdim return Result; 1034226584Sdim break; 1035226584Sdim } 1036226584Sdim 1037226584Sdim case IF: { 1038243830Sdim IntInit *LHSi = dyn_cast<IntInit>(LHS); 1039226584Sdim if (Init *I = LHS->convertInitializerTo(IntRecTy::get())) 1040243830Sdim LHSi = dyn_cast<IntInit>(I); 1041226584Sdim if (LHSi) { 1042288943Sdim if (LHSi->getValue()) 1043226584Sdim return MHS; 1044288943Sdim return RHS; 1045226584Sdim } 1046226584Sdim break; 1047226584Sdim } 1048226584Sdim } 1049226584Sdim 1050226584Sdim return const_cast<TernOpInit *>(this); 1051226584Sdim} 1052226584Sdim 1053226584SdimInit *TernOpInit::resolveReferences(Record &R, 1054226584Sdim const RecordVal *RV) const { 1055226584Sdim Init *lhs = LHS->resolveReferences(R, RV); 1056226584Sdim 1057296417Sdim if (getOpcode() == IF && lhs != LHS) { 1058243830Sdim IntInit *Value = dyn_cast<IntInit>(lhs); 1059226584Sdim if (Init *I = lhs->convertInitializerTo(IntRecTy::get())) 1060243830Sdim Value = dyn_cast<IntInit>(I); 1061276479Sdim if (Value) { 1062226584Sdim // Short-circuit 1063226584Sdim if (Value->getValue()) { 1064226584Sdim Init *mhs = MHS->resolveReferences(R, RV); 1065226584Sdim return (TernOpInit::get(getOpcode(), lhs, mhs, 1066276479Sdim RHS, getType()))->Fold(&R, nullptr); 1067226584Sdim } 1068288943Sdim Init *rhs = RHS->resolveReferences(R, RV); 1069288943Sdim return (TernOpInit::get(getOpcode(), lhs, MHS, 1070288943Sdim rhs, getType()))->Fold(&R, nullptr); 1071226584Sdim } 1072226584Sdim } 1073226584Sdim 1074226584Sdim Init *mhs = MHS->resolveReferences(R, RV); 1075226584Sdim Init *rhs = RHS->resolveReferences(R, RV); 1076226584Sdim 1077226584Sdim if (LHS != lhs || MHS != mhs || RHS != rhs) 1078226584Sdim return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, 1079276479Sdim getType()))->Fold(&R, nullptr); 1080276479Sdim return Fold(&R, nullptr); 1081226584Sdim} 1082226584Sdim 1083226584Sdimstd::string TernOpInit::getAsString() const { 1084226584Sdim std::string Result; 1085296417Sdim switch (getOpcode()) { 1086226584Sdim case SUBST: Result = "!subst"; break; 1087226584Sdim case FOREACH: Result = "!foreach"; break; 1088226584Sdim case IF: Result = "!if"; break; 1089288943Sdim } 1090288943Sdim return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", " + 1091288943Sdim RHS->getAsString() + ")"; 1092226584Sdim} 1093226584Sdim 1094226584SdimRecTy *TypedInit::getFieldType(const std::string &FieldName) const { 1095243830Sdim if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) 1096243830Sdim if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName)) 1097226584Sdim return Field->getType(); 1098276479Sdim return nullptr; 1099226584Sdim} 1100226584Sdim 1101226584SdimInit * 1102288943SdimTypedInit::convertInitializerTo(RecTy *Ty) const { 1103288943Sdim if (isa<IntRecTy>(Ty)) { 1104288943Sdim if (getType()->typeIsConvertibleTo(Ty)) 1105288943Sdim return const_cast<TypedInit *>(this); 1106288943Sdim return nullptr; 1107288943Sdim } 1108288943Sdim 1109288943Sdim if (isa<StringRecTy>(Ty)) { 1110288943Sdim if (isa<StringRecTy>(getType())) 1111288943Sdim return const_cast<TypedInit *>(this); 1112288943Sdim return nullptr; 1113288943Sdim } 1114288943Sdim 1115288943Sdim if (isa<BitRecTy>(Ty)) { 1116288943Sdim // Accept variable if it is already of bit type! 1117288943Sdim if (isa<BitRecTy>(getType())) 1118288943Sdim return const_cast<TypedInit *>(this); 1119288943Sdim if (auto *BitsTy = dyn_cast<BitsRecTy>(getType())) { 1120288943Sdim // Accept only bits<1> expression. 1121288943Sdim if (BitsTy->getNumBits() == 1) 1122288943Sdim return const_cast<TypedInit *>(this); 1123288943Sdim return nullptr; 1124288943Sdim } 1125288943Sdim // Ternary !if can be converted to bit, but only if both sides are 1126288943Sdim // convertible to a bit. 1127288943Sdim if (const auto *TOI = dyn_cast<TernOpInit>(this)) { 1128288943Sdim if (TOI->getOpcode() == TernOpInit::TernaryOp::IF && 1129288943Sdim TOI->getMHS()->convertInitializerTo(BitRecTy::get()) && 1130288943Sdim TOI->getRHS()->convertInitializerTo(BitRecTy::get())) 1131288943Sdim return const_cast<TypedInit *>(this); 1132288943Sdim return nullptr; 1133288943Sdim } 1134288943Sdim return nullptr; 1135288943Sdim } 1136288943Sdim 1137288943Sdim if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { 1138288943Sdim if (BRT->getNumBits() == 1 && isa<BitRecTy>(getType())) 1139288943Sdim return BitsInit::get(const_cast<TypedInit *>(this)); 1140288943Sdim 1141288943Sdim if (getType()->typeIsConvertibleTo(BRT)) { 1142288943Sdim SmallVector<Init *, 16> NewBits(BRT->getNumBits()); 1143288943Sdim 1144288943Sdim for (unsigned i = 0; i != BRT->getNumBits(); ++i) 1145288943Sdim NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), i); 1146288943Sdim return BitsInit::get(NewBits); 1147288943Sdim } 1148288943Sdim 1149288943Sdim return nullptr; 1150288943Sdim } 1151288943Sdim 1152288943Sdim if (auto *DLRT = dyn_cast<ListRecTy>(Ty)) { 1153288943Sdim if (auto *SLRT = dyn_cast<ListRecTy>(getType())) 1154288943Sdim if (SLRT->getElementType()->typeIsConvertibleTo(DLRT->getElementType())) 1155288943Sdim return const_cast<TypedInit *>(this); 1156288943Sdim return nullptr; 1157288943Sdim } 1158288943Sdim 1159288943Sdim if (auto *DRT = dyn_cast<DagRecTy>(Ty)) { 1160288943Sdim if (getType()->typeIsConvertibleTo(DRT)) 1161288943Sdim return const_cast<TypedInit *>(this); 1162288943Sdim return nullptr; 1163288943Sdim } 1164288943Sdim 1165288943Sdim if (auto *SRRT = dyn_cast<RecordRecTy>(Ty)) { 1166288943Sdim // Ensure that this is compatible with Rec. 1167288943Sdim if (RecordRecTy *DRRT = dyn_cast<RecordRecTy>(getType())) 1168288943Sdim if (DRRT->getRecord()->isSubClassOf(SRRT->getRecord()) || 1169288943Sdim DRRT->getRecord() == SRRT->getRecord()) 1170288943Sdim return const_cast<TypedInit *>(this); 1171288943Sdim return nullptr; 1172288943Sdim } 1173288943Sdim 1174288943Sdim return nullptr; 1175288943Sdim} 1176288943Sdim 1177288943SdimInit * 1178226584SdimTypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { 1179243830Sdim BitsRecTy *T = dyn_cast<BitsRecTy>(getType()); 1180276479Sdim if (!T) return nullptr; // Cannot subscript a non-bits variable. 1181226584Sdim unsigned NumBits = T->getNumBits(); 1182226584Sdim 1183226584Sdim SmallVector<Init *, 16> NewBits(Bits.size()); 1184226584Sdim for (unsigned i = 0, e = Bits.size(); i != e; ++i) { 1185226584Sdim if (Bits[i] >= NumBits) 1186276479Sdim return nullptr; 1187226584Sdim 1188226584Sdim NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]); 1189226584Sdim } 1190226584Sdim return BitsInit::get(NewBits); 1191226584Sdim} 1192226584Sdim 1193226584SdimInit * 1194226584SdimTypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { 1195243830Sdim ListRecTy *T = dyn_cast<ListRecTy>(getType()); 1196276479Sdim if (!T) return nullptr; // Cannot subscript a non-list variable. 1197226584Sdim 1198226584Sdim if (Elements.size() == 1) 1199226584Sdim return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]); 1200226584Sdim 1201226584Sdim std::vector<Init*> ListInits; 1202226584Sdim ListInits.reserve(Elements.size()); 1203226584Sdim for (unsigned i = 0, e = Elements.size(); i != e; ++i) 1204226584Sdim ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this), 1205226584Sdim Elements[i])); 1206226584Sdim return ListInit::get(ListInits, T); 1207226584Sdim} 1208226584Sdim 1209226584Sdim 1210226584SdimVarInit *VarInit::get(const std::string &VN, RecTy *T) { 1211234353Sdim Init *Value = StringInit::get(VN); 1212234353Sdim return VarInit::get(Value, T); 1213234353Sdim} 1214234353Sdim 1215234353SdimVarInit *VarInit::get(Init *VN, RecTy *T) { 1216234353Sdim typedef std::pair<RecTy *, Init *> Key; 1217288943Sdim static DenseMap<Key, std::unique_ptr<VarInit>> ThePool; 1218226584Sdim 1219226584Sdim Key TheKey(std::make_pair(T, VN)); 1220226584Sdim 1221288943Sdim std::unique_ptr<VarInit> &I = ThePool[TheKey]; 1222288943Sdim if (!I) I.reset(new VarInit(VN, T)); 1223288943Sdim return I.get(); 1224226584Sdim} 1225226584Sdim 1226234353Sdimconst std::string &VarInit::getName() const { 1227288943Sdim StringInit *NameString = cast<StringInit>(getNameInit()); 1228234353Sdim return NameString->getValue(); 1229234353Sdim} 1230234353Sdim 1231243830SdimInit *VarInit::getBit(unsigned Bit) const { 1232243830Sdim if (getType() == BitRecTy::get()) 1233243830Sdim return const_cast<VarInit*>(this); 1234243830Sdim return VarBitInit::get(const_cast<VarInit*>(this), Bit); 1235226584Sdim} 1236226584Sdim 1237226584SdimInit *VarInit::resolveListElementReference(Record &R, 1238226584Sdim const RecordVal *IRV, 1239226584Sdim unsigned Elt) const { 1240276479Sdim if (R.isTemplateArg(getNameInit())) return nullptr; 1241276479Sdim if (IRV && IRV->getNameInit() != getNameInit()) return nullptr; 1242226584Sdim 1243234353Sdim RecordVal *RV = R.getValue(getNameInit()); 1244226584Sdim assert(RV && "Reference to a non-existent variable?"); 1245243830Sdim ListInit *LI = dyn_cast<ListInit>(RV->getValue()); 1246288943Sdim if (!LI) 1247288943Sdim return VarListElementInit::get(cast<TypedInit>(RV->getValue()), Elt); 1248226584Sdim 1249288943Sdim if (Elt >= LI->size()) 1250276479Sdim return nullptr; // Out of range reference. 1251226584Sdim Init *E = LI->getElement(Elt); 1252226584Sdim // If the element is set to some value, or if we are resolving a reference 1253226584Sdim // to a specific variable and that variable is explicitly unset, then 1254226584Sdim // replace the VarListElementInit with it. 1255243830Sdim if (IRV || !isa<UnsetInit>(E)) 1256226584Sdim return E; 1257276479Sdim return nullptr; 1258226584Sdim} 1259226584Sdim 1260226584Sdim 1261226584SdimRecTy *VarInit::getFieldType(const std::string &FieldName) const { 1262243830Sdim if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType())) 1263226584Sdim if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) 1264226584Sdim return RV->getType(); 1265276479Sdim return nullptr; 1266226584Sdim} 1267226584Sdim 1268226584SdimInit *VarInit::getFieldInit(Record &R, const RecordVal *RV, 1269226584Sdim const std::string &FieldName) const { 1270243830Sdim if (isa<RecordRecTy>(getType())) 1271226584Sdim if (const RecordVal *Val = R.getValue(VarName)) { 1272243830Sdim if (RV != Val && (RV || isa<UnsetInit>(Val->getValue()))) 1273276479Sdim return nullptr; 1274226584Sdim Init *TheInit = Val->getValue(); 1275226584Sdim assert(TheInit != this && "Infinite loop detected!"); 1276226584Sdim if (Init *I = TheInit->getFieldInit(R, RV, FieldName)) 1277226584Sdim return I; 1278288943Sdim return nullptr; 1279226584Sdim } 1280276479Sdim return nullptr; 1281226584Sdim} 1282226584Sdim 1283226584Sdim/// resolveReferences - This method is used by classes that refer to other 1284226584Sdim/// variables which may not be defined at the time the expression is formed. 1285226584Sdim/// If a value is set for the variable later, this method will be called on 1286226584Sdim/// users of the value to allow the value to propagate out. 1287226584Sdim/// 1288226584SdimInit *VarInit::resolveReferences(Record &R, const RecordVal *RV) const { 1289226584Sdim if (RecordVal *Val = R.getValue(VarName)) 1290276479Sdim if (RV == Val || (!RV && !isa<UnsetInit>(Val->getValue()))) 1291226584Sdim return Val->getValue(); 1292226584Sdim return const_cast<VarInit *>(this); 1293226584Sdim} 1294226584Sdim 1295226584SdimVarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { 1296226584Sdim typedef std::pair<TypedInit *, unsigned> Key; 1297288943Sdim static DenseMap<Key, std::unique_ptr<VarBitInit>> ThePool; 1298226584Sdim 1299226584Sdim Key TheKey(std::make_pair(T, B)); 1300226584Sdim 1301288943Sdim std::unique_ptr<VarBitInit> &I = ThePool[TheKey]; 1302288943Sdim if (!I) I.reset(new VarBitInit(T, B)); 1303288943Sdim return I.get(); 1304226584Sdim} 1305226584Sdim 1306288943SdimInit *VarBitInit::convertInitializerTo(RecTy *Ty) const { 1307288943Sdim if (isa<BitRecTy>(Ty)) 1308288943Sdim return const_cast<VarBitInit *>(this); 1309288943Sdim 1310288943Sdim return nullptr; 1311288943Sdim} 1312288943Sdim 1313226584Sdimstd::string VarBitInit::getAsString() const { 1314288943Sdim return TI->getAsString() + "{" + utostr(Bit) + "}"; 1315226584Sdim} 1316226584Sdim 1317226584SdimInit *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const { 1318243830Sdim Init *I = TI->resolveReferences(R, RV); 1319243830Sdim if (TI != I) 1320243830Sdim return I->getBit(getBitNum()); 1321243830Sdim 1322243830Sdim return const_cast<VarBitInit*>(this); 1323226584Sdim} 1324226584Sdim 1325226584SdimVarListElementInit *VarListElementInit::get(TypedInit *T, 1326226584Sdim unsigned E) { 1327226584Sdim typedef std::pair<TypedInit *, unsigned> Key; 1328288943Sdim static DenseMap<Key, std::unique_ptr<VarListElementInit>> ThePool; 1329226584Sdim 1330226584Sdim Key TheKey(std::make_pair(T, E)); 1331226584Sdim 1332288943Sdim std::unique_ptr<VarListElementInit> &I = ThePool[TheKey]; 1333288943Sdim if (!I) I.reset(new VarListElementInit(T, E)); 1334288943Sdim return I.get(); 1335226584Sdim} 1336226584Sdim 1337226584Sdimstd::string VarListElementInit::getAsString() const { 1338226584Sdim return TI->getAsString() + "[" + utostr(Element) + "]"; 1339226584Sdim} 1340226584Sdim 1341226584SdimInit * 1342226584SdimVarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const { 1343226584Sdim if (Init *I = getVariable()->resolveListElementReference(R, RV, 1344226584Sdim getElementNum())) 1345226584Sdim return I; 1346226584Sdim return const_cast<VarListElementInit *>(this); 1347226584Sdim} 1348226584Sdim 1349243830SdimInit *VarListElementInit::getBit(unsigned Bit) const { 1350243830Sdim if (getType() == BitRecTy::get()) 1351243830Sdim return const_cast<VarListElementInit*>(this); 1352243830Sdim return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit); 1353226584Sdim} 1354226584Sdim 1355226584SdimInit *VarListElementInit:: resolveListElementReference(Record &R, 1356226584Sdim const RecordVal *RV, 1357226584Sdim unsigned Elt) const { 1358288943Sdim if (Init *Result = TI->resolveListElementReference(R, RV, Element)) { 1359243830Sdim if (TypedInit *TInit = dyn_cast<TypedInit>(Result)) { 1360288943Sdim if (Init *Result2 = TInit->resolveListElementReference(R, RV, Elt)) 1361288943Sdim return Result2; 1362288943Sdim return VarListElementInit::get(TInit, Elt); 1363226584Sdim } 1364226584Sdim return Result; 1365226584Sdim } 1366288943Sdim 1367276479Sdim return nullptr; 1368226584Sdim} 1369226584Sdim 1370226584SdimDefInit *DefInit::get(Record *R) { 1371226584Sdim return R->getDefInit(); 1372226584Sdim} 1373226584Sdim 1374288943SdimInit *DefInit::convertInitializerTo(RecTy *Ty) const { 1375288943Sdim if (auto *RRT = dyn_cast<RecordRecTy>(Ty)) 1376288943Sdim if (getDef()->isSubClassOf(RRT->getRecord())) 1377288943Sdim return const_cast<DefInit *>(this); 1378288943Sdim return nullptr; 1379288943Sdim} 1380288943Sdim 1381226584SdimRecTy *DefInit::getFieldType(const std::string &FieldName) const { 1382226584Sdim if (const RecordVal *RV = Def->getValue(FieldName)) 1383226584Sdim return RV->getType(); 1384276479Sdim return nullptr; 1385226584Sdim} 1386226584Sdim 1387226584SdimInit *DefInit::getFieldInit(Record &R, const RecordVal *RV, 1388226584Sdim const std::string &FieldName) const { 1389226584Sdim return Def->getValue(FieldName)->getValue(); 1390226584Sdim} 1391226584Sdim 1392226584Sdim 1393226584Sdimstd::string DefInit::getAsString() const { 1394226584Sdim return Def->getName(); 1395226584Sdim} 1396226584Sdim 1397226584SdimFieldInit *FieldInit::get(Init *R, const std::string &FN) { 1398226584Sdim typedef std::pair<Init *, TableGenStringKey> Key; 1399288943Sdim static DenseMap<Key, std::unique_ptr<FieldInit>> ThePool; 1400226584Sdim 1401226584Sdim Key TheKey(std::make_pair(R, FN)); 1402226584Sdim 1403288943Sdim std::unique_ptr<FieldInit> &I = ThePool[TheKey]; 1404288943Sdim if (!I) I.reset(new FieldInit(R, FN)); 1405288943Sdim return I.get(); 1406226584Sdim} 1407226584Sdim 1408243830SdimInit *FieldInit::getBit(unsigned Bit) const { 1409243830Sdim if (getType() == BitRecTy::get()) 1410243830Sdim return const_cast<FieldInit*>(this); 1411243830Sdim return VarBitInit::get(const_cast<FieldInit*>(this), Bit); 1412226584Sdim} 1413226584Sdim 1414226584SdimInit *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV, 1415226584Sdim unsigned Elt) const { 1416226584Sdim if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName)) 1417243830Sdim if (ListInit *LI = dyn_cast<ListInit>(ListVal)) { 1418288943Sdim if (Elt >= LI->size()) return nullptr; 1419226584Sdim Init *E = LI->getElement(Elt); 1420226584Sdim 1421226584Sdim // If the element is set to some value, or if we are resolving a 1422226584Sdim // reference to a specific variable and that variable is explicitly 1423226584Sdim // unset, then replace the VarListElementInit with it. 1424243830Sdim if (RV || !isa<UnsetInit>(E)) 1425226584Sdim return E; 1426226584Sdim } 1427276479Sdim return nullptr; 1428226584Sdim} 1429226584Sdim 1430226584SdimInit *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const { 1431226584Sdim Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec; 1432226584Sdim 1433288943Sdim if (Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName)) { 1434226584Sdim Init *BVR = BitsVal->resolveReferences(R, RV); 1435226584Sdim return BVR->isComplete() ? BVR : const_cast<FieldInit *>(this); 1436226584Sdim } 1437226584Sdim 1438288943Sdim if (NewRec != Rec) 1439226584Sdim return FieldInit::get(NewRec, FieldName); 1440226584Sdim return const_cast<FieldInit *>(this); 1441226584Sdim} 1442226584Sdim 1443249423Sdimstatic void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN, 1444249423Sdim ArrayRef<Init *> ArgRange, 1445249423Sdim ArrayRef<std::string> NameRange) { 1446226584Sdim ID.AddPointer(V); 1447226584Sdim ID.AddString(VN); 1448226584Sdim 1449226584Sdim ArrayRef<Init *>::iterator Arg = ArgRange.begin(); 1450226584Sdim ArrayRef<std::string>::iterator Name = NameRange.begin(); 1451226584Sdim while (Arg != ArgRange.end()) { 1452226584Sdim assert(Name != NameRange.end() && "Arg name underflow!"); 1453226584Sdim ID.AddPointer(*Arg++); 1454226584Sdim ID.AddString(*Name++); 1455226584Sdim } 1456226584Sdim assert(Name == NameRange.end() && "Arg name overflow!"); 1457226584Sdim} 1458226584Sdim 1459226584SdimDagInit * 1460226584SdimDagInit::get(Init *V, const std::string &VN, 1461226584Sdim ArrayRef<Init *> ArgRange, 1462226584Sdim ArrayRef<std::string> NameRange) { 1463288943Sdim static FoldingSet<DagInit> ThePool; 1464288943Sdim static std::vector<std::unique_ptr<DagInit>> TheActualPool; 1465226584Sdim 1466226584Sdim FoldingSetNodeID ID; 1467226584Sdim ProfileDagInit(ID, V, VN, ArgRange, NameRange); 1468226584Sdim 1469276479Sdim void *IP = nullptr; 1470226584Sdim if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) 1471226584Sdim return I; 1472226584Sdim 1473226584Sdim DagInit *I = new DagInit(V, VN, ArgRange, NameRange); 1474226584Sdim ThePool.InsertNode(I, IP); 1475288943Sdim TheActualPool.push_back(std::unique_ptr<DagInit>(I)); 1476226584Sdim return I; 1477226584Sdim} 1478226584Sdim 1479226584SdimDagInit * 1480226584SdimDagInit::get(Init *V, const std::string &VN, 1481226584Sdim const std::vector<std::pair<Init*, std::string> > &args) { 1482226584Sdim std::vector<Init *> Args; 1483226584Sdim std::vector<std::string> Names; 1484226584Sdim 1485288943Sdim for (const auto &Arg : args) { 1486288943Sdim Args.push_back(Arg.first); 1487288943Sdim Names.push_back(Arg.second); 1488226584Sdim } 1489226584Sdim 1490226584Sdim return DagInit::get(V, VN, Args, Names); 1491226584Sdim} 1492226584Sdim 1493226584Sdimvoid DagInit::Profile(FoldingSetNodeID &ID) const { 1494226584Sdim ProfileDagInit(ID, Val, ValName, Args, ArgNames); 1495226584Sdim} 1496226584Sdim 1497288943SdimInit *DagInit::convertInitializerTo(RecTy *Ty) const { 1498288943Sdim if (isa<DagRecTy>(Ty)) 1499288943Sdim return const_cast<DagInit *>(this); 1500288943Sdim 1501288943Sdim return nullptr; 1502288943Sdim} 1503288943Sdim 1504226584SdimInit *DagInit::resolveReferences(Record &R, const RecordVal *RV) const { 1505226584Sdim std::vector<Init*> NewArgs; 1506226584Sdim for (unsigned i = 0, e = Args.size(); i != e; ++i) 1507226584Sdim NewArgs.push_back(Args[i]->resolveReferences(R, RV)); 1508226584Sdim 1509226584Sdim Init *Op = Val->resolveReferences(R, RV); 1510226584Sdim 1511226584Sdim if (Args != NewArgs || Op != Val) 1512226584Sdim return DagInit::get(Op, ValName, NewArgs, ArgNames); 1513226584Sdim 1514226584Sdim return const_cast<DagInit *>(this); 1515226584Sdim} 1516226584Sdim 1517226584Sdim 1518226584Sdimstd::string DagInit::getAsString() const { 1519226584Sdim std::string Result = "(" + Val->getAsString(); 1520226584Sdim if (!ValName.empty()) 1521226584Sdim Result += ":" + ValName; 1522288943Sdim if (!Args.empty()) { 1523226584Sdim Result += " " + Args[0]->getAsString(); 1524226584Sdim if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0]; 1525226584Sdim for (unsigned i = 1, e = Args.size(); i != e; ++i) { 1526226584Sdim Result += ", " + Args[i]->getAsString(); 1527226584Sdim if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i]; 1528226584Sdim } 1529226584Sdim } 1530226584Sdim return Result + ")"; 1531226584Sdim} 1532226584Sdim 1533226584Sdim 1534226584Sdim//===----------------------------------------------------------------------===// 1535226584Sdim// Other implementations 1536226584Sdim//===----------------------------------------------------------------------===// 1537226584Sdim 1538288943SdimRecordVal::RecordVal(Init *N, RecTy *T, bool P) 1539288943Sdim : NameAndPrefix(N, P), Ty(T) { 1540288943Sdim Value = UnsetInit::get()->convertInitializerTo(Ty); 1541226584Sdim assert(Value && "Cannot create unset value for current type!"); 1542226584Sdim} 1543226584Sdim 1544288943SdimRecordVal::RecordVal(const std::string &N, RecTy *T, bool P) 1545288943Sdim : NameAndPrefix(StringInit::get(N), P), Ty(T) { 1546288943Sdim Value = UnsetInit::get()->convertInitializerTo(Ty); 1547226584Sdim assert(Value && "Cannot create unset value for current type!"); 1548226584Sdim} 1549226584Sdim 1550226584Sdimconst std::string &RecordVal::getName() const { 1551288943Sdim return cast<StringInit>(getNameInit())->getValue(); 1552226584Sdim} 1553226584Sdim 1554226584Sdimvoid RecordVal::dump() const { errs() << *this; } 1555226584Sdim 1556226584Sdimvoid RecordVal::print(raw_ostream &OS, bool PrintSem) const { 1557226584Sdim if (getPrefix()) OS << "field "; 1558234353Sdim OS << *getType() << " " << getNameInitAsString(); 1559226584Sdim 1560226584Sdim if (getValue()) 1561226584Sdim OS << " = " << *getValue(); 1562226584Sdim 1563226584Sdim if (PrintSem) OS << ";\n"; 1564226584Sdim} 1565226584Sdim 1566226584Sdimunsigned Record::LastID = 0; 1567226584Sdim 1568234353Sdimvoid Record::init() { 1569234353Sdim checkName(); 1570234353Sdim 1571234353Sdim // Every record potentially has a def at the top. This value is 1572234353Sdim // replaced with the top-level def name at instantiation time. 1573234353Sdim RecordVal DN("NAME", StringRecTy::get(), 0); 1574234353Sdim addValue(DN); 1575234353Sdim} 1576234353Sdim 1577226584Sdimvoid Record::checkName() { 1578226584Sdim // Ensure the record name has string type. 1579288943Sdim const TypedInit *TypedName = cast<const TypedInit>(Name); 1580288943Sdim if (!isa<StringRecTy>(TypedName->getType())) 1581243830Sdim PrintFatalError(getLoc(), "Record name is not a string!"); 1582226584Sdim} 1583226584Sdim 1584226584SdimDefInit *Record::getDefInit() { 1585226584Sdim if (!TheInit) 1586288943Sdim TheInit.reset(new DefInit(this, new RecordRecTy(this))); 1587288943Sdim return TheInit.get(); 1588226584Sdim} 1589226584Sdim 1590226584Sdimconst std::string &Record::getName() const { 1591288943Sdim return cast<StringInit>(Name)->getValue(); 1592226584Sdim} 1593226584Sdim 1594226584Sdimvoid Record::setName(Init *NewName) { 1595234353Sdim Name = NewName; 1596226584Sdim checkName(); 1597226584Sdim // DO NOT resolve record values to the name at this point because 1598226584Sdim // there might be default values for arguments of this def. Those 1599226584Sdim // arguments might not have been resolved yet so we don't want to 1600226584Sdim // prematurely assume values for those arguments were not passed to 1601226584Sdim // this def. 1602226584Sdim // 1603226584Sdim // Nonetheless, it may be that some of this Record's values 1604226584Sdim // reference the record name. Indeed, the reason for having the 1605226584Sdim // record name be an Init is to provide this flexibility. The extra 1606226584Sdim // resolve steps after completely instantiating defs takes care of 1607226584Sdim // this. See TGParser::ParseDef and TGParser::ParseDefm. 1608226584Sdim} 1609226584Sdim 1610226584Sdimvoid Record::setName(const std::string &Name) { 1611226584Sdim setName(StringInit::get(Name)); 1612226584Sdim} 1613226584Sdim 1614226584Sdim/// resolveReferencesTo - If anything in this record refers to RV, replace the 1615226584Sdim/// reference to RV with the RHS of RV. If RV is null, we resolve all possible 1616226584Sdim/// references. 1617226584Sdimvoid Record::resolveReferencesTo(const RecordVal *RV) { 1618226584Sdim for (unsigned i = 0, e = Values.size(); i != e; ++i) { 1619234353Sdim if (RV == &Values[i]) // Skip resolve the same field as the given one 1620234353Sdim continue; 1621226584Sdim if (Init *V = Values[i].getValue()) 1622243830Sdim if (Values[i].setValue(V->resolveReferences(*this, RV))) 1623288943Sdim PrintFatalError(getLoc(), "Invalid value is found when setting '" + 1624288943Sdim Values[i].getNameInitAsString() + 1625288943Sdim "' after resolving references" + 1626288943Sdim (RV ? " against '" + RV->getNameInitAsString() + 1627288943Sdim "' of (" + RV->getValue()->getAsUnquotedString() + 1628288943Sdim ")" 1629288943Sdim : "") + "\n"); 1630226584Sdim } 1631234353Sdim Init *OldName = getNameInit(); 1632234353Sdim Init *NewName = Name->resolveReferences(*this, RV); 1633234353Sdim if (NewName != OldName) { 1634234353Sdim // Re-register with RecordKeeper. 1635234353Sdim setName(NewName); 1636234353Sdim } 1637226584Sdim} 1638226584Sdim 1639226584Sdimvoid Record::dump() const { errs() << *this; } 1640226584Sdim 1641226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) { 1642234353Sdim OS << R.getNameInitAsString(); 1643226584Sdim 1644296417Sdim ArrayRef<Init *> TArgs = R.getTemplateArgs(); 1645226584Sdim if (!TArgs.empty()) { 1646226584Sdim OS << "<"; 1647288943Sdim bool NeedComma = false; 1648288943Sdim for (const Init *TA : TArgs) { 1649288943Sdim if (NeedComma) OS << ", "; 1650288943Sdim NeedComma = true; 1651288943Sdim const RecordVal *RV = R.getValue(TA); 1652226584Sdim assert(RV && "Template argument record not found??"); 1653226584Sdim RV->print(OS, false); 1654226584Sdim } 1655226584Sdim OS << ">"; 1656226584Sdim } 1657226584Sdim 1658226584Sdim OS << " {"; 1659288943Sdim ArrayRef<Record *> SC = R.getSuperClasses(); 1660226584Sdim if (!SC.empty()) { 1661226584Sdim OS << "\t//"; 1662288943Sdim for (const Record *Super : SC) 1663288943Sdim OS << " " << Super->getNameInitAsString(); 1664226584Sdim } 1665226584Sdim OS << "\n"; 1666226584Sdim 1667288943Sdim for (const RecordVal &Val : R.getValues()) 1668288943Sdim if (Val.getPrefix() && !R.isTemplateArg(Val.getName())) 1669288943Sdim OS << Val; 1670288943Sdim for (const RecordVal &Val : R.getValues()) 1671288943Sdim if (!Val.getPrefix() && !R.isTemplateArg(Val.getName())) 1672288943Sdim OS << Val; 1673226584Sdim 1674226584Sdim return OS << "}\n"; 1675226584Sdim} 1676226584Sdim 1677226584Sdim/// getValueInit - Return the initializer for a value with the specified name, 1678243830Sdim/// or abort if the field does not exist. 1679226584Sdim/// 1680226584SdimInit *Record::getValueInit(StringRef FieldName) const { 1681226584Sdim const RecordVal *R = getValue(FieldName); 1682276479Sdim if (!R || !R->getValue()) 1683243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1684276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1685226584Sdim return R->getValue(); 1686226584Sdim} 1687226584Sdim 1688226584Sdim 1689226584Sdim/// getValueAsString - This method looks up the specified field and returns its 1690243830Sdim/// value as a string, aborts if the field does not exist or if 1691226584Sdim/// the value is not a string. 1692226584Sdim/// 1693226584Sdimstd::string Record::getValueAsString(StringRef FieldName) const { 1694226584Sdim const RecordVal *R = getValue(FieldName); 1695276479Sdim if (!R || !R->getValue()) 1696243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1697276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1698226584Sdim 1699243830Sdim if (StringInit *SI = dyn_cast<StringInit>(R->getValue())) 1700226584Sdim return SI->getValue(); 1701243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1702276479Sdim FieldName + "' does not have a string initializer!"); 1703226584Sdim} 1704226584Sdim 1705226584Sdim/// getValueAsBitsInit - This method looks up the specified field and returns 1706243830Sdim/// its value as a BitsInit, aborts if the field does not exist or if 1707243830Sdim/// the value is not the right type. 1708226584Sdim/// 1709226584SdimBitsInit *Record::getValueAsBitsInit(StringRef FieldName) const { 1710226584Sdim const RecordVal *R = getValue(FieldName); 1711276479Sdim if (!R || !R->getValue()) 1712243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1713276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1714226584Sdim 1715243830Sdim if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue())) 1716226584Sdim return BI; 1717243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1718276479Sdim FieldName + "' does not have a BitsInit initializer!"); 1719226584Sdim} 1720226584Sdim 1721226584Sdim/// getValueAsListInit - This method looks up the specified field and returns 1722243830Sdim/// its value as a ListInit, aborting if the field does not exist or if 1723243830Sdim/// the value is not the right type. 1724226584Sdim/// 1725226584SdimListInit *Record::getValueAsListInit(StringRef FieldName) const { 1726226584Sdim const RecordVal *R = getValue(FieldName); 1727276479Sdim if (!R || !R->getValue()) 1728243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1729276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1730226584Sdim 1731243830Sdim if (ListInit *LI = dyn_cast<ListInit>(R->getValue())) 1732226584Sdim return LI; 1733243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1734276479Sdim FieldName + "' does not have a list initializer!"); 1735226584Sdim} 1736226584Sdim 1737226584Sdim/// getValueAsListOfDefs - This method looks up the specified field and returns 1738243830Sdim/// its value as a vector of records, aborting if the field does not exist 1739243830Sdim/// or if the value is not the right type. 1740226584Sdim/// 1741226584Sdimstd::vector<Record*> 1742226584SdimRecord::getValueAsListOfDefs(StringRef FieldName) const { 1743226584Sdim ListInit *List = getValueAsListInit(FieldName); 1744226584Sdim std::vector<Record*> Defs; 1745288943Sdim for (Init *I : List->getValues()) { 1746288943Sdim if (DefInit *DI = dyn_cast<DefInit>(I)) 1747226584Sdim Defs.push_back(DI->getDef()); 1748288943Sdim else 1749243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1750276479Sdim FieldName + "' list is not entirely DefInit!"); 1751226584Sdim } 1752226584Sdim return Defs; 1753226584Sdim} 1754226584Sdim 1755226584Sdim/// getValueAsInt - This method looks up the specified field and returns its 1756243830Sdim/// value as an int64_t, aborting if the field does not exist or if the value 1757243830Sdim/// is not the right type. 1758226584Sdim/// 1759226584Sdimint64_t Record::getValueAsInt(StringRef FieldName) const { 1760226584Sdim const RecordVal *R = getValue(FieldName); 1761276479Sdim if (!R || !R->getValue()) 1762243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1763276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1764226584Sdim 1765243830Sdim if (IntInit *II = dyn_cast<IntInit>(R->getValue())) 1766226584Sdim return II->getValue(); 1767243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1768276479Sdim FieldName + "' does not have an int initializer!"); 1769226584Sdim} 1770226584Sdim 1771226584Sdim/// getValueAsListOfInts - This method looks up the specified field and returns 1772243830Sdim/// its value as a vector of integers, aborting if the field does not exist or 1773243830Sdim/// if the value is not the right type. 1774226584Sdim/// 1775226584Sdimstd::vector<int64_t> 1776226584SdimRecord::getValueAsListOfInts(StringRef FieldName) const { 1777226584Sdim ListInit *List = getValueAsListInit(FieldName); 1778226584Sdim std::vector<int64_t> Ints; 1779288943Sdim for (Init *I : List->getValues()) { 1780288943Sdim if (IntInit *II = dyn_cast<IntInit>(I)) 1781226584Sdim Ints.push_back(II->getValue()); 1782288943Sdim else 1783243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1784276479Sdim FieldName + "' does not have a list of ints initializer!"); 1785226584Sdim } 1786226584Sdim return Ints; 1787226584Sdim} 1788226584Sdim 1789226584Sdim/// getValueAsListOfStrings - This method looks up the specified field and 1790243830Sdim/// returns its value as a vector of strings, aborting if the field does not 1791243830Sdim/// exist or if the value is not the right type. 1792226584Sdim/// 1793226584Sdimstd::vector<std::string> 1794226584SdimRecord::getValueAsListOfStrings(StringRef FieldName) const { 1795226584Sdim ListInit *List = getValueAsListInit(FieldName); 1796226584Sdim std::vector<std::string> Strings; 1797288943Sdim for (Init *I : List->getValues()) { 1798288943Sdim if (StringInit *SI = dyn_cast<StringInit>(I)) 1799288943Sdim Strings.push_back(SI->getValue()); 1800288943Sdim else 1801243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1802276479Sdim FieldName + "' does not have a list of strings initializer!"); 1803226584Sdim } 1804226584Sdim return Strings; 1805226584Sdim} 1806226584Sdim 1807226584Sdim/// getValueAsDef - This method looks up the specified field and returns its 1808243830Sdim/// value as a Record, aborting if the field does not exist or if the value 1809243830Sdim/// is not the right type. 1810226584Sdim/// 1811226584SdimRecord *Record::getValueAsDef(StringRef FieldName) const { 1812226584Sdim const RecordVal *R = getValue(FieldName); 1813276479Sdim if (!R || !R->getValue()) 1814243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1815276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1816226584Sdim 1817243830Sdim if (DefInit *DI = dyn_cast<DefInit>(R->getValue())) 1818226584Sdim return DI->getDef(); 1819243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1820276479Sdim FieldName + "' does not have a def initializer!"); 1821226584Sdim} 1822226584Sdim 1823226584Sdim/// getValueAsBit - This method looks up the specified field and returns its 1824243830Sdim/// value as a bit, aborting if the field does not exist or if the value is 1825243830Sdim/// not the right type. 1826226584Sdim/// 1827226584Sdimbool Record::getValueAsBit(StringRef FieldName) const { 1828226584Sdim const RecordVal *R = getValue(FieldName); 1829276479Sdim if (!R || !R->getValue()) 1830243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1831276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1832226584Sdim 1833243830Sdim if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) 1834226584Sdim return BI->getValue(); 1835243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1836276479Sdim FieldName + "' does not have a bit initializer!"); 1837226584Sdim} 1838226584Sdim 1839243830Sdimbool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const { 1840243830Sdim const RecordVal *R = getValue(FieldName); 1841276479Sdim if (!R || !R->getValue()) 1842243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1843243830Sdim "' does not have a field named `" + FieldName.str() + "'!\n"); 1844243830Sdim 1845288943Sdim if (isa<UnsetInit>(R->getValue())) { 1846243830Sdim Unset = true; 1847243830Sdim return false; 1848243830Sdim } 1849243830Sdim Unset = false; 1850243830Sdim if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) 1851243830Sdim return BI->getValue(); 1852243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1853276479Sdim FieldName + "' does not have a bit initializer!"); 1854243830Sdim} 1855243830Sdim 1856226584Sdim/// getValueAsDag - This method looks up the specified field and returns its 1857243830Sdim/// value as an Dag, aborting if the field does not exist or if the value is 1858243830Sdim/// not the right type. 1859226584Sdim/// 1860226584SdimDagInit *Record::getValueAsDag(StringRef FieldName) const { 1861226584Sdim const RecordVal *R = getValue(FieldName); 1862276479Sdim if (!R || !R->getValue()) 1863243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + 1864276479Sdim "' does not have a field named `" + FieldName + "'!\n"); 1865226584Sdim 1866243830Sdim if (DagInit *DI = dyn_cast<DagInit>(R->getValue())) 1867226584Sdim return DI; 1868243830Sdim PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + 1869276479Sdim FieldName + "' does not have a dag initializer!"); 1870226584Sdim} 1871226584Sdim 1872226584Sdim 1873226584Sdimvoid MultiClass::dump() const { 1874226584Sdim errs() << "Record:\n"; 1875226584Sdim Rec.dump(); 1876226584Sdim 1877226584Sdim errs() << "Defs:\n"; 1878288943Sdim for (const auto &Proto : DefPrototypes) 1879288943Sdim Proto->dump(); 1880226584Sdim} 1881226584Sdim 1882226584Sdim 1883226584Sdimvoid RecordKeeper::dump() const { errs() << *this; } 1884226584Sdim 1885226584Sdimraw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { 1886226584Sdim OS << "------------- Classes -----------------\n"; 1887288943Sdim for (const auto &C : RK.getClasses()) 1888280031Sdim OS << "class " << *C.second; 1889226584Sdim 1890226584Sdim OS << "------------- Defs -----------------\n"; 1891288943Sdim for (const auto &D : RK.getDefs()) 1892280031Sdim OS << "def " << *D.second; 1893226584Sdim return OS; 1894226584Sdim} 1895226584Sdim 1896226584Sdim 1897226584Sdim/// getAllDerivedDefinitions - This method returns all concrete definitions 1898226584Sdim/// that derive from the specified class name. If a class with the specified 1899226584Sdim/// name does not exist, an error is printed and true is returned. 1900226584Sdimstd::vector<Record*> 1901226584SdimRecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const { 1902226584Sdim Record *Class = getClass(ClassName); 1903226584Sdim if (!Class) 1904243830Sdim PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); 1905226584Sdim 1906226584Sdim std::vector<Record*> Defs; 1907280031Sdim for (const auto &D : getDefs()) 1908280031Sdim if (D.second->isSubClassOf(Class)) 1909280031Sdim Defs.push_back(D.second.get()); 1910226584Sdim 1911226584Sdim return Defs; 1912226584Sdim} 1913226584Sdim 1914234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1915234353Sdim/// to CurRec's name. 1916234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1917234353Sdim Init *Name, const std::string &Scoper) { 1918288943Sdim RecTy *Type = cast<TypedInit>(Name)->getType(); 1919234353Sdim 1920234353Sdim BinOpInit *NewName = 1921288943Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1922288943Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1923288943Sdim CurRec.getNameInit(), 1924288943Sdim StringInit::get(Scoper), 1925288943Sdim Type)->Fold(&CurRec, CurMultiClass), 1926288943Sdim Name, 1927288943Sdim Type); 1928234353Sdim 1929234353Sdim if (CurMultiClass && Scoper != "::") { 1930234353Sdim NewName = 1931288943Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1932288943Sdim BinOpInit::get(BinOpInit::STRCONCAT, 1933288943Sdim CurMultiClass->Rec.getNameInit(), 1934288943Sdim StringInit::get("::"), 1935288943Sdim Type)->Fold(&CurRec, CurMultiClass), 1936288943Sdim NewName->Fold(&CurRec, CurMultiClass), 1937288943Sdim Type); 1938234353Sdim } 1939234353Sdim 1940234353Sdim return NewName->Fold(&CurRec, CurMultiClass); 1941234353Sdim} 1942234353Sdim 1943234353Sdim/// QualifyName - Return an Init with a qualifier prefix referring 1944234353Sdim/// to CurRec's name. 1945234353SdimInit *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, 1946234353Sdim const std::string &Name, 1947234353Sdim const std::string &Scoper) { 1948234353Sdim return QualifyName(CurRec, CurMultiClass, StringInit::get(Name), Scoper); 1949234353Sdim} 1950