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