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