xref: /freebsd-src/contrib/llvm-project/llvm/lib/TableGen/Record.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- Record.cpp - Record implementation ---------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implement the tablegen record classes.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
131fd87a68SDimitry Andric #include "llvm/TableGen/Record.h"
140b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
150b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
160b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
220b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
230b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
240b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
250b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
27bdd1243dSDimitry Andric #include "llvm/Support/MathExtras.h"
280b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
290b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
300b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
310b57cec5SDimitry Andric #include <cassert>
320b57cec5SDimitry Andric #include <cstdint>
330b57cec5SDimitry Andric #include <map>
341fd87a68SDimitry Andric #include <memory>
350b57cec5SDimitry Andric #include <string>
360b57cec5SDimitry Andric #include <utility>
370b57cec5SDimitry Andric #include <vector>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric using namespace llvm;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric #define DEBUG_TYPE "tblgen-records"
420b57cec5SDimitry Andric 
43349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
44349cc55cSDimitry Andric //    Context
45349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
46349cc55cSDimitry Andric 
47349cc55cSDimitry Andric namespace llvm {
48349cc55cSDimitry Andric namespace detail {
4981ad6265SDimitry Andric /// This class represents the internal implementation of the RecordKeeper.
5081ad6265SDimitry Andric /// It contains all of the contextual static state of the Record classes. It is
5181ad6265SDimitry Andric /// kept out-of-line to simplify dependencies, and also make it easier for
5281ad6265SDimitry Andric /// internal classes to access the uniquer state of the keeper.
5381ad6265SDimitry Andric struct RecordKeeperImpl {
5481ad6265SDimitry Andric   RecordKeeperImpl(RecordKeeper &RK)
5581ad6265SDimitry Andric       : SharedBitRecTy(RK), SharedIntRecTy(RK), SharedStringRecTy(RK),
5681ad6265SDimitry Andric         SharedDagRecTy(RK), AnyRecord(RK, 0), TheUnsetInit(RK),
5781ad6265SDimitry Andric         TrueBitInit(true, &SharedBitRecTy),
58349cc55cSDimitry Andric         FalseBitInit(false, &SharedBitRecTy), StringInitStringPool(Allocator),
5981ad6265SDimitry Andric         StringInitCodePool(Allocator), AnonCounter(0), LastRecordID(0) {}
60349cc55cSDimitry Andric 
61349cc55cSDimitry Andric   BumpPtrAllocator Allocator;
62349cc55cSDimitry Andric   std::vector<BitsRecTy *> SharedBitsRecTys;
63349cc55cSDimitry Andric   BitRecTy SharedBitRecTy;
64349cc55cSDimitry Andric   IntRecTy SharedIntRecTy;
65349cc55cSDimitry Andric   StringRecTy SharedStringRecTy;
66349cc55cSDimitry Andric   DagRecTy SharedDagRecTy;
67349cc55cSDimitry Andric 
68349cc55cSDimitry Andric   RecordRecTy AnyRecord;
69349cc55cSDimitry Andric   UnsetInit TheUnsetInit;
70349cc55cSDimitry Andric   BitInit TrueBitInit;
71349cc55cSDimitry Andric   BitInit FalseBitInit;
72349cc55cSDimitry Andric 
7306c3fb27SDimitry Andric   FoldingSet<ArgumentInit> TheArgumentInitPool;
74349cc55cSDimitry Andric   FoldingSet<BitsInit> TheBitsInitPool;
75349cc55cSDimitry Andric   std::map<int64_t, IntInit *> TheIntInitPool;
76349cc55cSDimitry Andric   StringMap<StringInit *, BumpPtrAllocator &> StringInitStringPool;
77349cc55cSDimitry Andric   StringMap<StringInit *, BumpPtrAllocator &> StringInitCodePool;
78349cc55cSDimitry Andric   FoldingSet<ListInit> TheListInitPool;
79349cc55cSDimitry Andric   FoldingSet<UnOpInit> TheUnOpInitPool;
80349cc55cSDimitry Andric   FoldingSet<BinOpInit> TheBinOpInitPool;
81349cc55cSDimitry Andric   FoldingSet<TernOpInit> TheTernOpInitPool;
82349cc55cSDimitry Andric   FoldingSet<FoldOpInit> TheFoldOpInitPool;
83349cc55cSDimitry Andric   FoldingSet<IsAOpInit> TheIsAOpInitPool;
8481ad6265SDimitry Andric   FoldingSet<ExistsOpInit> TheExistsOpInitPool;
85349cc55cSDimitry Andric   DenseMap<std::pair<RecTy *, Init *>, VarInit *> TheVarInitPool;
86349cc55cSDimitry Andric   DenseMap<std::pair<TypedInit *, unsigned>, VarBitInit *> TheVarBitInitPool;
87349cc55cSDimitry Andric   FoldingSet<VarDefInit> TheVarDefInitPool;
88349cc55cSDimitry Andric   DenseMap<std::pair<Init *, StringInit *>, FieldInit *> TheFieldInitPool;
89349cc55cSDimitry Andric   FoldingSet<CondOpInit> TheCondOpInitPool;
90349cc55cSDimitry Andric   FoldingSet<DagInit> TheDagInitPool;
9181ad6265SDimitry Andric   FoldingSet<RecordRecTy> RecordTypePool;
92349cc55cSDimitry Andric 
9381ad6265SDimitry Andric   unsigned AnonCounter;
94349cc55cSDimitry Andric   unsigned LastRecordID;
95349cc55cSDimitry Andric };
96349cc55cSDimitry Andric } // namespace detail
97349cc55cSDimitry Andric } // namespace llvm
98349cc55cSDimitry Andric 
990b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1000b57cec5SDimitry Andric //    Type implementations
1010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1040b57cec5SDimitry Andric LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); }
1050b57cec5SDimitry Andric #endif
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric ListRecTy *RecTy::getListTy() {
1080b57cec5SDimitry Andric   if (!ListTy)
10981ad6265SDimitry Andric     ListTy = new (RK.getImpl().Allocator) ListRecTy(this);
1100b57cec5SDimitry Andric   return ListTy;
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1140b57cec5SDimitry Andric   assert(RHS && "NULL pointer");
1150b57cec5SDimitry Andric   return Kind == RHS->getRecTyKind();
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; }
1190b57cec5SDimitry Andric 
12081ad6265SDimitry Andric BitRecTy *BitRecTy::get(RecordKeeper &RK) {
12181ad6265SDimitry Andric   return &RK.getImpl().SharedBitRecTy;
12281ad6265SDimitry Andric }
123349cc55cSDimitry Andric 
1240b57cec5SDimitry Andric bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
1250b57cec5SDimitry Andric   if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind)
1260b57cec5SDimitry Andric     return true;
1270b57cec5SDimitry Andric   if (const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS))
1280b57cec5SDimitry Andric     return BitsTy->getNumBits() == 1;
1290b57cec5SDimitry Andric   return false;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
13281ad6265SDimitry Andric BitsRecTy *BitsRecTy::get(RecordKeeper &RK, unsigned Sz) {
13381ad6265SDimitry Andric   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
13481ad6265SDimitry Andric   if (Sz >= RKImpl.SharedBitsRecTys.size())
13581ad6265SDimitry Andric     RKImpl.SharedBitsRecTys.resize(Sz + 1);
13681ad6265SDimitry Andric   BitsRecTy *&Ty = RKImpl.SharedBitsRecTys[Sz];
1370b57cec5SDimitry Andric   if (!Ty)
13881ad6265SDimitry Andric     Ty = new (RKImpl.Allocator) BitsRecTy(RK, Sz);
1390b57cec5SDimitry Andric   return Ty;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric std::string BitsRecTy::getAsString() const {
1430b57cec5SDimitry Andric   return "bits<" + utostr(Size) + ">";
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric bool BitsRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1470b57cec5SDimitry Andric   if (RecTy::typeIsConvertibleTo(RHS)) //argument and the sender are same type
1480b57cec5SDimitry Andric     return cast<BitsRecTy>(RHS)->Size == Size;
1490b57cec5SDimitry Andric   RecTyKind kind = RHS->getRecTyKind();
1500b57cec5SDimitry Andric   return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
15381ad6265SDimitry Andric IntRecTy *IntRecTy::get(RecordKeeper &RK) {
15481ad6265SDimitry Andric   return &RK.getImpl().SharedIntRecTy;
15581ad6265SDimitry Andric }
156349cc55cSDimitry Andric 
1570b57cec5SDimitry Andric bool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1580b57cec5SDimitry Andric   RecTyKind kind = RHS->getRecTyKind();
1590b57cec5SDimitry Andric   return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind;
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
16281ad6265SDimitry Andric StringRecTy *StringRecTy::get(RecordKeeper &RK) {
16381ad6265SDimitry Andric   return &RK.getImpl().SharedStringRecTy;
16481ad6265SDimitry Andric }
165349cc55cSDimitry Andric 
1660b57cec5SDimitry Andric std::string StringRecTy::getAsString() const {
1670b57cec5SDimitry Andric   return "string";
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric bool StringRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1710b57cec5SDimitry Andric   RecTyKind Kind = RHS->getRecTyKind();
172e8d8bef9SDimitry Andric   return Kind == StringRecTyKind;
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric std::string ListRecTy::getAsString() const {
176e8d8bef9SDimitry Andric   return "list<" + ElementTy->getAsString() + ">";
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric bool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1800b57cec5SDimitry Andric   if (const auto *ListTy = dyn_cast<ListRecTy>(RHS))
181e8d8bef9SDimitry Andric     return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
1820b57cec5SDimitry Andric   return false;
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric bool ListRecTy::typeIsA(const RecTy *RHS) const {
1860b57cec5SDimitry Andric   if (const ListRecTy *RHSl = dyn_cast<ListRecTy>(RHS))
1870b57cec5SDimitry Andric     return getElementType()->typeIsA(RHSl->getElementType());
1880b57cec5SDimitry Andric   return false;
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
19181ad6265SDimitry Andric DagRecTy *DagRecTy::get(RecordKeeper &RK) {
19281ad6265SDimitry Andric   return &RK.getImpl().SharedDagRecTy;
19381ad6265SDimitry Andric }
194349cc55cSDimitry Andric 
1950b57cec5SDimitry Andric std::string DagRecTy::getAsString() const {
1960b57cec5SDimitry Andric   return "dag";
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric static void ProfileRecordRecTy(FoldingSetNodeID &ID,
2000b57cec5SDimitry Andric                                ArrayRef<Record *> Classes) {
2010b57cec5SDimitry Andric   ID.AddInteger(Classes.size());
2020b57cec5SDimitry Andric   for (Record *R : Classes)
2030b57cec5SDimitry Andric     ID.AddPointer(R);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
20681ad6265SDimitry Andric RecordRecTy *RecordRecTy::get(RecordKeeper &RK,
20781ad6265SDimitry Andric                               ArrayRef<Record *> UnsortedClasses) {
20881ad6265SDimitry Andric   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
209349cc55cSDimitry Andric   if (UnsortedClasses.empty())
21081ad6265SDimitry Andric     return &RKImpl.AnyRecord;
2110b57cec5SDimitry Andric 
21281ad6265SDimitry Andric   FoldingSet<RecordRecTy> &ThePool = RKImpl.RecordTypePool;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   SmallVector<Record *, 4> Classes(UnsortedClasses.begin(),
2150b57cec5SDimitry Andric                                    UnsortedClasses.end());
2160b57cec5SDimitry Andric   llvm::sort(Classes, [](Record *LHS, Record *RHS) {
2170b57cec5SDimitry Andric     return LHS->getNameInitAsString() < RHS->getNameInitAsString();
2180b57cec5SDimitry Andric   });
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   FoldingSetNodeID ID;
2210b57cec5SDimitry Andric   ProfileRecordRecTy(ID, Classes);
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   void *IP = nullptr;
2240b57cec5SDimitry Andric   if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos(ID, IP))
2250b57cec5SDimitry Andric     return Ty;
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric #ifndef NDEBUG
2280b57cec5SDimitry Andric   // Check for redundancy.
2290b57cec5SDimitry Andric   for (unsigned i = 0; i < Classes.size(); ++i) {
2300b57cec5SDimitry Andric     for (unsigned j = 0; j < Classes.size(); ++j) {
2310b57cec5SDimitry Andric       assert(i == j || !Classes[i]->isSubClassOf(Classes[j]));
2320b57cec5SDimitry Andric     }
2330b57cec5SDimitry Andric     assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
2340b57cec5SDimitry Andric   }
2350b57cec5SDimitry Andric #endif
2360b57cec5SDimitry Andric 
23781ad6265SDimitry Andric   void *Mem = RKImpl.Allocator.Allocate(
238349cc55cSDimitry Andric       totalSizeToAlloc<Record *>(Classes.size()), alignof(RecordRecTy));
23981ad6265SDimitry Andric   RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes.size());
2400b57cec5SDimitry Andric   std::uninitialized_copy(Classes.begin(), Classes.end(),
2410b57cec5SDimitry Andric                           Ty->getTrailingObjects<Record *>());
2420b57cec5SDimitry Andric   ThePool.InsertNode(Ty, IP);
2430b57cec5SDimitry Andric   return Ty;
2440b57cec5SDimitry Andric }
24581ad6265SDimitry Andric RecordRecTy *RecordRecTy::get(Record *Class) {
24681ad6265SDimitry Andric   assert(Class && "unexpected null class");
24781ad6265SDimitry Andric   return get(Class->getRecords(), Class);
24881ad6265SDimitry Andric }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric void RecordRecTy::Profile(FoldingSetNodeID &ID) const {
2510b57cec5SDimitry Andric   ProfileRecordRecTy(ID, getClasses());
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric std::string RecordRecTy::getAsString() const {
2550b57cec5SDimitry Andric   if (NumClasses == 1)
2560b57cec5SDimitry Andric     return getClasses()[0]->getNameInitAsString();
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   std::string Str = "{";
2590b57cec5SDimitry Andric   bool First = true;
2600b57cec5SDimitry Andric   for (Record *R : getClasses()) {
2610b57cec5SDimitry Andric     if (!First)
2620b57cec5SDimitry Andric       Str += ", ";
2630b57cec5SDimitry Andric     First = false;
2640b57cec5SDimitry Andric     Str += R->getNameInitAsString();
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric   Str += "}";
2670b57cec5SDimitry Andric   return Str;
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric bool RecordRecTy::isSubClassOf(Record *Class) const {
2710b57cec5SDimitry Andric   return llvm::any_of(getClasses(), [Class](Record *MySuperClass) {
2720b57cec5SDimitry Andric                                       return MySuperClass == Class ||
2730b57cec5SDimitry Andric                                              MySuperClass->isSubClassOf(Class);
2740b57cec5SDimitry Andric                                     });
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
2780b57cec5SDimitry Andric   if (this == RHS)
2790b57cec5SDimitry Andric     return true;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS);
2820b57cec5SDimitry Andric   if (!RTy)
2830b57cec5SDimitry Andric     return false;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   return llvm::all_of(RTy->getClasses(), [this](Record *TargetClass) {
2860b57cec5SDimitry Andric                                            return isSubClassOf(TargetClass);
2870b57cec5SDimitry Andric                                          });
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric bool RecordRecTy::typeIsA(const RecTy *RHS) const {
2910b57cec5SDimitry Andric   return typeIsConvertibleTo(RHS);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) {
2950b57cec5SDimitry Andric   SmallVector<Record *, 4> CommonSuperClasses;
296e8d8bef9SDimitry Andric   SmallVector<Record *, 4> Stack(T1->classes_begin(), T1->classes_end());
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   while (!Stack.empty()) {
299e8d8bef9SDimitry Andric     Record *R = Stack.pop_back_val();
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric     if (T2->isSubClassOf(R)) {
3020b57cec5SDimitry Andric       CommonSuperClasses.push_back(R);
3030b57cec5SDimitry Andric     } else {
3040b57cec5SDimitry Andric       R->getDirectSuperClasses(Stack);
3050b57cec5SDimitry Andric     }
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
30881ad6265SDimitry Andric   return RecordRecTy::get(T1->getRecordKeeper(), CommonSuperClasses);
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
3120b57cec5SDimitry Andric   if (T1 == T2)
3130b57cec5SDimitry Andric     return T1;
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
3160b57cec5SDimitry Andric     if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
3170b57cec5SDimitry Andric       return resolveRecordTypes(RecTy1, RecTy2);
3180b57cec5SDimitry Andric   }
3190b57cec5SDimitry Andric 
32006c3fb27SDimitry Andric   assert(T1 != nullptr && "Invalid record type");
3210b57cec5SDimitry Andric   if (T1->typeIsConvertibleTo(T2))
3220b57cec5SDimitry Andric     return T2;
32306c3fb27SDimitry Andric 
32406c3fb27SDimitry Andric   assert(T2 != nullptr && "Invalid record type");
3250b57cec5SDimitry Andric   if (T2->typeIsConvertibleTo(T1))
3260b57cec5SDimitry Andric     return T1;
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   if (ListRecTy *ListTy1 = dyn_cast<ListRecTy>(T1)) {
3290b57cec5SDimitry Andric     if (ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
3300b57cec5SDimitry Andric       RecTy* NewType = resolveTypes(ListTy1->getElementType(),
3310b57cec5SDimitry Andric                                     ListTy2->getElementType());
3320b57cec5SDimitry Andric       if (NewType)
3330b57cec5SDimitry Andric         return NewType->getListTy();
3340b57cec5SDimitry Andric     }
3350b57cec5SDimitry Andric   }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   return nullptr;
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3410b57cec5SDimitry Andric //    Initializer implementations
3420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric void Init::anchor() {}
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3470b57cec5SDimitry Andric LLVM_DUMP_METHOD void Init::dump() const { return print(errs()); }
3480b57cec5SDimitry Andric #endif
3490b57cec5SDimitry Andric 
35081ad6265SDimitry Andric RecordKeeper &Init::getRecordKeeper() const {
35181ad6265SDimitry Andric   if (auto *TyInit = dyn_cast<TypedInit>(this))
35281ad6265SDimitry Andric     return TyInit->getType()->getRecordKeeper();
35306c3fb27SDimitry Andric   if (auto *ArgInit = dyn_cast<ArgumentInit>(this))
35406c3fb27SDimitry Andric     return ArgInit->getRecordKeeper();
35581ad6265SDimitry Andric   return cast<UnsetInit>(this)->getRecordKeeper();
35681ad6265SDimitry Andric }
35781ad6265SDimitry Andric 
35881ad6265SDimitry Andric UnsetInit *UnsetInit::get(RecordKeeper &RK) {
35981ad6265SDimitry Andric   return &RK.getImpl().TheUnsetInit;
36081ad6265SDimitry Andric }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric Init *UnsetInit::getCastTo(RecTy *Ty) const {
3630b57cec5SDimitry Andric   return const_cast<UnsetInit *>(this);
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric Init *UnsetInit::convertInitializerTo(RecTy *Ty) const {
3670b57cec5SDimitry Andric   return const_cast<UnsetInit *>(this);
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
37006c3fb27SDimitry Andric static void ProfileArgumentInit(FoldingSetNodeID &ID, Init *Value,
37106c3fb27SDimitry Andric                                 ArgAuxType Aux) {
37206c3fb27SDimitry Andric   auto I = Aux.index();
37306c3fb27SDimitry Andric   ID.AddInteger(I);
37406c3fb27SDimitry Andric   if (I == ArgumentInit::Positional)
37506c3fb27SDimitry Andric     ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
37606c3fb27SDimitry Andric   if (I == ArgumentInit::Named)
37706c3fb27SDimitry Andric     ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
37806c3fb27SDimitry Andric   ID.AddPointer(Value);
37906c3fb27SDimitry Andric }
38006c3fb27SDimitry Andric 
38106c3fb27SDimitry Andric void ArgumentInit::Profile(FoldingSetNodeID &ID) const {
38206c3fb27SDimitry Andric   ProfileArgumentInit(ID, Value, Aux);
38306c3fb27SDimitry Andric }
38406c3fb27SDimitry Andric 
38506c3fb27SDimitry Andric ArgumentInit *ArgumentInit::get(Init *Value, ArgAuxType Aux) {
38606c3fb27SDimitry Andric   FoldingSetNodeID ID;
38706c3fb27SDimitry Andric   ProfileArgumentInit(ID, Value, Aux);
38806c3fb27SDimitry Andric 
38906c3fb27SDimitry Andric   RecordKeeper &RK = Value->getRecordKeeper();
39006c3fb27SDimitry Andric   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
39106c3fb27SDimitry Andric   void *IP = nullptr;
39206c3fb27SDimitry Andric   if (ArgumentInit *I = RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
39306c3fb27SDimitry Andric     return I;
39406c3fb27SDimitry Andric 
39506c3fb27SDimitry Andric   ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value, Aux);
39606c3fb27SDimitry Andric   RKImpl.TheArgumentInitPool.InsertNode(I, IP);
39706c3fb27SDimitry Andric   return I;
39806c3fb27SDimitry Andric }
39906c3fb27SDimitry Andric 
40006c3fb27SDimitry Andric Init *ArgumentInit::resolveReferences(Resolver &R) const {
40106c3fb27SDimitry Andric   Init *NewValue = Value->resolveReferences(R);
40206c3fb27SDimitry Andric   if (NewValue != Value)
40306c3fb27SDimitry Andric     return cloneWithValue(NewValue);
40406c3fb27SDimitry Andric 
40506c3fb27SDimitry Andric   return const_cast<ArgumentInit *>(this);
40606c3fb27SDimitry Andric }
40706c3fb27SDimitry Andric 
40881ad6265SDimitry Andric BitInit *BitInit::get(RecordKeeper &RK, bool V) {
40981ad6265SDimitry Andric   return V ? &RK.getImpl().TrueBitInit : &RK.getImpl().FalseBitInit;
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric Init *BitInit::convertInitializerTo(RecTy *Ty) const {
4130b57cec5SDimitry Andric   if (isa<BitRecTy>(Ty))
4140b57cec5SDimitry Andric     return const_cast<BitInit *>(this);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   if (isa<IntRecTy>(Ty))
41781ad6265SDimitry Andric     return IntInit::get(getRecordKeeper(), getValue());
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
4200b57cec5SDimitry Andric     // Can only convert single bit.
4210b57cec5SDimitry Andric     if (BRT->getNumBits() == 1)
42281ad6265SDimitry Andric       return BitsInit::get(getRecordKeeper(), const_cast<BitInit *>(this));
4230b57cec5SDimitry Andric   }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   return nullptr;
4260b57cec5SDimitry Andric }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric static void
4290b57cec5SDimitry Andric ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
4300b57cec5SDimitry Andric   ID.AddInteger(Range.size());
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   for (Init *I : Range)
4330b57cec5SDimitry Andric     ID.AddPointer(I);
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
43681ad6265SDimitry Andric BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<Init *> Range) {
4370b57cec5SDimitry Andric   FoldingSetNodeID ID;
4380b57cec5SDimitry Andric   ProfileBitsInit(ID, Range);
4390b57cec5SDimitry Andric 
44081ad6265SDimitry Andric   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
4410b57cec5SDimitry Andric   void *IP = nullptr;
44281ad6265SDimitry Andric   if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
4430b57cec5SDimitry Andric     return I;
4440b57cec5SDimitry Andric 
44581ad6265SDimitry Andric   void *Mem = RKImpl.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
44681ad6265SDimitry Andric                                         alignof(BitsInit));
44781ad6265SDimitry Andric   BitsInit *I = new (Mem) BitsInit(RK, Range.size());
4480b57cec5SDimitry Andric   std::uninitialized_copy(Range.begin(), Range.end(),
4490b57cec5SDimitry Andric                           I->getTrailingObjects<Init *>());
45081ad6265SDimitry Andric   RKImpl.TheBitsInitPool.InsertNode(I, IP);
4510b57cec5SDimitry Andric   return I;
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric void BitsInit::Profile(FoldingSetNodeID &ID) const {
455bdd1243dSDimitry Andric   ProfileBitsInit(ID, ArrayRef(getTrailingObjects<Init *>(), NumBits));
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric Init *BitsInit::convertInitializerTo(RecTy *Ty) const {
4590b57cec5SDimitry Andric   if (isa<BitRecTy>(Ty)) {
4600b57cec5SDimitry Andric     if (getNumBits() != 1) return nullptr; // Only accept if just one bit!
4610b57cec5SDimitry Andric     return getBit(0);
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
4650b57cec5SDimitry Andric     // If the number of bits is right, return it.  Otherwise we need to expand
4660b57cec5SDimitry Andric     // or truncate.
4670b57cec5SDimitry Andric     if (getNumBits() != BRT->getNumBits()) return nullptr;
4680b57cec5SDimitry Andric     return const_cast<BitsInit *>(this);
4690b57cec5SDimitry Andric   }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   if (isa<IntRecTy>(Ty)) {
4720b57cec5SDimitry Andric     int64_t Result = 0;
4730b57cec5SDimitry Andric     for (unsigned i = 0, e = getNumBits(); i != e; ++i)
4740b57cec5SDimitry Andric       if (auto *Bit = dyn_cast<BitInit>(getBit(i)))
4750b57cec5SDimitry Andric         Result |= static_cast<int64_t>(Bit->getValue()) << i;
4760b57cec5SDimitry Andric       else
4770b57cec5SDimitry Andric         return nullptr;
47881ad6265SDimitry Andric     return IntInit::get(getRecordKeeper(), Result);
4790b57cec5SDimitry Andric   }
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   return nullptr;
4820b57cec5SDimitry Andric }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric Init *
4850b57cec5SDimitry Andric BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
4860b57cec5SDimitry Andric   SmallVector<Init *, 16> NewBits(Bits.size());
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
4890b57cec5SDimitry Andric     if (Bits[i] >= getNumBits())
4900b57cec5SDimitry Andric       return nullptr;
4910b57cec5SDimitry Andric     NewBits[i] = getBit(Bits[i]);
4920b57cec5SDimitry Andric   }
49381ad6265SDimitry Andric   return BitsInit::get(getRecordKeeper(), NewBits);
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric bool BitsInit::isConcrete() const {
4970b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
4980b57cec5SDimitry Andric     if (!getBit(i)->isConcrete())
4990b57cec5SDimitry Andric       return false;
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric   return true;
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric std::string BitsInit::getAsString() const {
5050b57cec5SDimitry Andric   std::string Result = "{ ";
5060b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
5070b57cec5SDimitry Andric     if (i) Result += ", ";
5080b57cec5SDimitry Andric     if (Init *Bit = getBit(e-i-1))
5090b57cec5SDimitry Andric       Result += Bit->getAsString();
5100b57cec5SDimitry Andric     else
5110b57cec5SDimitry Andric       Result += "*";
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric   return Result + " }";
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric // resolveReferences - If there are any field references that refer to fields
5170b57cec5SDimitry Andric // that have been filled in, we can propagate the values now.
5180b57cec5SDimitry Andric Init *BitsInit::resolveReferences(Resolver &R) const {
5190b57cec5SDimitry Andric   bool Changed = false;
5200b57cec5SDimitry Andric   SmallVector<Init *, 16> NewBits(getNumBits());
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   Init *CachedBitVarRef = nullptr;
5230b57cec5SDimitry Andric   Init *CachedBitVarResolved = nullptr;
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
5260b57cec5SDimitry Andric     Init *CurBit = getBit(i);
5270b57cec5SDimitry Andric     Init *NewBit = CurBit;
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric     if (VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
5300b57cec5SDimitry Andric       if (CurBitVar->getBitVar() != CachedBitVarRef) {
5310b57cec5SDimitry Andric         CachedBitVarRef = CurBitVar->getBitVar();
5320b57cec5SDimitry Andric         CachedBitVarResolved = CachedBitVarRef->resolveReferences(R);
5330b57cec5SDimitry Andric       }
5348bcb0991SDimitry Andric       assert(CachedBitVarResolved && "Unresolved bitvar reference");
5350b57cec5SDimitry Andric       NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum());
5360b57cec5SDimitry Andric     } else {
5370b57cec5SDimitry Andric       // getBit(0) implicitly converts int and bits<1> values to bit.
5380b57cec5SDimitry Andric       NewBit = CurBit->resolveReferences(R)->getBit(0);
5390b57cec5SDimitry Andric     }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric     if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
5420b57cec5SDimitry Andric       NewBit = CurBit;
5430b57cec5SDimitry Andric     NewBits[i] = NewBit;
5440b57cec5SDimitry Andric     Changed |= CurBit != NewBit;
5450b57cec5SDimitry Andric   }
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   if (Changed)
54881ad6265SDimitry Andric     return BitsInit::get(getRecordKeeper(), NewBits);
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   return const_cast<BitsInit *>(this);
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric 
55381ad6265SDimitry Andric IntInit *IntInit::get(RecordKeeper &RK, int64_t V) {
55481ad6265SDimitry Andric   IntInit *&I = RK.getImpl().TheIntInitPool[V];
555349cc55cSDimitry Andric   if (!I)
55681ad6265SDimitry Andric     I = new (RK.getImpl().Allocator) IntInit(RK, V);
5570b57cec5SDimitry Andric   return I;
5580b57cec5SDimitry Andric }
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric std::string IntInit::getAsString() const {
5610b57cec5SDimitry Andric   return itostr(Value);
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
5650b57cec5SDimitry Andric   // For example, with NumBits == 4, we permit Values from [-7 .. 15].
5660b57cec5SDimitry Andric   return (NumBits >= sizeof(Value) * 8) ||
5670b57cec5SDimitry Andric          (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric Init *IntInit::convertInitializerTo(RecTy *Ty) const {
5710b57cec5SDimitry Andric   if (isa<IntRecTy>(Ty))
5720b57cec5SDimitry Andric     return const_cast<IntInit *>(this);
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   if (isa<BitRecTy>(Ty)) {
5750b57cec5SDimitry Andric     int64_t Val = getValue();
5760b57cec5SDimitry Andric     if (Val != 0 && Val != 1) return nullptr;  // Only accept 0 or 1 for a bit!
57781ad6265SDimitry Andric     return BitInit::get(getRecordKeeper(), Val != 0);
5780b57cec5SDimitry Andric   }
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
5810b57cec5SDimitry Andric     int64_t Value = getValue();
5820b57cec5SDimitry Andric     // Make sure this bitfield is large enough to hold the integer value.
5830b57cec5SDimitry Andric     if (!canFitInBitfield(Value, BRT->getNumBits()))
5840b57cec5SDimitry Andric       return nullptr;
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric     SmallVector<Init *, 16> NewBits(BRT->getNumBits());
5870b57cec5SDimitry Andric     for (unsigned i = 0; i != BRT->getNumBits(); ++i)
58881ad6265SDimitry Andric       NewBits[i] =
58981ad6265SDimitry Andric           BitInit::get(getRecordKeeper(), Value & ((i < 64) ? (1LL << i) : 0));
5900b57cec5SDimitry Andric 
59181ad6265SDimitry Andric     return BitsInit::get(getRecordKeeper(), NewBits);
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   return nullptr;
5950b57cec5SDimitry Andric }
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric Init *
5980b57cec5SDimitry Andric IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
5990b57cec5SDimitry Andric   SmallVector<Init *, 16> NewBits(Bits.size());
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
6020b57cec5SDimitry Andric     if (Bits[i] >= 64)
6030b57cec5SDimitry Andric       return nullptr;
6040b57cec5SDimitry Andric 
60581ad6265SDimitry Andric     NewBits[i] =
60681ad6265SDimitry Andric         BitInit::get(getRecordKeeper(), Value & (INT64_C(1) << Bits[i]));
6070b57cec5SDimitry Andric   }
60881ad6265SDimitry Andric   return BitsInit::get(getRecordKeeper(), NewBits);
6090b57cec5SDimitry Andric }
6100b57cec5SDimitry Andric 
61181ad6265SDimitry Andric AnonymousNameInit *AnonymousNameInit::get(RecordKeeper &RK, unsigned V) {
61281ad6265SDimitry Andric   return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V);
613fe6060f1SDimitry Andric }
614fe6060f1SDimitry Andric 
615fe6060f1SDimitry Andric StringInit *AnonymousNameInit::getNameInit() const {
61681ad6265SDimitry Andric   return StringInit::get(getRecordKeeper(), getAsString());
617fe6060f1SDimitry Andric }
618fe6060f1SDimitry Andric 
619fe6060f1SDimitry Andric std::string AnonymousNameInit::getAsString() const {
620fe6060f1SDimitry Andric   return "anonymous_" + utostr(Value);
621fe6060f1SDimitry Andric }
622fe6060f1SDimitry Andric 
623fe6060f1SDimitry Andric Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
624fe6060f1SDimitry Andric   auto *Old = const_cast<Init *>(static_cast<const Init *>(this));
625fe6060f1SDimitry Andric   auto *New = R.resolve(Old);
626fe6060f1SDimitry Andric   New = New ? New : Old;
627fe6060f1SDimitry Andric   if (R.isFinal())
628fe6060f1SDimitry Andric     if (auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
629fe6060f1SDimitry Andric       return Anonymous->getNameInit();
630fe6060f1SDimitry Andric   return New;
631fe6060f1SDimitry Andric }
632fe6060f1SDimitry Andric 
63381ad6265SDimitry Andric StringInit *StringInit::get(RecordKeeper &RK, StringRef V, StringFormat Fmt) {
63481ad6265SDimitry Andric   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
63581ad6265SDimitry Andric   auto &InitMap = Fmt == SF_String ? RKImpl.StringInitStringPool
63681ad6265SDimitry Andric                                    : RKImpl.StringInitCodePool;
637349cc55cSDimitry Andric   auto &Entry = *InitMap.insert(std::make_pair(V, nullptr)).first;
6380b57cec5SDimitry Andric   if (!Entry.second)
63981ad6265SDimitry Andric     Entry.second = new (RKImpl.Allocator) StringInit(RK, Entry.getKey(), Fmt);
6400b57cec5SDimitry Andric   return Entry.second;
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric Init *StringInit::convertInitializerTo(RecTy *Ty) const {
6440b57cec5SDimitry Andric   if (isa<StringRecTy>(Ty))
6450b57cec5SDimitry Andric     return const_cast<StringInit *>(this);
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   return nullptr;
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric static void ProfileListInit(FoldingSetNodeID &ID,
6510b57cec5SDimitry Andric                             ArrayRef<Init *> Range,
6520b57cec5SDimitry Andric                             RecTy *EltTy) {
6530b57cec5SDimitry Andric   ID.AddInteger(Range.size());
6540b57cec5SDimitry Andric   ID.AddPointer(EltTy);
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   for (Init *I : Range)
6570b57cec5SDimitry Andric     ID.AddPointer(I);
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
6610b57cec5SDimitry Andric   FoldingSetNodeID ID;
6620b57cec5SDimitry Andric   ProfileListInit(ID, Range, EltTy);
6630b57cec5SDimitry Andric 
66481ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl();
6650b57cec5SDimitry Andric   void *IP = nullptr;
66681ad6265SDimitry Andric   if (ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
6670b57cec5SDimitry Andric     return I;
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
6700b57cec5SDimitry Andric          cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
6710b57cec5SDimitry Andric 
67281ad6265SDimitry Andric   void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
67381ad6265SDimitry Andric                                     alignof(ListInit));
6740b57cec5SDimitry Andric   ListInit *I = new (Mem) ListInit(Range.size(), EltTy);
6750b57cec5SDimitry Andric   std::uninitialized_copy(Range.begin(), Range.end(),
6760b57cec5SDimitry Andric                           I->getTrailingObjects<Init *>());
67781ad6265SDimitry Andric   RK.TheListInitPool.InsertNode(I, IP);
6780b57cec5SDimitry Andric   return I;
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric 
6810b57cec5SDimitry Andric void ListInit::Profile(FoldingSetNodeID &ID) const {
6820b57cec5SDimitry Andric   RecTy *EltTy = cast<ListRecTy>(getType())->getElementType();
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric   ProfileListInit(ID, getValues(), EltTy);
6850b57cec5SDimitry Andric }
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric Init *ListInit::convertInitializerTo(RecTy *Ty) const {
6880b57cec5SDimitry Andric   if (getType() == Ty)
6890b57cec5SDimitry Andric     return const_cast<ListInit*>(this);
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   if (auto *LRT = dyn_cast<ListRecTy>(Ty)) {
6920b57cec5SDimitry Andric     SmallVector<Init*, 8> Elements;
6930b57cec5SDimitry Andric     Elements.reserve(getValues().size());
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric     // Verify that all of the elements of the list are subclasses of the
6960b57cec5SDimitry Andric     // appropriate class!
6970b57cec5SDimitry Andric     bool Changed = false;
6980b57cec5SDimitry Andric     RecTy *ElementType = LRT->getElementType();
6990b57cec5SDimitry Andric     for (Init *I : getValues())
7000b57cec5SDimitry Andric       if (Init *CI = I->convertInitializerTo(ElementType)) {
7010b57cec5SDimitry Andric         Elements.push_back(CI);
7020b57cec5SDimitry Andric         if (CI != I)
7030b57cec5SDimitry Andric           Changed = true;
7040b57cec5SDimitry Andric       } else
7050b57cec5SDimitry Andric         return nullptr;
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric     if (!Changed)
7080b57cec5SDimitry Andric       return const_cast<ListInit*>(this);
7090b57cec5SDimitry Andric     return ListInit::get(Elements, ElementType);
7100b57cec5SDimitry Andric   }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric   return nullptr;
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric Record *ListInit::getElementAsRecord(unsigned i) const {
7160b57cec5SDimitry Andric   assert(i < NumValues && "List element index out of range!");
7170b57cec5SDimitry Andric   DefInit *DI = dyn_cast<DefInit>(getElement(i));
7180b57cec5SDimitry Andric   if (!DI)
7190b57cec5SDimitry Andric     PrintFatalError("Expected record in list!");
7200b57cec5SDimitry Andric   return DI->getDef();
7210b57cec5SDimitry Andric }
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric Init *ListInit::resolveReferences(Resolver &R) const {
7240b57cec5SDimitry Andric   SmallVector<Init*, 8> Resolved;
7250b57cec5SDimitry Andric   Resolved.reserve(size());
7260b57cec5SDimitry Andric   bool Changed = false;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   for (Init *CurElt : getValues()) {
7290b57cec5SDimitry Andric     Init *E = CurElt->resolveReferences(R);
7300b57cec5SDimitry Andric     Changed |= E != CurElt;
7310b57cec5SDimitry Andric     Resolved.push_back(E);
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   if (Changed)
7350b57cec5SDimitry Andric     return ListInit::get(Resolved, getElementType());
7360b57cec5SDimitry Andric   return const_cast<ListInit *>(this);
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric 
739fe6060f1SDimitry Andric bool ListInit::isComplete() const {
740fe6060f1SDimitry Andric   for (Init *Element : *this) {
741fe6060f1SDimitry Andric     if (!Element->isComplete())
742fe6060f1SDimitry Andric       return false;
743fe6060f1SDimitry Andric   }
744fe6060f1SDimitry Andric   return true;
745fe6060f1SDimitry Andric }
746fe6060f1SDimitry Andric 
7470b57cec5SDimitry Andric bool ListInit::isConcrete() const {
7480b57cec5SDimitry Andric   for (Init *Element : *this) {
7490b57cec5SDimitry Andric     if (!Element->isConcrete())
7500b57cec5SDimitry Andric       return false;
7510b57cec5SDimitry Andric   }
7520b57cec5SDimitry Andric   return true;
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric std::string ListInit::getAsString() const {
7560b57cec5SDimitry Andric   std::string Result = "[";
7570b57cec5SDimitry Andric   const char *sep = "";
7580b57cec5SDimitry Andric   for (Init *Element : *this) {
7590b57cec5SDimitry Andric     Result += sep;
7600b57cec5SDimitry Andric     sep = ", ";
7610b57cec5SDimitry Andric     Result += Element->getAsString();
7620b57cec5SDimitry Andric   }
7630b57cec5SDimitry Andric   return Result + "]";
7640b57cec5SDimitry Andric }
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric Init *OpInit::getBit(unsigned Bit) const {
76781ad6265SDimitry Andric   if (getType() == BitRecTy::get(getRecordKeeper()))
7680b57cec5SDimitry Andric     return const_cast<OpInit*>(this);
7690b57cec5SDimitry Andric   return VarBitInit::get(const_cast<OpInit*>(this), Bit);
7700b57cec5SDimitry Andric }
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric static void
7730b57cec5SDimitry Andric ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) {
7740b57cec5SDimitry Andric   ID.AddInteger(Opcode);
7750b57cec5SDimitry Andric   ID.AddPointer(Op);
7760b57cec5SDimitry Andric   ID.AddPointer(Type);
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) {
7800b57cec5SDimitry Andric   FoldingSetNodeID ID;
7810b57cec5SDimitry Andric   ProfileUnOpInit(ID, Opc, LHS, Type);
7820b57cec5SDimitry Andric 
78381ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl();
7840b57cec5SDimitry Andric   void *IP = nullptr;
78581ad6265SDimitry Andric   if (UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
7860b57cec5SDimitry Andric     return I;
7870b57cec5SDimitry Andric 
78881ad6265SDimitry Andric   UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type);
78981ad6265SDimitry Andric   RK.TheUnOpInitPool.InsertNode(I, IP);
7900b57cec5SDimitry Andric   return I;
7910b57cec5SDimitry Andric }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric void UnOpInit::Profile(FoldingSetNodeID &ID) const {
7940b57cec5SDimitry Andric   ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
7950b57cec5SDimitry Andric }
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
79881ad6265SDimitry Andric   RecordKeeper &RK = getRecordKeeper();
7990b57cec5SDimitry Andric   switch (getOpcode()) {
8005f757f3fSDimitry Andric   case REPR:
8015f757f3fSDimitry Andric     if (LHS->isConcrete()) {
8025f757f3fSDimitry Andric       // If it is a Record, print the full content.
8035f757f3fSDimitry Andric       if (const auto *Def = dyn_cast<DefInit>(LHS)) {
8045f757f3fSDimitry Andric         std::string S;
8055f757f3fSDimitry Andric         raw_string_ostream OS(S);
8065f757f3fSDimitry Andric         OS << *Def->getDef();
8075f757f3fSDimitry Andric         OS.flush();
8085f757f3fSDimitry Andric         return StringInit::get(RK, S);
8095f757f3fSDimitry Andric       } else {
8105f757f3fSDimitry Andric         // Otherwise, print the value of the variable.
8115f757f3fSDimitry Andric         //
8125f757f3fSDimitry Andric         // NOTE: we could recursively !repr the elements of a list,
8135f757f3fSDimitry Andric         // but that could produce a lot of output when printing a
8145f757f3fSDimitry Andric         // defset.
8155f757f3fSDimitry Andric         return StringInit::get(RK, LHS->getAsString());
8165f757f3fSDimitry Andric       }
8175f757f3fSDimitry Andric     }
8185f757f3fSDimitry Andric     break;
81906c3fb27SDimitry Andric   case TOLOWER:
82006c3fb27SDimitry Andric     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
82106c3fb27SDimitry Andric       return StringInit::get(RK, LHSs->getValue().lower());
82206c3fb27SDimitry Andric     break;
82306c3fb27SDimitry Andric   case TOUPPER:
82406c3fb27SDimitry Andric     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
82506c3fb27SDimitry Andric       return StringInit::get(RK, LHSs->getValue().upper());
82606c3fb27SDimitry Andric     break;
8270b57cec5SDimitry Andric   case CAST:
8280b57cec5SDimitry Andric     if (isa<StringRecTy>(getType())) {
8290b57cec5SDimitry Andric       if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
8300b57cec5SDimitry Andric         return LHSs;
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric       if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
83381ad6265SDimitry Andric         return StringInit::get(RK, LHSd->getAsString());
8340b57cec5SDimitry Andric 
83581ad6265SDimitry Andric       if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
83681ad6265SDimitry Andric               LHS->convertInitializerTo(IntRecTy::get(RK))))
83781ad6265SDimitry Andric         return StringInit::get(RK, LHSi->getAsString());
838e8d8bef9SDimitry Andric 
8390b57cec5SDimitry Andric     } else if (isa<RecordRecTy>(getType())) {
8400b57cec5SDimitry Andric       if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
84106c3fb27SDimitry Andric         Record *D = RK.getDef(Name->getValue());
84206c3fb27SDimitry Andric         if (!D && CurRec) {
8430b57cec5SDimitry Andric           // Self-references are allowed, but their resolution is delayed until
8440b57cec5SDimitry Andric           // the final resolve to ensure that we get the correct type for them.
845fe6060f1SDimitry Andric           auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
846fe6060f1SDimitry Andric           if (Name == CurRec->getNameInit() ||
847fe6060f1SDimitry Andric               (Anonymous && Name == Anonymous->getNameInit())) {
8480b57cec5SDimitry Andric             if (!IsFinal)
8490b57cec5SDimitry Andric               break;
8500b57cec5SDimitry Andric             D = CurRec;
8510b57cec5SDimitry Andric           }
8520b57cec5SDimitry Andric         }
8530b57cec5SDimitry Andric 
85406c3fb27SDimitry Andric         auto PrintFatalErrorHelper = [CurRec](const Twine &T) {
85506c3fb27SDimitry Andric           if (CurRec)
85606c3fb27SDimitry Andric             PrintFatalError(CurRec->getLoc(), T);
85706c3fb27SDimitry Andric           else
85806c3fb27SDimitry Andric             PrintFatalError(T);
85906c3fb27SDimitry Andric         };
86006c3fb27SDimitry Andric 
86106c3fb27SDimitry Andric         if (!D) {
86206c3fb27SDimitry Andric           if (IsFinal) {
86306c3fb27SDimitry Andric             PrintFatalErrorHelper(Twine("Undefined reference to record: '") +
86406c3fb27SDimitry Andric                                   Name->getValue() + "'\n");
86506c3fb27SDimitry Andric           }
86606c3fb27SDimitry Andric           break;
86706c3fb27SDimitry Andric         }
86806c3fb27SDimitry Andric 
8690b57cec5SDimitry Andric         DefInit *DI = DefInit::get(D);
8700b57cec5SDimitry Andric         if (!DI->getType()->typeIsA(getType())) {
87106c3fb27SDimitry Andric           PrintFatalErrorHelper(Twine("Expected type '") +
8720b57cec5SDimitry Andric                                 getType()->getAsString() + "', got '" +
8730b57cec5SDimitry Andric                                 DI->getType()->getAsString() + "' in: " +
8740b57cec5SDimitry Andric                                 getAsString() + "\n");
8750b57cec5SDimitry Andric         }
8760b57cec5SDimitry Andric         return DI;
8770b57cec5SDimitry Andric       }
8780b57cec5SDimitry Andric     }
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric     if (Init *NewInit = LHS->convertInitializerTo(getType()))
8810b57cec5SDimitry Andric       return NewInit;
8820b57cec5SDimitry Andric     break;
8830b57cec5SDimitry Andric 
884e8d8bef9SDimitry Andric   case NOT:
88581ad6265SDimitry Andric     if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
88681ad6265SDimitry Andric             LHS->convertInitializerTo(IntRecTy::get(RK))))
88781ad6265SDimitry Andric       return IntInit::get(RK, LHSi->getValue() ? 0 : 1);
888e8d8bef9SDimitry Andric     break;
889e8d8bef9SDimitry Andric 
8900b57cec5SDimitry Andric   case HEAD:
8910b57cec5SDimitry Andric     if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
8920b57cec5SDimitry Andric       assert(!LHSl->empty() && "Empty list in head");
8930b57cec5SDimitry Andric       return LHSl->getElement(0);
8940b57cec5SDimitry Andric     }
8950b57cec5SDimitry Andric     break;
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   case TAIL:
8980b57cec5SDimitry Andric     if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
8990b57cec5SDimitry Andric       assert(!LHSl->empty() && "Empty list in tail");
9000b57cec5SDimitry Andric       // Note the +1.  We can't just pass the result of getValues()
9010b57cec5SDimitry Andric       // directly.
9020b57cec5SDimitry Andric       return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
9030b57cec5SDimitry Andric     }
9040b57cec5SDimitry Andric     break;
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   case SIZE:
9070b57cec5SDimitry Andric     if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
90881ad6265SDimitry Andric       return IntInit::get(RK, LHSl->size());
909e8d8bef9SDimitry Andric     if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
91081ad6265SDimitry Andric       return IntInit::get(RK, LHSd->arg_size());
911e8d8bef9SDimitry Andric     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
91281ad6265SDimitry Andric       return IntInit::get(RK, LHSs->getValue().size());
9130b57cec5SDimitry Andric     break;
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   case EMPTY:
9160b57cec5SDimitry Andric     if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
91781ad6265SDimitry Andric       return IntInit::get(RK, LHSl->empty());
918e8d8bef9SDimitry Andric     if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
91981ad6265SDimitry Andric       return IntInit::get(RK, LHSd->arg_empty());
9200b57cec5SDimitry Andric     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
92181ad6265SDimitry Andric       return IntInit::get(RK, LHSs->getValue().empty());
9220b57cec5SDimitry Andric     break;
923480093f4SDimitry Andric 
924e8d8bef9SDimitry Andric   case GETDAGOP:
925480093f4SDimitry Andric     if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
926297eecfbSDimitry Andric       // TI is not necessarily a def due to the late resolution in multiclasses,
927297eecfbSDimitry Andric       // but has to be a TypedInit.
928297eecfbSDimitry Andric       auto *TI = cast<TypedInit>(Dag->getOperator());
929297eecfbSDimitry Andric       if (!TI->getType()->typeIsA(getType())) {
930480093f4SDimitry Andric         PrintFatalError(CurRec->getLoc(),
931297eecfbSDimitry Andric                         Twine("Expected type '") + getType()->getAsString() +
932297eecfbSDimitry Andric                             "', got '" + TI->getType()->getAsString() +
933297eecfbSDimitry Andric                             "' in: " + getAsString() + "\n");
934480093f4SDimitry Andric       } else {
935297eecfbSDimitry Andric         return Dag->getOperator();
936480093f4SDimitry Andric       }
937480093f4SDimitry Andric     }
938480093f4SDimitry Andric     break;
939bdd1243dSDimitry Andric 
940bdd1243dSDimitry Andric   case LOG2:
941bdd1243dSDimitry Andric     if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
942bdd1243dSDimitry Andric             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
943bdd1243dSDimitry Andric       int64_t LHSv = LHSi->getValue();
944bdd1243dSDimitry Andric       if (LHSv <= 0) {
945bdd1243dSDimitry Andric         PrintFatalError(CurRec->getLoc(),
946bdd1243dSDimitry Andric                         "Illegal operation: logtwo is undefined "
947bdd1243dSDimitry Andric                         "on arguments less than or equal to 0");
948bdd1243dSDimitry Andric       } else {
949bdd1243dSDimitry Andric         uint64_t Log = Log2_64(LHSv);
950bdd1243dSDimitry Andric         assert(Log <= INT64_MAX &&
951bdd1243dSDimitry Andric                "Log of an int64_t must be smaller than INT64_MAX");
952bdd1243dSDimitry Andric         return IntInit::get(RK, static_cast<int64_t>(Log));
953bdd1243dSDimitry Andric       }
954bdd1243dSDimitry Andric     }
955bdd1243dSDimitry Andric     break;
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric   return const_cast<UnOpInit *>(this);
9580b57cec5SDimitry Andric }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric Init *UnOpInit::resolveReferences(Resolver &R) const {
9610b57cec5SDimitry Andric   Init *lhs = LHS->resolveReferences(R);
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric   if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
9640b57cec5SDimitry Andric     return (UnOpInit::get(getOpcode(), lhs, getType()))
9650b57cec5SDimitry Andric         ->Fold(R.getCurrentRecord(), R.isFinal());
9660b57cec5SDimitry Andric   return const_cast<UnOpInit *>(this);
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric std::string UnOpInit::getAsString() const {
9700b57cec5SDimitry Andric   std::string Result;
9710b57cec5SDimitry Andric   switch (getOpcode()) {
9720b57cec5SDimitry Andric   case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
973e8d8bef9SDimitry Andric   case NOT: Result = "!not"; break;
9740b57cec5SDimitry Andric   case HEAD: Result = "!head"; break;
9750b57cec5SDimitry Andric   case TAIL: Result = "!tail"; break;
9760b57cec5SDimitry Andric   case SIZE: Result = "!size"; break;
9770b57cec5SDimitry Andric   case EMPTY: Result = "!empty"; break;
978e8d8bef9SDimitry Andric   case GETDAGOP: Result = "!getdagop"; break;
979bdd1243dSDimitry Andric   case LOG2 : Result = "!logtwo"; break;
9805f757f3fSDimitry Andric   case REPR:
9815f757f3fSDimitry Andric     Result = "!repr";
9825f757f3fSDimitry Andric     break;
98306c3fb27SDimitry Andric   case TOLOWER:
98406c3fb27SDimitry Andric     Result = "!tolower";
98506c3fb27SDimitry Andric     break;
98606c3fb27SDimitry Andric   case TOUPPER:
98706c3fb27SDimitry Andric     Result = "!toupper";
98806c3fb27SDimitry Andric     break;
9890b57cec5SDimitry Andric   }
9900b57cec5SDimitry Andric   return Result + "(" + LHS->getAsString() + ")";
9910b57cec5SDimitry Andric }
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric static void
9940b57cec5SDimitry Andric ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS,
9950b57cec5SDimitry Andric                  RecTy *Type) {
9960b57cec5SDimitry Andric   ID.AddInteger(Opcode);
9970b57cec5SDimitry Andric   ID.AddPointer(LHS);
9980b57cec5SDimitry Andric   ID.AddPointer(RHS);
9990b57cec5SDimitry Andric   ID.AddPointer(Type);
10000b57cec5SDimitry Andric }
10010b57cec5SDimitry Andric 
1002349cc55cSDimitry Andric BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS, RecTy *Type) {
10030b57cec5SDimitry Andric   FoldingSetNodeID ID;
10040b57cec5SDimitry Andric   ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
10050b57cec5SDimitry Andric 
100681ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
10070b57cec5SDimitry Andric   void *IP = nullptr;
100881ad6265SDimitry Andric   if (BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
10090b57cec5SDimitry Andric     return I;
10100b57cec5SDimitry Andric 
101181ad6265SDimitry Andric   BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);
101281ad6265SDimitry Andric   RK.TheBinOpInitPool.InsertNode(I, IP);
10130b57cec5SDimitry Andric   return I;
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric void BinOpInit::Profile(FoldingSetNodeID &ID) const {
10170b57cec5SDimitry Andric   ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric static StringInit *ConcatStringInits(const StringInit *I0,
10210b57cec5SDimitry Andric                                      const StringInit *I1) {
10220b57cec5SDimitry Andric   SmallString<80> Concat(I0->getValue());
10230b57cec5SDimitry Andric   Concat.append(I1->getValue());
102481ad6265SDimitry Andric   return StringInit::get(
102581ad6265SDimitry Andric       I0->getRecordKeeper(), Concat,
102681ad6265SDimitry Andric       StringInit::determineFormat(I0->getFormat(), I1->getFormat()));
1027e8d8bef9SDimitry Andric }
1028e8d8bef9SDimitry Andric 
1029e8d8bef9SDimitry Andric static StringInit *interleaveStringList(const ListInit *List,
1030e8d8bef9SDimitry Andric                                         const StringInit *Delim) {
1031e8d8bef9SDimitry Andric   if (List->size() == 0)
103281ad6265SDimitry Andric     return StringInit::get(List->getRecordKeeper(), "");
1033e8d8bef9SDimitry Andric   StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
1034e8d8bef9SDimitry Andric   if (!Element)
1035e8d8bef9SDimitry Andric     return nullptr;
1036e8d8bef9SDimitry Andric   SmallString<80> Result(Element->getValue());
1037e8d8bef9SDimitry Andric   StringInit::StringFormat Fmt = StringInit::SF_String;
1038e8d8bef9SDimitry Andric 
1039e8d8bef9SDimitry Andric   for (unsigned I = 1, E = List->size(); I < E; ++I) {
1040e8d8bef9SDimitry Andric     Result.append(Delim->getValue());
1041e8d8bef9SDimitry Andric     StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
1042e8d8bef9SDimitry Andric     if (!Element)
1043e8d8bef9SDimitry Andric       return nullptr;
1044e8d8bef9SDimitry Andric     Result.append(Element->getValue());
1045e8d8bef9SDimitry Andric     Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
1046e8d8bef9SDimitry Andric   }
104781ad6265SDimitry Andric   return StringInit::get(List->getRecordKeeper(), Result, Fmt);
1048e8d8bef9SDimitry Andric }
1049e8d8bef9SDimitry Andric 
1050e8d8bef9SDimitry Andric static StringInit *interleaveIntList(const ListInit *List,
1051e8d8bef9SDimitry Andric                                      const StringInit *Delim) {
105281ad6265SDimitry Andric   RecordKeeper &RK = List->getRecordKeeper();
1053e8d8bef9SDimitry Andric   if (List->size() == 0)
105481ad6265SDimitry Andric     return StringInit::get(RK, "");
105581ad6265SDimitry Andric   IntInit *Element = dyn_cast_or_null<IntInit>(
105681ad6265SDimitry Andric       List->getElement(0)->convertInitializerTo(IntRecTy::get(RK)));
1057e8d8bef9SDimitry Andric   if (!Element)
1058e8d8bef9SDimitry Andric     return nullptr;
1059e8d8bef9SDimitry Andric   SmallString<80> Result(Element->getAsString());
1060e8d8bef9SDimitry Andric 
1061e8d8bef9SDimitry Andric   for (unsigned I = 1, E = List->size(); I < E; ++I) {
1062e8d8bef9SDimitry Andric     Result.append(Delim->getValue());
106381ad6265SDimitry Andric     IntInit *Element = dyn_cast_or_null<IntInit>(
106481ad6265SDimitry Andric         List->getElement(I)->convertInitializerTo(IntRecTy::get(RK)));
1065e8d8bef9SDimitry Andric     if (!Element)
1066e8d8bef9SDimitry Andric       return nullptr;
1067e8d8bef9SDimitry Andric     Result.append(Element->getAsString());
1068e8d8bef9SDimitry Andric   }
106981ad6265SDimitry Andric   return StringInit::get(RK, Result);
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
10730b57cec5SDimitry Andric   // Shortcut for the common case of concatenating two strings.
10740b57cec5SDimitry Andric   if (const StringInit *I0s = dyn_cast<StringInit>(I0))
10750b57cec5SDimitry Andric     if (const StringInit *I1s = dyn_cast<StringInit>(I1))
10760b57cec5SDimitry Andric       return ConcatStringInits(I0s, I1s);
107781ad6265SDimitry Andric   return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1,
107881ad6265SDimitry Andric                         StringRecTy::get(I0->getRecordKeeper()));
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric static ListInit *ConcatListInits(const ListInit *LHS,
10820b57cec5SDimitry Andric                                  const ListInit *RHS) {
10830b57cec5SDimitry Andric   SmallVector<Init *, 8> Args;
1084e8d8bef9SDimitry Andric   llvm::append_range(Args, *LHS);
1085e8d8bef9SDimitry Andric   llvm::append_range(Args, *RHS);
10860b57cec5SDimitry Andric   return ListInit::get(Args, LHS->getElementType());
10870b57cec5SDimitry Andric }
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) {
10900b57cec5SDimitry Andric   assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list");
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric   // Shortcut for the common case of concatenating two lists.
10930b57cec5SDimitry Andric   if (const ListInit *LHSList = dyn_cast<ListInit>(LHS))
10940b57cec5SDimitry Andric     if (const ListInit *RHSList = dyn_cast<ListInit>(RHS))
10950b57cec5SDimitry Andric       return ConcatListInits(LHSList, RHSList);
10960b57cec5SDimitry Andric   return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric 
109906c3fb27SDimitry Andric std::optional<bool> BinOpInit::CompareInit(unsigned Opc, Init *LHS,
110006c3fb27SDimitry Andric                                            Init *RHS) const {
1101bdd1243dSDimitry Andric   // First see if we have two bit, bits, or int.
1102bdd1243dSDimitry Andric   IntInit *LHSi = dyn_cast_or_null<IntInit>(
1103bdd1243dSDimitry Andric       LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1104bdd1243dSDimitry Andric   IntInit *RHSi = dyn_cast_or_null<IntInit>(
1105bdd1243dSDimitry Andric       RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1106bdd1243dSDimitry Andric 
1107bdd1243dSDimitry Andric   if (LHSi && RHSi) {
1108bdd1243dSDimitry Andric     bool Result;
1109bdd1243dSDimitry Andric     switch (Opc) {
1110bdd1243dSDimitry Andric     case EQ:
1111bdd1243dSDimitry Andric       Result = LHSi->getValue() == RHSi->getValue();
1112bdd1243dSDimitry Andric       break;
1113bdd1243dSDimitry Andric     case NE:
1114bdd1243dSDimitry Andric       Result = LHSi->getValue() != RHSi->getValue();
1115bdd1243dSDimitry Andric       break;
1116bdd1243dSDimitry Andric     case LE:
1117bdd1243dSDimitry Andric       Result = LHSi->getValue() <= RHSi->getValue();
1118bdd1243dSDimitry Andric       break;
1119bdd1243dSDimitry Andric     case LT:
1120bdd1243dSDimitry Andric       Result = LHSi->getValue() < RHSi->getValue();
1121bdd1243dSDimitry Andric       break;
1122bdd1243dSDimitry Andric     case GE:
1123bdd1243dSDimitry Andric       Result = LHSi->getValue() >= RHSi->getValue();
1124bdd1243dSDimitry Andric       break;
1125bdd1243dSDimitry Andric     case GT:
1126bdd1243dSDimitry Andric       Result = LHSi->getValue() > RHSi->getValue();
1127bdd1243dSDimitry Andric       break;
1128bdd1243dSDimitry Andric     default:
1129bdd1243dSDimitry Andric       llvm_unreachable("unhandled comparison");
1130bdd1243dSDimitry Andric     }
1131bdd1243dSDimitry Andric     return Result;
1132bdd1243dSDimitry Andric   }
1133bdd1243dSDimitry Andric 
1134bdd1243dSDimitry Andric   // Next try strings.
1135bdd1243dSDimitry Andric   StringInit *LHSs = dyn_cast<StringInit>(LHS);
1136bdd1243dSDimitry Andric   StringInit *RHSs = dyn_cast<StringInit>(RHS);
1137bdd1243dSDimitry Andric 
1138bdd1243dSDimitry Andric   if (LHSs && RHSs) {
1139bdd1243dSDimitry Andric     bool Result;
1140bdd1243dSDimitry Andric     switch (Opc) {
1141bdd1243dSDimitry Andric     case EQ:
1142bdd1243dSDimitry Andric       Result = LHSs->getValue() == RHSs->getValue();
1143bdd1243dSDimitry Andric       break;
1144bdd1243dSDimitry Andric     case NE:
1145bdd1243dSDimitry Andric       Result = LHSs->getValue() != RHSs->getValue();
1146bdd1243dSDimitry Andric       break;
1147bdd1243dSDimitry Andric     case LE:
1148bdd1243dSDimitry Andric       Result = LHSs->getValue() <= RHSs->getValue();
1149bdd1243dSDimitry Andric       break;
1150bdd1243dSDimitry Andric     case LT:
1151bdd1243dSDimitry Andric       Result = LHSs->getValue() < RHSs->getValue();
1152bdd1243dSDimitry Andric       break;
1153bdd1243dSDimitry Andric     case GE:
1154bdd1243dSDimitry Andric       Result = LHSs->getValue() >= RHSs->getValue();
1155bdd1243dSDimitry Andric       break;
1156bdd1243dSDimitry Andric     case GT:
1157bdd1243dSDimitry Andric       Result = LHSs->getValue() > RHSs->getValue();
1158bdd1243dSDimitry Andric       break;
1159bdd1243dSDimitry Andric     default:
1160bdd1243dSDimitry Andric       llvm_unreachable("unhandled comparison");
1161bdd1243dSDimitry Andric     }
1162bdd1243dSDimitry Andric     return Result;
1163bdd1243dSDimitry Andric   }
1164bdd1243dSDimitry Andric 
1165bdd1243dSDimitry Andric   // Finally, !eq and !ne can be used with records.
1166bdd1243dSDimitry Andric   if (Opc == EQ || Opc == NE) {
1167bdd1243dSDimitry Andric     DefInit *LHSd = dyn_cast<DefInit>(LHS);
1168bdd1243dSDimitry Andric     DefInit *RHSd = dyn_cast<DefInit>(RHS);
1169bdd1243dSDimitry Andric     if (LHSd && RHSd)
1170bdd1243dSDimitry Andric       return (Opc == EQ) ? LHSd == RHSd : LHSd != RHSd;
1171bdd1243dSDimitry Andric   }
1172bdd1243dSDimitry Andric 
1173bdd1243dSDimitry Andric   return std::nullopt;
1174bdd1243dSDimitry Andric }
1175bdd1243dSDimitry Andric 
117606c3fb27SDimitry Andric static std::optional<unsigned> getDagArgNoByKey(DagInit *Dag, Init *Key,
117706c3fb27SDimitry Andric                                                 std::string &Error) {
117806c3fb27SDimitry Andric   // Accessor by index
117906c3fb27SDimitry Andric   if (IntInit *Idx = dyn_cast<IntInit>(Key)) {
118006c3fb27SDimitry Andric     int64_t Pos = Idx->getValue();
118106c3fb27SDimitry Andric     if (Pos < 0) {
118206c3fb27SDimitry Andric       // The index is negative.
118306c3fb27SDimitry Andric       Error =
118406c3fb27SDimitry Andric           (Twine("index ") + std::to_string(Pos) + Twine(" is negative")).str();
118506c3fb27SDimitry Andric       return std::nullopt;
118606c3fb27SDimitry Andric     }
118706c3fb27SDimitry Andric     if (Pos >= Dag->getNumArgs()) {
118806c3fb27SDimitry Andric       // The index is out-of-range.
118906c3fb27SDimitry Andric       Error = (Twine("index ") + std::to_string(Pos) +
119006c3fb27SDimitry Andric                " is out of range (dag has " +
119106c3fb27SDimitry Andric                std::to_string(Dag->getNumArgs()) + " arguments)")
119206c3fb27SDimitry Andric                   .str();
119306c3fb27SDimitry Andric       return std::nullopt;
119406c3fb27SDimitry Andric     }
119506c3fb27SDimitry Andric     return Pos;
119606c3fb27SDimitry Andric   }
119706c3fb27SDimitry Andric   assert(isa<StringInit>(Key));
119806c3fb27SDimitry Andric   // Accessor by name
119906c3fb27SDimitry Andric   StringInit *Name = dyn_cast<StringInit>(Key);
120006c3fb27SDimitry Andric   auto ArgNo = Dag->getArgNo(Name->getValue());
120106c3fb27SDimitry Andric   if (!ArgNo) {
120206c3fb27SDimitry Andric     // The key is not found.
120306c3fb27SDimitry Andric     Error = (Twine("key '") + Name->getValue() + Twine("' is not found")).str();
120406c3fb27SDimitry Andric     return std::nullopt;
120506c3fb27SDimitry Andric   }
120606c3fb27SDimitry Andric   return *ArgNo;
120706c3fb27SDimitry Andric }
120806c3fb27SDimitry Andric 
12090b57cec5SDimitry Andric Init *BinOpInit::Fold(Record *CurRec) const {
12100b57cec5SDimitry Andric   switch (getOpcode()) {
12110b57cec5SDimitry Andric   case CONCAT: {
12120b57cec5SDimitry Andric     DagInit *LHSs = dyn_cast<DagInit>(LHS);
12130b57cec5SDimitry Andric     DagInit *RHSs = dyn_cast<DagInit>(RHS);
12140b57cec5SDimitry Andric     if (LHSs && RHSs) {
12150b57cec5SDimitry Andric       DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
12160b57cec5SDimitry Andric       DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
1217480093f4SDimitry Andric       if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
1218480093f4SDimitry Andric           (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
12190b57cec5SDimitry Andric         break;
1220480093f4SDimitry Andric       if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
12210b57cec5SDimitry Andric         PrintFatalError(Twine("Concatenated Dag operators do not match: '") +
12220b57cec5SDimitry Andric                         LHSs->getAsString() + "' vs. '" + RHSs->getAsString() +
12230b57cec5SDimitry Andric                         "'");
12240b57cec5SDimitry Andric       }
1225480093f4SDimitry Andric       Init *Op = LOp ? LOp : ROp;
1226480093f4SDimitry Andric       if (!Op)
122781ad6265SDimitry Andric         Op = UnsetInit::get(getRecordKeeper());
1228480093f4SDimitry Andric 
12290b57cec5SDimitry Andric       SmallVector<Init*, 8> Args;
12300b57cec5SDimitry Andric       SmallVector<StringInit*, 8> ArgNames;
12310b57cec5SDimitry Andric       for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
12320b57cec5SDimitry Andric         Args.push_back(LHSs->getArg(i));
12330b57cec5SDimitry Andric         ArgNames.push_back(LHSs->getArgName(i));
12340b57cec5SDimitry Andric       }
12350b57cec5SDimitry Andric       for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
12360b57cec5SDimitry Andric         Args.push_back(RHSs->getArg(i));
12370b57cec5SDimitry Andric         ArgNames.push_back(RHSs->getArgName(i));
12380b57cec5SDimitry Andric       }
1239480093f4SDimitry Andric       return DagInit::get(Op, nullptr, Args, ArgNames);
12400b57cec5SDimitry Andric     }
12410b57cec5SDimitry Andric     break;
12420b57cec5SDimitry Andric   }
12430b57cec5SDimitry Andric   case LISTCONCAT: {
12440b57cec5SDimitry Andric     ListInit *LHSs = dyn_cast<ListInit>(LHS);
12450b57cec5SDimitry Andric     ListInit *RHSs = dyn_cast<ListInit>(RHS);
12460b57cec5SDimitry Andric     if (LHSs && RHSs) {
12470b57cec5SDimitry Andric       SmallVector<Init *, 8> Args;
1248e8d8bef9SDimitry Andric       llvm::append_range(Args, *LHSs);
1249e8d8bef9SDimitry Andric       llvm::append_range(Args, *RHSs);
12500b57cec5SDimitry Andric       return ListInit::get(Args, LHSs->getElementType());
12510b57cec5SDimitry Andric     }
12520b57cec5SDimitry Andric     break;
12530b57cec5SDimitry Andric   }
12540b57cec5SDimitry Andric   case LISTSPLAT: {
12550b57cec5SDimitry Andric     TypedInit *Value = dyn_cast<TypedInit>(LHS);
12560b57cec5SDimitry Andric     IntInit *Size = dyn_cast<IntInit>(RHS);
12570b57cec5SDimitry Andric     if (Value && Size) {
12580b57cec5SDimitry Andric       SmallVector<Init *, 8> Args(Size->getValue(), Value);
12590b57cec5SDimitry Andric       return ListInit::get(Args, Value->getType());
12600b57cec5SDimitry Andric     }
12610b57cec5SDimitry Andric     break;
12620b57cec5SDimitry Andric   }
1263bdd1243dSDimitry Andric   case LISTREMOVE: {
1264bdd1243dSDimitry Andric     ListInit *LHSs = dyn_cast<ListInit>(LHS);
1265bdd1243dSDimitry Andric     ListInit *RHSs = dyn_cast<ListInit>(RHS);
1266bdd1243dSDimitry Andric     if (LHSs && RHSs) {
1267bdd1243dSDimitry Andric       SmallVector<Init *, 8> Args;
1268bdd1243dSDimitry Andric       for (Init *EltLHS : *LHSs) {
1269bdd1243dSDimitry Andric         bool Found = false;
1270bdd1243dSDimitry Andric         for (Init *EltRHS : *RHSs) {
1271bdd1243dSDimitry Andric           if (std::optional<bool> Result = CompareInit(EQ, EltLHS, EltRHS)) {
1272bdd1243dSDimitry Andric             if (*Result) {
1273bdd1243dSDimitry Andric               Found = true;
1274bdd1243dSDimitry Andric               break;
1275bdd1243dSDimitry Andric             }
1276bdd1243dSDimitry Andric           }
1277bdd1243dSDimitry Andric         }
1278bdd1243dSDimitry Andric         if (!Found)
1279bdd1243dSDimitry Andric           Args.push_back(EltLHS);
1280bdd1243dSDimitry Andric       }
1281bdd1243dSDimitry Andric       return ListInit::get(Args, LHSs->getElementType());
1282bdd1243dSDimitry Andric     }
1283bdd1243dSDimitry Andric     break;
1284bdd1243dSDimitry Andric   }
128506c3fb27SDimitry Andric   case LISTELEM: {
128606c3fb27SDimitry Andric     auto *TheList = dyn_cast<ListInit>(LHS);
128706c3fb27SDimitry Andric     auto *Idx = dyn_cast<IntInit>(RHS);
128806c3fb27SDimitry Andric     if (!TheList || !Idx)
128906c3fb27SDimitry Andric       break;
129006c3fb27SDimitry Andric     auto i = Idx->getValue();
129106c3fb27SDimitry Andric     if (i < 0 || i >= (ssize_t)TheList->size())
129206c3fb27SDimitry Andric       break;
129306c3fb27SDimitry Andric     return TheList->getElement(i);
129406c3fb27SDimitry Andric   }
129506c3fb27SDimitry Andric   case LISTSLICE: {
129606c3fb27SDimitry Andric     auto *TheList = dyn_cast<ListInit>(LHS);
129706c3fb27SDimitry Andric     auto *SliceIdxs = dyn_cast<ListInit>(RHS);
129806c3fb27SDimitry Andric     if (!TheList || !SliceIdxs)
129906c3fb27SDimitry Andric       break;
130006c3fb27SDimitry Andric     SmallVector<Init *, 8> Args;
130106c3fb27SDimitry Andric     Args.reserve(SliceIdxs->size());
130206c3fb27SDimitry Andric     for (auto *I : *SliceIdxs) {
130306c3fb27SDimitry Andric       auto *II = dyn_cast<IntInit>(I);
130406c3fb27SDimitry Andric       if (!II)
130506c3fb27SDimitry Andric         goto unresolved;
130606c3fb27SDimitry Andric       auto i = II->getValue();
130706c3fb27SDimitry Andric       if (i < 0 || i >= (ssize_t)TheList->size())
130806c3fb27SDimitry Andric         goto unresolved;
130906c3fb27SDimitry Andric       Args.push_back(TheList->getElement(i));
131006c3fb27SDimitry Andric     }
131106c3fb27SDimitry Andric     return ListInit::get(Args, TheList->getElementType());
131206c3fb27SDimitry Andric   }
131306c3fb27SDimitry Andric   case RANGEC: {
131406c3fb27SDimitry Andric     auto *LHSi = dyn_cast<IntInit>(LHS);
131506c3fb27SDimitry Andric     auto *RHSi = dyn_cast<IntInit>(RHS);
131606c3fb27SDimitry Andric     if (!LHSi || !RHSi)
131706c3fb27SDimitry Andric       break;
131806c3fb27SDimitry Andric 
131906c3fb27SDimitry Andric     auto Start = LHSi->getValue();
132006c3fb27SDimitry Andric     auto End = RHSi->getValue();
132106c3fb27SDimitry Andric     SmallVector<Init *, 8> Args;
132206c3fb27SDimitry Andric     if (getOpcode() == RANGEC) {
132306c3fb27SDimitry Andric       // Closed interval
132406c3fb27SDimitry Andric       if (Start <= End) {
132506c3fb27SDimitry Andric         // Ascending order
132606c3fb27SDimitry Andric         Args.reserve(End - Start + 1);
132706c3fb27SDimitry Andric         for (auto i = Start; i <= End; ++i)
132806c3fb27SDimitry Andric           Args.push_back(IntInit::get(getRecordKeeper(), i));
132906c3fb27SDimitry Andric       } else {
133006c3fb27SDimitry Andric         // Descending order
133106c3fb27SDimitry Andric         Args.reserve(Start - End + 1);
133206c3fb27SDimitry Andric         for (auto i = Start; i >= End; --i)
133306c3fb27SDimitry Andric           Args.push_back(IntInit::get(getRecordKeeper(), i));
133406c3fb27SDimitry Andric       }
133506c3fb27SDimitry Andric     } else if (Start < End) {
133606c3fb27SDimitry Andric       // Half-open interval (excludes `End`)
133706c3fb27SDimitry Andric       Args.reserve(End - Start);
133806c3fb27SDimitry Andric       for (auto i = Start; i < End; ++i)
133906c3fb27SDimitry Andric         Args.push_back(IntInit::get(getRecordKeeper(), i));
134006c3fb27SDimitry Andric     } else {
134106c3fb27SDimitry Andric       // Empty set
134206c3fb27SDimitry Andric     }
134306c3fb27SDimitry Andric     return ListInit::get(Args, LHSi->getType());
134406c3fb27SDimitry Andric   }
13450b57cec5SDimitry Andric   case STRCONCAT: {
13460b57cec5SDimitry Andric     StringInit *LHSs = dyn_cast<StringInit>(LHS);
13470b57cec5SDimitry Andric     StringInit *RHSs = dyn_cast<StringInit>(RHS);
13480b57cec5SDimitry Andric     if (LHSs && RHSs)
13490b57cec5SDimitry Andric       return ConcatStringInits(LHSs, RHSs);
13500b57cec5SDimitry Andric     break;
13510b57cec5SDimitry Andric   }
1352e8d8bef9SDimitry Andric   case INTERLEAVE: {
1353e8d8bef9SDimitry Andric     ListInit *List = dyn_cast<ListInit>(LHS);
1354e8d8bef9SDimitry Andric     StringInit *Delim = dyn_cast<StringInit>(RHS);
1355e8d8bef9SDimitry Andric     if (List && Delim) {
1356e8d8bef9SDimitry Andric       StringInit *Result;
1357e8d8bef9SDimitry Andric       if (isa<StringRecTy>(List->getElementType()))
1358e8d8bef9SDimitry Andric         Result = interleaveStringList(List, Delim);
1359e8d8bef9SDimitry Andric       else
1360e8d8bef9SDimitry Andric         Result = interleaveIntList(List, Delim);
1361e8d8bef9SDimitry Andric       if (Result)
1362e8d8bef9SDimitry Andric         return Result;
1363e8d8bef9SDimitry Andric     }
1364e8d8bef9SDimitry Andric     break;
1365e8d8bef9SDimitry Andric   }
13660b57cec5SDimitry Andric   case EQ:
13670b57cec5SDimitry Andric   case NE:
13680b57cec5SDimitry Andric   case LE:
13690b57cec5SDimitry Andric   case LT:
13700b57cec5SDimitry Andric   case GE:
13710b57cec5SDimitry Andric   case GT: {
1372bdd1243dSDimitry Andric     if (std::optional<bool> Result = CompareInit(getOpcode(), LHS, RHS))
1373bdd1243dSDimitry Andric       return BitInit::get(getRecordKeeper(), *Result);
13740b57cec5SDimitry Andric     break;
13750b57cec5SDimitry Andric   }
137606c3fb27SDimitry Andric   case GETDAGARG: {
137706c3fb27SDimitry Andric     DagInit *Dag = dyn_cast<DagInit>(LHS);
137806c3fb27SDimitry Andric     if (Dag && isa<IntInit, StringInit>(RHS)) {
137906c3fb27SDimitry Andric       std::string Error;
138006c3fb27SDimitry Andric       auto ArgNo = getDagArgNoByKey(Dag, RHS, Error);
138106c3fb27SDimitry Andric       if (!ArgNo)
138206c3fb27SDimitry Andric         PrintFatalError(CurRec->getLoc(), "!getdagarg " + Error);
138306c3fb27SDimitry Andric 
138406c3fb27SDimitry Andric       assert(*ArgNo < Dag->getNumArgs());
138506c3fb27SDimitry Andric 
138606c3fb27SDimitry Andric       Init *Arg = Dag->getArg(*ArgNo);
138706c3fb27SDimitry Andric       if (auto *TI = dyn_cast<TypedInit>(Arg))
138806c3fb27SDimitry Andric         if (!TI->getType()->typeIsConvertibleTo(getType()))
138906c3fb27SDimitry Andric           return UnsetInit::get(Dag->getRecordKeeper());
139006c3fb27SDimitry Andric       return Arg;
139106c3fb27SDimitry Andric     }
139206c3fb27SDimitry Andric     break;
139306c3fb27SDimitry Andric   }
139406c3fb27SDimitry Andric   case GETDAGNAME: {
139506c3fb27SDimitry Andric     DagInit *Dag = dyn_cast<DagInit>(LHS);
139606c3fb27SDimitry Andric     IntInit *Idx = dyn_cast<IntInit>(RHS);
139706c3fb27SDimitry Andric     if (Dag && Idx) {
139806c3fb27SDimitry Andric       int64_t Pos = Idx->getValue();
139906c3fb27SDimitry Andric       if (Pos < 0 || Pos >= Dag->getNumArgs()) {
140006c3fb27SDimitry Andric         // The index is out-of-range.
140106c3fb27SDimitry Andric         PrintError(CurRec->getLoc(),
140206c3fb27SDimitry Andric                    Twine("!getdagname index is out of range 0...") +
140306c3fb27SDimitry Andric                        std::to_string(Dag->getNumArgs() - 1) + ": " +
140406c3fb27SDimitry Andric                        std::to_string(Pos));
140506c3fb27SDimitry Andric       }
140606c3fb27SDimitry Andric       Init *ArgName = Dag->getArgName(Pos);
140706c3fb27SDimitry Andric       if (!ArgName)
140806c3fb27SDimitry Andric         return UnsetInit::get(getRecordKeeper());
140906c3fb27SDimitry Andric       return ArgName;
141006c3fb27SDimitry Andric     }
141106c3fb27SDimitry Andric     break;
141206c3fb27SDimitry Andric   }
1413e8d8bef9SDimitry Andric   case SETDAGOP: {
1414480093f4SDimitry Andric     DagInit *Dag = dyn_cast<DagInit>(LHS);
1415480093f4SDimitry Andric     DefInit *Op = dyn_cast<DefInit>(RHS);
1416480093f4SDimitry Andric     if (Dag && Op) {
1417480093f4SDimitry Andric       SmallVector<Init*, 8> Args;
1418480093f4SDimitry Andric       SmallVector<StringInit*, 8> ArgNames;
1419480093f4SDimitry Andric       for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
1420480093f4SDimitry Andric         Args.push_back(Dag->getArg(i));
1421480093f4SDimitry Andric         ArgNames.push_back(Dag->getArgName(i));
1422480093f4SDimitry Andric       }
1423480093f4SDimitry Andric       return DagInit::get(Op, nullptr, Args, ArgNames);
1424480093f4SDimitry Andric     }
1425480093f4SDimitry Andric     break;
1426480093f4SDimitry Andric   }
14270b57cec5SDimitry Andric   case ADD:
1428e8d8bef9SDimitry Andric   case SUB:
14290b57cec5SDimitry Andric   case MUL:
1430bdd1243dSDimitry Andric   case DIV:
14310b57cec5SDimitry Andric   case AND:
14320b57cec5SDimitry Andric   case OR:
1433e8d8bef9SDimitry Andric   case XOR:
14340b57cec5SDimitry Andric   case SHL:
14350b57cec5SDimitry Andric   case SRA:
14360b57cec5SDimitry Andric   case SRL: {
143781ad6265SDimitry Andric     IntInit *LHSi = dyn_cast_or_null<IntInit>(
143881ad6265SDimitry Andric         LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
143981ad6265SDimitry Andric     IntInit *RHSi = dyn_cast_or_null<IntInit>(
144081ad6265SDimitry Andric         RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
14410b57cec5SDimitry Andric     if (LHSi && RHSi) {
14420b57cec5SDimitry Andric       int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
14430b57cec5SDimitry Andric       int64_t Result;
14440b57cec5SDimitry Andric       switch (getOpcode()) {
14450b57cec5SDimitry Andric       default: llvm_unreachable("Bad opcode!");
14460b57cec5SDimitry Andric       case ADD: Result = LHSv + RHSv; break;
1447e8d8bef9SDimitry Andric       case SUB: Result = LHSv - RHSv; break;
14480b57cec5SDimitry Andric       case MUL: Result = LHSv * RHSv; break;
1449bdd1243dSDimitry Andric       case DIV:
1450bdd1243dSDimitry Andric         if (RHSv == 0)
1451bdd1243dSDimitry Andric           PrintFatalError(CurRec->getLoc(),
1452bdd1243dSDimitry Andric                           "Illegal operation: division by zero");
1453bdd1243dSDimitry Andric         else if (LHSv == INT64_MIN && RHSv == -1)
1454bdd1243dSDimitry Andric           PrintFatalError(CurRec->getLoc(),
1455bdd1243dSDimitry Andric                           "Illegal operation: INT64_MIN / -1");
1456bdd1243dSDimitry Andric         else
1457bdd1243dSDimitry Andric           Result = LHSv / RHSv;
1458bdd1243dSDimitry Andric         break;
14590b57cec5SDimitry Andric       case AND: Result = LHSv & RHSv; break;
14600b57cec5SDimitry Andric       case OR:  Result = LHSv | RHSv; break;
1461e8d8bef9SDimitry Andric       case XOR: Result = LHSv ^ RHSv; break;
14625ffd83dbSDimitry Andric       case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
14630b57cec5SDimitry Andric       case SRA: Result = LHSv >> RHSv; break;
14640b57cec5SDimitry Andric       case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
14650b57cec5SDimitry Andric       }
146681ad6265SDimitry Andric       return IntInit::get(getRecordKeeper(), Result);
14670b57cec5SDimitry Andric     }
14680b57cec5SDimitry Andric     break;
14690b57cec5SDimitry Andric   }
14700b57cec5SDimitry Andric   }
147106c3fb27SDimitry Andric unresolved:
14720b57cec5SDimitry Andric   return const_cast<BinOpInit *>(this);
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric Init *BinOpInit::resolveReferences(Resolver &R) const {
14760b57cec5SDimitry Andric   Init *lhs = LHS->resolveReferences(R);
14770b57cec5SDimitry Andric   Init *rhs = RHS->resolveReferences(R);
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   if (LHS != lhs || RHS != rhs)
14800b57cec5SDimitry Andric     return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))
14810b57cec5SDimitry Andric         ->Fold(R.getCurrentRecord());
14820b57cec5SDimitry Andric   return const_cast<BinOpInit *>(this);
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric std::string BinOpInit::getAsString() const {
14860b57cec5SDimitry Andric   std::string Result;
14870b57cec5SDimitry Andric   switch (getOpcode()) {
148806c3fb27SDimitry Andric   case LISTELEM:
148906c3fb27SDimitry Andric   case LISTSLICE:
149006c3fb27SDimitry Andric     return LHS->getAsString() + "[" + RHS->getAsString() + "]";
149106c3fb27SDimitry Andric   case RANGEC:
149206c3fb27SDimitry Andric     return LHS->getAsString() + "..." + RHS->getAsString();
14930b57cec5SDimitry Andric   case CONCAT: Result = "!con"; break;
14940b57cec5SDimitry Andric   case ADD: Result = "!add"; break;
1495e8d8bef9SDimitry Andric   case SUB: Result = "!sub"; break;
14960b57cec5SDimitry Andric   case MUL: Result = "!mul"; break;
1497bdd1243dSDimitry Andric   case DIV: Result = "!div"; break;
14980b57cec5SDimitry Andric   case AND: Result = "!and"; break;
14990b57cec5SDimitry Andric   case OR: Result = "!or"; break;
1500e8d8bef9SDimitry Andric   case XOR: Result = "!xor"; break;
15010b57cec5SDimitry Andric   case SHL: Result = "!shl"; break;
15020b57cec5SDimitry Andric   case SRA: Result = "!sra"; break;
15030b57cec5SDimitry Andric   case SRL: Result = "!srl"; break;
15040b57cec5SDimitry Andric   case EQ: Result = "!eq"; break;
15050b57cec5SDimitry Andric   case NE: Result = "!ne"; break;
15060b57cec5SDimitry Andric   case LE: Result = "!le"; break;
15070b57cec5SDimitry Andric   case LT: Result = "!lt"; break;
15080b57cec5SDimitry Andric   case GE: Result = "!ge"; break;
15090b57cec5SDimitry Andric   case GT: Result = "!gt"; break;
15100b57cec5SDimitry Andric   case LISTCONCAT: Result = "!listconcat"; break;
15110b57cec5SDimitry Andric   case LISTSPLAT: Result = "!listsplat"; break;
15125f757f3fSDimitry Andric   case LISTREMOVE:
15135f757f3fSDimitry Andric     Result = "!listremove";
15145f757f3fSDimitry Andric     break;
15150b57cec5SDimitry Andric   case STRCONCAT: Result = "!strconcat"; break;
1516e8d8bef9SDimitry Andric   case INTERLEAVE: Result = "!interleave"; break;
1517e8d8bef9SDimitry Andric   case SETDAGOP: Result = "!setdagop"; break;
151806c3fb27SDimitry Andric   case GETDAGARG:
151906c3fb27SDimitry Andric     Result = "!getdagarg<" + getType()->getAsString() + ">";
152006c3fb27SDimitry Andric     break;
152106c3fb27SDimitry Andric   case GETDAGNAME:
152206c3fb27SDimitry Andric     Result = "!getdagname";
152306c3fb27SDimitry Andric     break;
15240b57cec5SDimitry Andric   }
15250b57cec5SDimitry Andric   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
15260b57cec5SDimitry Andric }
15270b57cec5SDimitry Andric 
15280b57cec5SDimitry Andric static void
15290b57cec5SDimitry Andric ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS,
15300b57cec5SDimitry Andric                   Init *RHS, RecTy *Type) {
15310b57cec5SDimitry Andric   ID.AddInteger(Opcode);
15320b57cec5SDimitry Andric   ID.AddPointer(LHS);
15330b57cec5SDimitry Andric   ID.AddPointer(MHS);
15340b57cec5SDimitry Andric   ID.AddPointer(RHS);
15350b57cec5SDimitry Andric   ID.AddPointer(Type);
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
15390b57cec5SDimitry Andric                             RecTy *Type) {
15400b57cec5SDimitry Andric   FoldingSetNodeID ID;
15410b57cec5SDimitry Andric   ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
15420b57cec5SDimitry Andric 
154381ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
15440b57cec5SDimitry Andric   void *IP = nullptr;
154581ad6265SDimitry Andric   if (TernOpInit *I = RK.TheTernOpInitPool.FindNodeOrInsertPos(ID, IP))
15460b57cec5SDimitry Andric     return I;
15470b57cec5SDimitry Andric 
154881ad6265SDimitry Andric   TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
154981ad6265SDimitry Andric   RK.TheTernOpInitPool.InsertNode(I, IP);
15500b57cec5SDimitry Andric   return I;
15510b57cec5SDimitry Andric }
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric void TernOpInit::Profile(FoldingSetNodeID &ID) const {
15540b57cec5SDimitry Andric   ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType());
15550b57cec5SDimitry Andric }
15560b57cec5SDimitry Andric 
1557e8d8bef9SDimitry Andric static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
15580b57cec5SDimitry Andric   MapResolver R(CurRec);
15590b57cec5SDimitry Andric   R.set(LHS, MHSe);
15600b57cec5SDimitry Andric   return RHS->resolveReferences(R);
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric 
15630b57cec5SDimitry Andric static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
15640b57cec5SDimitry Andric                              Record *CurRec) {
15650b57cec5SDimitry Andric   bool Change = false;
1566e8d8bef9SDimitry Andric   Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
15670b57cec5SDimitry Andric   if (Val != MHSd->getOperator())
15680b57cec5SDimitry Andric     Change = true;
15690b57cec5SDimitry Andric 
15700b57cec5SDimitry Andric   SmallVector<std::pair<Init *, StringInit *>, 8> NewArgs;
15710b57cec5SDimitry Andric   for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
15720b57cec5SDimitry Andric     Init *Arg = MHSd->getArg(i);
15730b57cec5SDimitry Andric     Init *NewArg;
15740b57cec5SDimitry Andric     StringInit *ArgName = MHSd->getArgName(i);
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric     if (DagInit *Argd = dyn_cast<DagInit>(Arg))
15770b57cec5SDimitry Andric       NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec);
15780b57cec5SDimitry Andric     else
1579e8d8bef9SDimitry Andric       NewArg = ItemApply(LHS, Arg, RHS, CurRec);
15800b57cec5SDimitry Andric 
15810b57cec5SDimitry Andric     NewArgs.push_back(std::make_pair(NewArg, ArgName));
15820b57cec5SDimitry Andric     if (Arg != NewArg)
15830b57cec5SDimitry Andric       Change = true;
15840b57cec5SDimitry Andric   }
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric   if (Change)
15870b57cec5SDimitry Andric     return DagInit::get(Val, nullptr, NewArgs);
15880b57cec5SDimitry Andric   return MHSd;
15890b57cec5SDimitry Andric }
15900b57cec5SDimitry Andric 
15910b57cec5SDimitry Andric // Applies RHS to all elements of MHS, using LHS as a temp variable.
15920b57cec5SDimitry Andric static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
15930b57cec5SDimitry Andric                            Record *CurRec) {
15940b57cec5SDimitry Andric   if (DagInit *MHSd = dyn_cast<DagInit>(MHS))
15950b57cec5SDimitry Andric     return ForeachDagApply(LHS, MHSd, RHS, CurRec);
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
15980b57cec5SDimitry Andric     SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end());
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric     for (Init *&Item : NewList) {
1601e8d8bef9SDimitry Andric       Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
16020b57cec5SDimitry Andric       if (NewItem != Item)
16030b57cec5SDimitry Andric         Item = NewItem;
16040b57cec5SDimitry Andric     }
16050b57cec5SDimitry Andric     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
16060b57cec5SDimitry Andric   }
16070b57cec5SDimitry Andric 
16080b57cec5SDimitry Andric   return nullptr;
16090b57cec5SDimitry Andric }
16100b57cec5SDimitry Andric 
1611e8d8bef9SDimitry Andric // Evaluates RHS for all elements of MHS, using LHS as a temp variable.
1612e8d8bef9SDimitry Andric // Creates a new list with the elements that evaluated to true.
1613e8d8bef9SDimitry Andric static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
1614e8d8bef9SDimitry Andric                           Record *CurRec) {
1615e8d8bef9SDimitry Andric   if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1616e8d8bef9SDimitry Andric     SmallVector<Init *, 8> NewList;
1617e8d8bef9SDimitry Andric 
1618e8d8bef9SDimitry Andric     for (Init *Item : MHSl->getValues()) {
1619e8d8bef9SDimitry Andric       Init *Include = ItemApply(LHS, Item, RHS, CurRec);
1620e8d8bef9SDimitry Andric       if (!Include)
1621e8d8bef9SDimitry Andric         return nullptr;
162281ad6265SDimitry Andric       if (IntInit *IncludeInt =
162381ad6265SDimitry Andric               dyn_cast_or_null<IntInit>(Include->convertInitializerTo(
162481ad6265SDimitry Andric                   IntRecTy::get(LHS->getRecordKeeper())))) {
1625e8d8bef9SDimitry Andric         if (IncludeInt->getValue())
1626e8d8bef9SDimitry Andric           NewList.push_back(Item);
1627e8d8bef9SDimitry Andric       } else {
1628e8d8bef9SDimitry Andric         return nullptr;
1629e8d8bef9SDimitry Andric       }
1630e8d8bef9SDimitry Andric     }
1631e8d8bef9SDimitry Andric     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
1632e8d8bef9SDimitry Andric   }
1633e8d8bef9SDimitry Andric 
1634e8d8bef9SDimitry Andric   return nullptr;
1635e8d8bef9SDimitry Andric }
1636e8d8bef9SDimitry Andric 
16370b57cec5SDimitry Andric Init *TernOpInit::Fold(Record *CurRec) const {
163881ad6265SDimitry Andric   RecordKeeper &RK = getRecordKeeper();
16390b57cec5SDimitry Andric   switch (getOpcode()) {
16400b57cec5SDimitry Andric   case SUBST: {
16410b57cec5SDimitry Andric     DefInit *LHSd = dyn_cast<DefInit>(LHS);
16420b57cec5SDimitry Andric     VarInit *LHSv = dyn_cast<VarInit>(LHS);
16430b57cec5SDimitry Andric     StringInit *LHSs = dyn_cast<StringInit>(LHS);
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric     DefInit *MHSd = dyn_cast<DefInit>(MHS);
16460b57cec5SDimitry Andric     VarInit *MHSv = dyn_cast<VarInit>(MHS);
16470b57cec5SDimitry Andric     StringInit *MHSs = dyn_cast<StringInit>(MHS);
16480b57cec5SDimitry Andric 
16490b57cec5SDimitry Andric     DefInit *RHSd = dyn_cast<DefInit>(RHS);
16500b57cec5SDimitry Andric     VarInit *RHSv = dyn_cast<VarInit>(RHS);
16510b57cec5SDimitry Andric     StringInit *RHSs = dyn_cast<StringInit>(RHS);
16520b57cec5SDimitry Andric 
16530b57cec5SDimitry Andric     if (LHSd && MHSd && RHSd) {
16540b57cec5SDimitry Andric       Record *Val = RHSd->getDef();
16550b57cec5SDimitry Andric       if (LHSd->getAsString() == RHSd->getAsString())
16560b57cec5SDimitry Andric         Val = MHSd->getDef();
16570b57cec5SDimitry Andric       return DefInit::get(Val);
16580b57cec5SDimitry Andric     }
16590b57cec5SDimitry Andric     if (LHSv && MHSv && RHSv) {
16605ffd83dbSDimitry Andric       std::string Val = std::string(RHSv->getName());
16610b57cec5SDimitry Andric       if (LHSv->getAsString() == RHSv->getAsString())
16625ffd83dbSDimitry Andric         Val = std::string(MHSv->getName());
16630b57cec5SDimitry Andric       return VarInit::get(Val, getType());
16640b57cec5SDimitry Andric     }
16650b57cec5SDimitry Andric     if (LHSs && MHSs && RHSs) {
16665ffd83dbSDimitry Andric       std::string Val = std::string(RHSs->getValue());
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric       std::string::size_type found;
16690b57cec5SDimitry Andric       std::string::size_type idx = 0;
16700b57cec5SDimitry Andric       while (true) {
16715ffd83dbSDimitry Andric         found = Val.find(std::string(LHSs->getValue()), idx);
16720b57cec5SDimitry Andric         if (found == std::string::npos)
16730b57cec5SDimitry Andric           break;
16745ffd83dbSDimitry Andric         Val.replace(found, LHSs->getValue().size(),
16755ffd83dbSDimitry Andric                     std::string(MHSs->getValue()));
16760b57cec5SDimitry Andric         idx = found + MHSs->getValue().size();
16770b57cec5SDimitry Andric       }
16780b57cec5SDimitry Andric 
167981ad6265SDimitry Andric       return StringInit::get(RK, Val);
16800b57cec5SDimitry Andric     }
16810b57cec5SDimitry Andric     break;
16820b57cec5SDimitry Andric   }
16830b57cec5SDimitry Andric 
16840b57cec5SDimitry Andric   case FOREACH: {
16850b57cec5SDimitry Andric     if (Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec))
16860b57cec5SDimitry Andric       return Result;
16870b57cec5SDimitry Andric     break;
16880b57cec5SDimitry Andric   }
16890b57cec5SDimitry Andric 
1690e8d8bef9SDimitry Andric   case FILTER: {
1691e8d8bef9SDimitry Andric     if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
1692e8d8bef9SDimitry Andric       return Result;
1693e8d8bef9SDimitry Andric     break;
1694e8d8bef9SDimitry Andric   }
1695e8d8bef9SDimitry Andric 
16960b57cec5SDimitry Andric   case IF: {
16970b57cec5SDimitry Andric     if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
169881ad6265SDimitry Andric             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
16990b57cec5SDimitry Andric       if (LHSi->getValue())
17000b57cec5SDimitry Andric         return MHS;
17010b57cec5SDimitry Andric       return RHS;
17020b57cec5SDimitry Andric     }
17030b57cec5SDimitry Andric     break;
17040b57cec5SDimitry Andric   }
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric   case DAG: {
17070b57cec5SDimitry Andric     ListInit *MHSl = dyn_cast<ListInit>(MHS);
17080b57cec5SDimitry Andric     ListInit *RHSl = dyn_cast<ListInit>(RHS);
17090b57cec5SDimitry Andric     bool MHSok = MHSl || isa<UnsetInit>(MHS);
17100b57cec5SDimitry Andric     bool RHSok = RHSl || isa<UnsetInit>(RHS);
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric     if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
17130b57cec5SDimitry Andric       break; // Typically prevented by the parser, but might happen with template args
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric     if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
17160b57cec5SDimitry Andric       SmallVector<std::pair<Init *, StringInit *>, 8> Children;
17170b57cec5SDimitry Andric       unsigned Size = MHSl ? MHSl->size() : RHSl->size();
17180b57cec5SDimitry Andric       for (unsigned i = 0; i != Size; ++i) {
171981ad6265SDimitry Andric         Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK);
172081ad6265SDimitry Andric         Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK);
17210b57cec5SDimitry Andric         if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
17220b57cec5SDimitry Andric           return const_cast<TernOpInit *>(this);
17230b57cec5SDimitry Andric         Children.emplace_back(Node, dyn_cast<StringInit>(Name));
17240b57cec5SDimitry Andric       }
17250b57cec5SDimitry Andric       return DagInit::get(LHS, nullptr, Children);
17260b57cec5SDimitry Andric     }
17270b57cec5SDimitry Andric     break;
17280b57cec5SDimitry Andric   }
1729e8d8bef9SDimitry Andric 
17305f757f3fSDimitry Andric   case RANGE: {
17315f757f3fSDimitry Andric     auto *LHSi = dyn_cast<IntInit>(LHS);
17325f757f3fSDimitry Andric     auto *MHSi = dyn_cast<IntInit>(MHS);
17335f757f3fSDimitry Andric     auto *RHSi = dyn_cast<IntInit>(RHS);
17345f757f3fSDimitry Andric     if (!LHSi || !MHSi || !RHSi)
17355f757f3fSDimitry Andric       break;
17365f757f3fSDimitry Andric 
17375f757f3fSDimitry Andric     auto Start = LHSi->getValue();
17385f757f3fSDimitry Andric     auto End = MHSi->getValue();
17395f757f3fSDimitry Andric     auto Step = RHSi->getValue();
17405f757f3fSDimitry Andric     if (Step == 0)
17415f757f3fSDimitry Andric       PrintError(CurRec->getLoc(), "Step of !range can't be 0");
17425f757f3fSDimitry Andric 
17435f757f3fSDimitry Andric     SmallVector<Init *, 8> Args;
17445f757f3fSDimitry Andric     if (Start < End && Step > 0) {
17455f757f3fSDimitry Andric       Args.reserve((End - Start) / Step);
17465f757f3fSDimitry Andric       for (auto I = Start; I < End; I += Step)
17475f757f3fSDimitry Andric         Args.push_back(IntInit::get(getRecordKeeper(), I));
17485f757f3fSDimitry Andric     } else if (Start > End && Step < 0) {
17495f757f3fSDimitry Andric       Args.reserve((Start - End) / -Step);
17505f757f3fSDimitry Andric       for (auto I = Start; I > End; I += Step)
17515f757f3fSDimitry Andric         Args.push_back(IntInit::get(getRecordKeeper(), I));
17525f757f3fSDimitry Andric     } else {
17535f757f3fSDimitry Andric       // Empty set
17545f757f3fSDimitry Andric     }
17555f757f3fSDimitry Andric     return ListInit::get(Args, LHSi->getType());
17565f757f3fSDimitry Andric   }
17575f757f3fSDimitry Andric 
1758e8d8bef9SDimitry Andric   case SUBSTR: {
1759e8d8bef9SDimitry Andric     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1760e8d8bef9SDimitry Andric     IntInit *MHSi = dyn_cast<IntInit>(MHS);
1761e8d8bef9SDimitry Andric     IntInit *RHSi = dyn_cast<IntInit>(RHS);
1762e8d8bef9SDimitry Andric     if (LHSs && MHSi && RHSi) {
1763e8d8bef9SDimitry Andric       int64_t StringSize = LHSs->getValue().size();
1764e8d8bef9SDimitry Andric       int64_t Start = MHSi->getValue();
1765e8d8bef9SDimitry Andric       int64_t Length = RHSi->getValue();
1766e8d8bef9SDimitry Andric       if (Start < 0 || Start > StringSize)
1767e8d8bef9SDimitry Andric         PrintError(CurRec->getLoc(),
1768e8d8bef9SDimitry Andric                    Twine("!substr start position is out of range 0...") +
1769e8d8bef9SDimitry Andric                        std::to_string(StringSize) + ": " +
1770e8d8bef9SDimitry Andric                        std::to_string(Start));
1771e8d8bef9SDimitry Andric       if (Length < 0)
1772e8d8bef9SDimitry Andric         PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
177381ad6265SDimitry Andric       return StringInit::get(RK, LHSs->getValue().substr(Start, Length),
1774e8d8bef9SDimitry Andric                              LHSs->getFormat());
1775e8d8bef9SDimitry Andric     }
1776e8d8bef9SDimitry Andric     break;
1777e8d8bef9SDimitry Andric   }
1778fe6060f1SDimitry Andric 
1779fe6060f1SDimitry Andric   case FIND: {
1780fe6060f1SDimitry Andric     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1781fe6060f1SDimitry Andric     StringInit *MHSs = dyn_cast<StringInit>(MHS);
1782fe6060f1SDimitry Andric     IntInit *RHSi = dyn_cast<IntInit>(RHS);
1783fe6060f1SDimitry Andric     if (LHSs && MHSs && RHSi) {
1784fe6060f1SDimitry Andric       int64_t SourceSize = LHSs->getValue().size();
1785fe6060f1SDimitry Andric       int64_t Start = RHSi->getValue();
1786fe6060f1SDimitry Andric       if (Start < 0 || Start > SourceSize)
1787fe6060f1SDimitry Andric         PrintError(CurRec->getLoc(),
1788fe6060f1SDimitry Andric                    Twine("!find start position is out of range 0...") +
1789fe6060f1SDimitry Andric                        std::to_string(SourceSize) + ": " +
1790fe6060f1SDimitry Andric                        std::to_string(Start));
1791fe6060f1SDimitry Andric       auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1792fe6060f1SDimitry Andric       if (I == std::string::npos)
179381ad6265SDimitry Andric         return IntInit::get(RK, -1);
179481ad6265SDimitry Andric       return IntInit::get(RK, I);
1795fe6060f1SDimitry Andric     }
1796fe6060f1SDimitry Andric     break;
1797fe6060f1SDimitry Andric   }
179806c3fb27SDimitry Andric 
179906c3fb27SDimitry Andric   case SETDAGARG: {
180006c3fb27SDimitry Andric     DagInit *Dag = dyn_cast<DagInit>(LHS);
180106c3fb27SDimitry Andric     if (Dag && isa<IntInit, StringInit>(MHS)) {
180206c3fb27SDimitry Andric       std::string Error;
180306c3fb27SDimitry Andric       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
180406c3fb27SDimitry Andric       if (!ArgNo)
180506c3fb27SDimitry Andric         PrintFatalError(CurRec->getLoc(), "!setdagarg " + Error);
180606c3fb27SDimitry Andric 
180706c3fb27SDimitry Andric       assert(*ArgNo < Dag->getNumArgs());
180806c3fb27SDimitry Andric 
180906c3fb27SDimitry Andric       SmallVector<Init *, 8> Args(Dag->getArgs());
181006c3fb27SDimitry Andric       SmallVector<StringInit *, 8> Names(Dag->getArgNames());
181106c3fb27SDimitry Andric       Args[*ArgNo] = RHS;
181206c3fb27SDimitry Andric       return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
181306c3fb27SDimitry Andric     }
181406c3fb27SDimitry Andric     break;
181506c3fb27SDimitry Andric   }
181606c3fb27SDimitry Andric 
181706c3fb27SDimitry Andric   case SETDAGNAME: {
181806c3fb27SDimitry Andric     DagInit *Dag = dyn_cast<DagInit>(LHS);
181906c3fb27SDimitry Andric     if (Dag && isa<IntInit, StringInit>(MHS)) {
182006c3fb27SDimitry Andric       std::string Error;
182106c3fb27SDimitry Andric       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
182206c3fb27SDimitry Andric       if (!ArgNo)
182306c3fb27SDimitry Andric         PrintFatalError(CurRec->getLoc(), "!setdagname " + Error);
182406c3fb27SDimitry Andric 
182506c3fb27SDimitry Andric       assert(*ArgNo < Dag->getNumArgs());
182606c3fb27SDimitry Andric 
182706c3fb27SDimitry Andric       SmallVector<Init *, 8> Args(Dag->getArgs());
182806c3fb27SDimitry Andric       SmallVector<StringInit *, 8> Names(Dag->getArgNames());
182906c3fb27SDimitry Andric       Names[*ArgNo] = dyn_cast<StringInit>(RHS);
183006c3fb27SDimitry Andric       return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
183106c3fb27SDimitry Andric     }
183206c3fb27SDimitry Andric     break;
183306c3fb27SDimitry Andric   }
18340b57cec5SDimitry Andric   }
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   return const_cast<TernOpInit *>(this);
18370b57cec5SDimitry Andric }
18380b57cec5SDimitry Andric 
18390b57cec5SDimitry Andric Init *TernOpInit::resolveReferences(Resolver &R) const {
18400b57cec5SDimitry Andric   Init *lhs = LHS->resolveReferences(R);
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric   if (getOpcode() == IF && lhs != LHS) {
18430b57cec5SDimitry Andric     if (IntInit *Value = dyn_cast_or_null<IntInit>(
184481ad6265SDimitry Andric             lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
18450b57cec5SDimitry Andric       // Short-circuit
18460b57cec5SDimitry Andric       if (Value->getValue())
18470b57cec5SDimitry Andric         return MHS->resolveReferences(R);
18480b57cec5SDimitry Andric       return RHS->resolveReferences(R);
18490b57cec5SDimitry Andric     }
18500b57cec5SDimitry Andric   }
18510b57cec5SDimitry Andric 
18520b57cec5SDimitry Andric   Init *mhs = MHS->resolveReferences(R);
18530b57cec5SDimitry Andric   Init *rhs;
18540b57cec5SDimitry Andric 
1855e8d8bef9SDimitry Andric   if (getOpcode() == FOREACH || getOpcode() == FILTER) {
18560b57cec5SDimitry Andric     ShadowResolver SR(R);
18570b57cec5SDimitry Andric     SR.addShadow(lhs);
18580b57cec5SDimitry Andric     rhs = RHS->resolveReferences(SR);
18590b57cec5SDimitry Andric   } else {
18600b57cec5SDimitry Andric     rhs = RHS->resolveReferences(R);
18610b57cec5SDimitry Andric   }
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric   if (LHS != lhs || MHS != mhs || RHS != rhs)
18640b57cec5SDimitry Andric     return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType()))
18650b57cec5SDimitry Andric         ->Fold(R.getCurrentRecord());
18660b57cec5SDimitry Andric   return const_cast<TernOpInit *>(this);
18670b57cec5SDimitry Andric }
18680b57cec5SDimitry Andric 
18690b57cec5SDimitry Andric std::string TernOpInit::getAsString() const {
18700b57cec5SDimitry Andric   std::string Result;
18710b57cec5SDimitry Andric   bool UnquotedLHS = false;
18720b57cec5SDimitry Andric   switch (getOpcode()) {
1873e8d8bef9SDimitry Andric   case DAG: Result = "!dag"; break;
1874e8d8bef9SDimitry Andric   case FILTER: Result = "!filter"; UnquotedLHS = true; break;
18750b57cec5SDimitry Andric   case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
18760b57cec5SDimitry Andric   case IF: Result = "!if"; break;
18775f757f3fSDimitry Andric   case RANGE:
18785f757f3fSDimitry Andric     Result = "!range";
18795f757f3fSDimitry Andric     break;
1880e8d8bef9SDimitry Andric   case SUBST: Result = "!subst"; break;
1881e8d8bef9SDimitry Andric   case SUBSTR: Result = "!substr"; break;
1882fe6060f1SDimitry Andric   case FIND: Result = "!find"; break;
188306c3fb27SDimitry Andric   case SETDAGARG:
188406c3fb27SDimitry Andric     Result = "!setdagarg";
188506c3fb27SDimitry Andric     break;
188606c3fb27SDimitry Andric   case SETDAGNAME:
188706c3fb27SDimitry Andric     Result = "!setdagname";
188806c3fb27SDimitry Andric     break;
18890b57cec5SDimitry Andric   }
18900b57cec5SDimitry Andric   return (Result + "(" +
18910b57cec5SDimitry Andric           (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
18920b57cec5SDimitry Andric           ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")");
18930b57cec5SDimitry Andric }
18940b57cec5SDimitry Andric 
1895fe6060f1SDimitry Andric static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List,
1896fe6060f1SDimitry Andric                               Init *A, Init *B, Init *Expr, RecTy *Type) {
18970b57cec5SDimitry Andric   ID.AddPointer(Start);
18980b57cec5SDimitry Andric   ID.AddPointer(List);
18990b57cec5SDimitry Andric   ID.AddPointer(A);
19000b57cec5SDimitry Andric   ID.AddPointer(B);
19010b57cec5SDimitry Andric   ID.AddPointer(Expr);
19020b57cec5SDimitry Andric   ID.AddPointer(Type);
19030b57cec5SDimitry Andric }
19040b57cec5SDimitry Andric 
19050b57cec5SDimitry Andric FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B,
19060b57cec5SDimitry Andric                             Init *Expr, RecTy *Type) {
19070b57cec5SDimitry Andric   FoldingSetNodeID ID;
19080b57cec5SDimitry Andric   ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
19090b57cec5SDimitry Andric 
191081ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl();
19110b57cec5SDimitry Andric   void *IP = nullptr;
191281ad6265SDimitry Andric   if (FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
19130b57cec5SDimitry Andric     return I;
19140b57cec5SDimitry Andric 
191581ad6265SDimitry Andric   FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
191681ad6265SDimitry Andric   RK.TheFoldOpInitPool.InsertNode(I, IP);
19170b57cec5SDimitry Andric   return I;
19180b57cec5SDimitry Andric }
19190b57cec5SDimitry Andric 
19200b57cec5SDimitry Andric void FoldOpInit::Profile(FoldingSetNodeID &ID) const {
19210b57cec5SDimitry Andric   ProfileFoldOpInit(ID, Start, List, A, B, Expr, getType());
19220b57cec5SDimitry Andric }
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric Init *FoldOpInit::Fold(Record *CurRec) const {
19250b57cec5SDimitry Andric   if (ListInit *LI = dyn_cast<ListInit>(List)) {
19260b57cec5SDimitry Andric     Init *Accum = Start;
19270b57cec5SDimitry Andric     for (Init *Elt : *LI) {
19280b57cec5SDimitry Andric       MapResolver R(CurRec);
19290b57cec5SDimitry Andric       R.set(A, Accum);
19300b57cec5SDimitry Andric       R.set(B, Elt);
19310b57cec5SDimitry Andric       Accum = Expr->resolveReferences(R);
19320b57cec5SDimitry Andric     }
19330b57cec5SDimitry Andric     return Accum;
19340b57cec5SDimitry Andric   }
19350b57cec5SDimitry Andric   return const_cast<FoldOpInit *>(this);
19360b57cec5SDimitry Andric }
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric Init *FoldOpInit::resolveReferences(Resolver &R) const {
19390b57cec5SDimitry Andric   Init *NewStart = Start->resolveReferences(R);
19400b57cec5SDimitry Andric   Init *NewList = List->resolveReferences(R);
19410b57cec5SDimitry Andric   ShadowResolver SR(R);
19420b57cec5SDimitry Andric   SR.addShadow(A);
19430b57cec5SDimitry Andric   SR.addShadow(B);
19440b57cec5SDimitry Andric   Init *NewExpr = Expr->resolveReferences(SR);
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric   if (Start == NewStart && List == NewList && Expr == NewExpr)
19470b57cec5SDimitry Andric     return const_cast<FoldOpInit *>(this);
19480b57cec5SDimitry Andric 
19490b57cec5SDimitry Andric   return get(NewStart, NewList, A, B, NewExpr, getType())
19500b57cec5SDimitry Andric       ->Fold(R.getCurrentRecord());
19510b57cec5SDimitry Andric }
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric Init *FoldOpInit::getBit(unsigned Bit) const {
19540b57cec5SDimitry Andric   return VarBitInit::get(const_cast<FoldOpInit *>(this), Bit);
19550b57cec5SDimitry Andric }
19560b57cec5SDimitry Andric 
19570b57cec5SDimitry Andric std::string FoldOpInit::getAsString() const {
19580b57cec5SDimitry Andric   return (Twine("!foldl(") + Start->getAsString() + ", " + List->getAsString() +
19590b57cec5SDimitry Andric           ", " + A->getAsUnquotedString() + ", " + B->getAsUnquotedString() +
19600b57cec5SDimitry Andric           ", " + Expr->getAsString() + ")")
19610b57cec5SDimitry Andric       .str();
19620b57cec5SDimitry Andric }
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
19650b57cec5SDimitry Andric                              Init *Expr) {
19660b57cec5SDimitry Andric   ID.AddPointer(CheckType);
19670b57cec5SDimitry Andric   ID.AddPointer(Expr);
19680b57cec5SDimitry Andric }
19690b57cec5SDimitry Andric 
19700b57cec5SDimitry Andric IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) {
19710b57cec5SDimitry Andric 
19720b57cec5SDimitry Andric   FoldingSetNodeID ID;
19730b57cec5SDimitry Andric   ProfileIsAOpInit(ID, CheckType, Expr);
19740b57cec5SDimitry Andric 
197581ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
19760b57cec5SDimitry Andric   void *IP = nullptr;
197781ad6265SDimitry Andric   if (IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
19780b57cec5SDimitry Andric     return I;
19790b57cec5SDimitry Andric 
198081ad6265SDimitry Andric   IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);
198181ad6265SDimitry Andric   RK.TheIsAOpInitPool.InsertNode(I, IP);
19820b57cec5SDimitry Andric   return I;
19830b57cec5SDimitry Andric }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric void IsAOpInit::Profile(FoldingSetNodeID &ID) const {
19860b57cec5SDimitry Andric   ProfileIsAOpInit(ID, CheckType, Expr);
19870b57cec5SDimitry Andric }
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric Init *IsAOpInit::Fold() const {
19900b57cec5SDimitry Andric   if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
19910b57cec5SDimitry Andric     // Is the expression type known to be (a subclass of) the desired type?
19920b57cec5SDimitry Andric     if (TI->getType()->typeIsConvertibleTo(CheckType))
199381ad6265SDimitry Andric       return IntInit::get(getRecordKeeper(), 1);
19940b57cec5SDimitry Andric 
19950b57cec5SDimitry Andric     if (isa<RecordRecTy>(CheckType)) {
19960b57cec5SDimitry Andric       // If the target type is not a subclass of the expression type, or if
19970b57cec5SDimitry Andric       // the expression has fully resolved to a record, we know that it can't
19980b57cec5SDimitry Andric       // be of the required type.
19990b57cec5SDimitry Andric       if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr))
200081ad6265SDimitry Andric         return IntInit::get(getRecordKeeper(), 0);
20010b57cec5SDimitry Andric     } else {
20020b57cec5SDimitry Andric       // We treat non-record types as not castable.
200381ad6265SDimitry Andric       return IntInit::get(getRecordKeeper(), 0);
20040b57cec5SDimitry Andric     }
20050b57cec5SDimitry Andric   }
20060b57cec5SDimitry Andric   return const_cast<IsAOpInit *>(this);
20070b57cec5SDimitry Andric }
20080b57cec5SDimitry Andric 
20090b57cec5SDimitry Andric Init *IsAOpInit::resolveReferences(Resolver &R) const {
20100b57cec5SDimitry Andric   Init *NewExpr = Expr->resolveReferences(R);
20110b57cec5SDimitry Andric   if (Expr != NewExpr)
20120b57cec5SDimitry Andric     return get(CheckType, NewExpr)->Fold();
20130b57cec5SDimitry Andric   return const_cast<IsAOpInit *>(this);
20140b57cec5SDimitry Andric }
20150b57cec5SDimitry Andric 
20160b57cec5SDimitry Andric Init *IsAOpInit::getBit(unsigned Bit) const {
20170b57cec5SDimitry Andric   return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit);
20180b57cec5SDimitry Andric }
20190b57cec5SDimitry Andric 
20200b57cec5SDimitry Andric std::string IsAOpInit::getAsString() const {
20210b57cec5SDimitry Andric   return (Twine("!isa<") + CheckType->getAsString() + ">(" +
20220b57cec5SDimitry Andric           Expr->getAsString() + ")")
20230b57cec5SDimitry Andric       .str();
20240b57cec5SDimitry Andric }
20250b57cec5SDimitry Andric 
202681ad6265SDimitry Andric static void ProfileExistsOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
202781ad6265SDimitry Andric                                 Init *Expr) {
202881ad6265SDimitry Andric   ID.AddPointer(CheckType);
202981ad6265SDimitry Andric   ID.AddPointer(Expr);
203081ad6265SDimitry Andric }
203181ad6265SDimitry Andric 
203281ad6265SDimitry Andric ExistsOpInit *ExistsOpInit::get(RecTy *CheckType, Init *Expr) {
203381ad6265SDimitry Andric   FoldingSetNodeID ID;
203481ad6265SDimitry Andric   ProfileExistsOpInit(ID, CheckType, Expr);
203581ad6265SDimitry Andric 
203681ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
203781ad6265SDimitry Andric   void *IP = nullptr;
203881ad6265SDimitry Andric   if (ExistsOpInit *I = RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
203981ad6265SDimitry Andric     return I;
204081ad6265SDimitry Andric 
204181ad6265SDimitry Andric   ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);
204281ad6265SDimitry Andric   RK.TheExistsOpInitPool.InsertNode(I, IP);
204381ad6265SDimitry Andric   return I;
204481ad6265SDimitry Andric }
204581ad6265SDimitry Andric 
204681ad6265SDimitry Andric void ExistsOpInit::Profile(FoldingSetNodeID &ID) const {
204781ad6265SDimitry Andric   ProfileExistsOpInit(ID, CheckType, Expr);
204881ad6265SDimitry Andric }
204981ad6265SDimitry Andric 
205081ad6265SDimitry Andric Init *ExistsOpInit::Fold(Record *CurRec, bool IsFinal) const {
205181ad6265SDimitry Andric   if (StringInit *Name = dyn_cast<StringInit>(Expr)) {
205281ad6265SDimitry Andric 
205306c3fb27SDimitry Andric     // Look up all defined records to see if we can find one.
205406c3fb27SDimitry Andric     Record *D = CheckType->getRecordKeeper().getDef(Name->getValue());
205506c3fb27SDimitry Andric     if (D) {
205606c3fb27SDimitry Andric       // Check if types are compatible.
205706c3fb27SDimitry Andric       return IntInit::get(getRecordKeeper(),
205806c3fb27SDimitry Andric                           DefInit::get(D)->getType()->typeIsA(CheckType));
205906c3fb27SDimitry Andric     }
206006c3fb27SDimitry Andric 
206106c3fb27SDimitry Andric     if (CurRec) {
206281ad6265SDimitry Andric       // Self-references are allowed, but their resolution is delayed until
206381ad6265SDimitry Andric       // the final resolve to ensure that we get the correct type for them.
206481ad6265SDimitry Andric       auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
206581ad6265SDimitry Andric       if (Name == CurRec->getNameInit() ||
206681ad6265SDimitry Andric           (Anonymous && Name == Anonymous->getNameInit())) {
206781ad6265SDimitry Andric         if (!IsFinal)
206881ad6265SDimitry Andric           return const_cast<ExistsOpInit *>(this);
206981ad6265SDimitry Andric 
207081ad6265SDimitry Andric         // No doubt that there exists a record, so we should check if types are
207106c3fb27SDimitry Andric         // compatible.
207281ad6265SDimitry Andric         return IntInit::get(getRecordKeeper(),
207381ad6265SDimitry Andric                             CurRec->getType()->typeIsA(CheckType));
207481ad6265SDimitry Andric       }
207506c3fb27SDimitry Andric     }
207681ad6265SDimitry Andric 
207781ad6265SDimitry Andric     if (IsFinal)
207881ad6265SDimitry Andric       return IntInit::get(getRecordKeeper(), 0);
207981ad6265SDimitry Andric     return const_cast<ExistsOpInit *>(this);
208081ad6265SDimitry Andric   }
208181ad6265SDimitry Andric   return const_cast<ExistsOpInit *>(this);
208281ad6265SDimitry Andric }
208381ad6265SDimitry Andric 
208481ad6265SDimitry Andric Init *ExistsOpInit::resolveReferences(Resolver &R) const {
208581ad6265SDimitry Andric   Init *NewExpr = Expr->resolveReferences(R);
208681ad6265SDimitry Andric   if (Expr != NewExpr || R.isFinal())
208781ad6265SDimitry Andric     return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal());
208881ad6265SDimitry Andric   return const_cast<ExistsOpInit *>(this);
208981ad6265SDimitry Andric }
209081ad6265SDimitry Andric 
209181ad6265SDimitry Andric Init *ExistsOpInit::getBit(unsigned Bit) const {
209281ad6265SDimitry Andric   return VarBitInit::get(const_cast<ExistsOpInit *>(this), Bit);
209381ad6265SDimitry Andric }
209481ad6265SDimitry Andric 
209581ad6265SDimitry Andric std::string ExistsOpInit::getAsString() const {
209681ad6265SDimitry Andric   return (Twine("!exists<") + CheckType->getAsString() + ">(" +
209781ad6265SDimitry Andric           Expr->getAsString() + ")")
209881ad6265SDimitry Andric       .str();
209981ad6265SDimitry Andric }
210081ad6265SDimitry Andric 
21010b57cec5SDimitry Andric RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
21020b57cec5SDimitry Andric   if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) {
21030b57cec5SDimitry Andric     for (Record *Rec : RecordType->getClasses()) {
21040b57cec5SDimitry Andric       if (RecordVal *Field = Rec->getValue(FieldName))
21050b57cec5SDimitry Andric         return Field->getType();
21060b57cec5SDimitry Andric     }
21070b57cec5SDimitry Andric   }
21080b57cec5SDimitry Andric   return nullptr;
21090b57cec5SDimitry Andric }
21100b57cec5SDimitry Andric 
21110b57cec5SDimitry Andric Init *
21120b57cec5SDimitry Andric TypedInit::convertInitializerTo(RecTy *Ty) const {
21130b57cec5SDimitry Andric   if (getType() == Ty || getType()->typeIsA(Ty))
21140b57cec5SDimitry Andric     return const_cast<TypedInit *>(this);
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric   if (isa<BitRecTy>(getType()) && isa<BitsRecTy>(Ty) &&
21170b57cec5SDimitry Andric       cast<BitsRecTy>(Ty)->getNumBits() == 1)
211881ad6265SDimitry Andric     return BitsInit::get(getRecordKeeper(), {const_cast<TypedInit *>(this)});
21190b57cec5SDimitry Andric 
21200b57cec5SDimitry Andric   return nullptr;
21210b57cec5SDimitry Andric }
21220b57cec5SDimitry Andric 
21230b57cec5SDimitry Andric Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
21240b57cec5SDimitry Andric   BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
21250b57cec5SDimitry Andric   if (!T) return nullptr;  // Cannot subscript a non-bits variable.
21260b57cec5SDimitry Andric   unsigned NumBits = T->getNumBits();
21270b57cec5SDimitry Andric 
21280b57cec5SDimitry Andric   SmallVector<Init *, 16> NewBits;
21290b57cec5SDimitry Andric   NewBits.reserve(Bits.size());
21300b57cec5SDimitry Andric   for (unsigned Bit : Bits) {
21310b57cec5SDimitry Andric     if (Bit >= NumBits)
21320b57cec5SDimitry Andric       return nullptr;
21330b57cec5SDimitry Andric 
21340b57cec5SDimitry Andric     NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit));
21350b57cec5SDimitry Andric   }
213681ad6265SDimitry Andric   return BitsInit::get(getRecordKeeper(), NewBits);
21370b57cec5SDimitry Andric }
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric Init *TypedInit::getCastTo(RecTy *Ty) const {
21400b57cec5SDimitry Andric   // Handle the common case quickly
21410b57cec5SDimitry Andric   if (getType() == Ty || getType()->typeIsA(Ty))
21420b57cec5SDimitry Andric     return const_cast<TypedInit *>(this);
21430b57cec5SDimitry Andric 
21440b57cec5SDimitry Andric   if (Init *Converted = convertInitializerTo(Ty)) {
21450b57cec5SDimitry Andric     assert(!isa<TypedInit>(Converted) ||
21460b57cec5SDimitry Andric            cast<TypedInit>(Converted)->getType()->typeIsA(Ty));
21470b57cec5SDimitry Andric     return Converted;
21480b57cec5SDimitry Andric   }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric   if (!getType()->typeIsConvertibleTo(Ty))
21510b57cec5SDimitry Andric     return nullptr;
21520b57cec5SDimitry Andric 
21530b57cec5SDimitry Andric   return UnOpInit::get(UnOpInit::CAST, const_cast<TypedInit *>(this), Ty)
21540b57cec5SDimitry Andric       ->Fold(nullptr);
21550b57cec5SDimitry Andric }
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric VarInit *VarInit::get(StringRef VN, RecTy *T) {
215881ad6265SDimitry Andric   Init *Value = StringInit::get(T->getRecordKeeper(), VN);
21590b57cec5SDimitry Andric   return VarInit::get(Value, T);
21600b57cec5SDimitry Andric }
21610b57cec5SDimitry Andric 
21620b57cec5SDimitry Andric VarInit *VarInit::get(Init *VN, RecTy *T) {
216381ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
216481ad6265SDimitry Andric   VarInit *&I = RK.TheVarInitPool[std::make_pair(T, VN)];
21650b57cec5SDimitry Andric   if (!I)
216681ad6265SDimitry Andric     I = new (RK.Allocator) VarInit(VN, T);
21670b57cec5SDimitry Andric   return I;
21680b57cec5SDimitry Andric }
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric StringRef VarInit::getName() const {
21710b57cec5SDimitry Andric   StringInit *NameString = cast<StringInit>(getNameInit());
21720b57cec5SDimitry Andric   return NameString->getValue();
21730b57cec5SDimitry Andric }
21740b57cec5SDimitry Andric 
21750b57cec5SDimitry Andric Init *VarInit::getBit(unsigned Bit) const {
217681ad6265SDimitry Andric   if (getType() == BitRecTy::get(getRecordKeeper()))
21770b57cec5SDimitry Andric     return const_cast<VarInit*>(this);
21780b57cec5SDimitry Andric   return VarBitInit::get(const_cast<VarInit*>(this), Bit);
21790b57cec5SDimitry Andric }
21800b57cec5SDimitry Andric 
21810b57cec5SDimitry Andric Init *VarInit::resolveReferences(Resolver &R) const {
21820b57cec5SDimitry Andric   if (Init *Val = R.resolve(VarName))
21830b57cec5SDimitry Andric     return Val;
21840b57cec5SDimitry Andric   return const_cast<VarInit *>(this);
21850b57cec5SDimitry Andric }
21860b57cec5SDimitry Andric 
21870b57cec5SDimitry Andric VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
218881ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
218981ad6265SDimitry Andric   VarBitInit *&I = RK.TheVarBitInitPool[std::make_pair(T, B)];
21900b57cec5SDimitry Andric   if (!I)
219181ad6265SDimitry Andric     I = new (RK.Allocator) VarBitInit(T, B);
21920b57cec5SDimitry Andric   return I;
21930b57cec5SDimitry Andric }
21940b57cec5SDimitry Andric 
21950b57cec5SDimitry Andric std::string VarBitInit::getAsString() const {
21960b57cec5SDimitry Andric   return TI->getAsString() + "{" + utostr(Bit) + "}";
21970b57cec5SDimitry Andric }
21980b57cec5SDimitry Andric 
21990b57cec5SDimitry Andric Init *VarBitInit::resolveReferences(Resolver &R) const {
22000b57cec5SDimitry Andric   Init *I = TI->resolveReferences(R);
22010b57cec5SDimitry Andric   if (TI != I)
22020b57cec5SDimitry Andric     return I->getBit(getBitNum());
22030b57cec5SDimitry Andric 
22040b57cec5SDimitry Andric   return const_cast<VarBitInit*>(this);
22050b57cec5SDimitry Andric }
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric DefInit::DefInit(Record *D)
22080b57cec5SDimitry Andric     : TypedInit(IK_DefInit, D->getType()), Def(D) {}
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric DefInit *DefInit::get(Record *R) {
22110b57cec5SDimitry Andric   return R->getDefInit();
22120b57cec5SDimitry Andric }
22130b57cec5SDimitry Andric 
22140b57cec5SDimitry Andric Init *DefInit::convertInitializerTo(RecTy *Ty) const {
22150b57cec5SDimitry Andric   if (auto *RRT = dyn_cast<RecordRecTy>(Ty))
22160b57cec5SDimitry Andric     if (getType()->typeIsConvertibleTo(RRT))
22170b57cec5SDimitry Andric       return const_cast<DefInit *>(this);
22180b57cec5SDimitry Andric   return nullptr;
22190b57cec5SDimitry Andric }
22200b57cec5SDimitry Andric 
22210b57cec5SDimitry Andric RecTy *DefInit::getFieldType(StringInit *FieldName) const {
22220b57cec5SDimitry Andric   if (const RecordVal *RV = Def->getValue(FieldName))
22230b57cec5SDimitry Andric     return RV->getType();
22240b57cec5SDimitry Andric   return nullptr;
22250b57cec5SDimitry Andric }
22260b57cec5SDimitry Andric 
22275ffd83dbSDimitry Andric std::string DefInit::getAsString() const { return std::string(Def->getName()); }
22280b57cec5SDimitry Andric 
222906c3fb27SDimitry Andric static void ProfileVarDefInit(FoldingSetNodeID &ID, Record *Class,
223006c3fb27SDimitry Andric                               ArrayRef<ArgumentInit *> Args) {
22310b57cec5SDimitry Andric   ID.AddInteger(Args.size());
22320b57cec5SDimitry Andric   ID.AddPointer(Class);
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric   for (Init *I : Args)
22350b57cec5SDimitry Andric     ID.AddPointer(I);
22360b57cec5SDimitry Andric }
22370b57cec5SDimitry Andric 
223881ad6265SDimitry Andric VarDefInit::VarDefInit(Record *Class, unsigned N)
223981ad6265SDimitry Andric     : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class),
224081ad6265SDimitry Andric       NumArgs(N) {}
224181ad6265SDimitry Andric 
224206c3fb27SDimitry Andric VarDefInit *VarDefInit::get(Record *Class, ArrayRef<ArgumentInit *> Args) {
22430b57cec5SDimitry Andric   FoldingSetNodeID ID;
22440b57cec5SDimitry Andric   ProfileVarDefInit(ID, Class, Args);
22450b57cec5SDimitry Andric 
224681ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Class->getRecords().getImpl();
22470b57cec5SDimitry Andric   void *IP = nullptr;
224881ad6265SDimitry Andric   if (VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
22490b57cec5SDimitry Andric     return I;
22500b57cec5SDimitry Andric 
225106c3fb27SDimitry Andric   void *Mem = RK.Allocator.Allocate(
225206c3fb27SDimitry Andric       totalSizeToAlloc<ArgumentInit *>(Args.size()), alignof(VarDefInit));
22530b57cec5SDimitry Andric   VarDefInit *I = new (Mem) VarDefInit(Class, Args.size());
22540b57cec5SDimitry Andric   std::uninitialized_copy(Args.begin(), Args.end(),
225506c3fb27SDimitry Andric                           I->getTrailingObjects<ArgumentInit *>());
225681ad6265SDimitry Andric   RK.TheVarDefInitPool.InsertNode(I, IP);
22570b57cec5SDimitry Andric   return I;
22580b57cec5SDimitry Andric }
22590b57cec5SDimitry Andric 
22600b57cec5SDimitry Andric void VarDefInit::Profile(FoldingSetNodeID &ID) const {
22610b57cec5SDimitry Andric   ProfileVarDefInit(ID, Class, args());
22620b57cec5SDimitry Andric }
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric DefInit *VarDefInit::instantiate() {
22650b57cec5SDimitry Andric   if (!Def) {
22660b57cec5SDimitry Andric     RecordKeeper &Records = Class->getRecords();
22675f757f3fSDimitry Andric     auto NewRecOwner =
22685f757f3fSDimitry Andric         std::make_unique<Record>(Records.getNewAnonymousName(), Class->getLoc(),
22695f757f3fSDimitry Andric                                  Records, Record::RK_AnonymousDef);
22700b57cec5SDimitry Andric     Record *NewRec = NewRecOwner.get();
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric     // Copy values from class to instance
22730b57cec5SDimitry Andric     for (const RecordVal &Val : Class->getValues())
22740b57cec5SDimitry Andric       NewRec->addValue(Val);
22750b57cec5SDimitry Andric 
2276fe6060f1SDimitry Andric     // Copy assertions from class to instance.
2277fe6060f1SDimitry Andric     NewRec->appendAssertions(Class);
2278fe6060f1SDimitry Andric 
22795f757f3fSDimitry Andric     // Copy dumps from class to instance.
22805f757f3fSDimitry Andric     NewRec->appendDumps(Class);
22815f757f3fSDimitry Andric 
22820b57cec5SDimitry Andric     // Substitute and resolve template arguments
22830b57cec5SDimitry Andric     ArrayRef<Init *> TArgs = Class->getTemplateArgs();
22840b57cec5SDimitry Andric     MapResolver R(NewRec);
22850b57cec5SDimitry Andric 
2286*0fca6ea1SDimitry Andric     for (Init *Arg : TArgs) {
2287*0fca6ea1SDimitry Andric       R.set(Arg, NewRec->getValue(Arg)->getValue());
2288*0fca6ea1SDimitry Andric       NewRec->removeValue(Arg);
228906c3fb27SDimitry Andric     }
22900b57cec5SDimitry Andric 
229106c3fb27SDimitry Andric     for (auto *Arg : args()) {
229206c3fb27SDimitry Andric       if (Arg->isPositional())
229306c3fb27SDimitry Andric         R.set(TArgs[Arg->getIndex()], Arg->getValue());
229406c3fb27SDimitry Andric       if (Arg->isNamed())
229506c3fb27SDimitry Andric         R.set(Arg->getName(), Arg->getValue());
22960b57cec5SDimitry Andric     }
22970b57cec5SDimitry Andric 
22980b57cec5SDimitry Andric     NewRec->resolveReferences(R);
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric     // Add superclasses.
23010b57cec5SDimitry Andric     ArrayRef<std::pair<Record *, SMRange>> SCs = Class->getSuperClasses();
23020b57cec5SDimitry Andric     for (const auto &SCPair : SCs)
23030b57cec5SDimitry Andric       NewRec->addSuperClass(SCPair.first, SCPair.second);
23040b57cec5SDimitry Andric 
23050b57cec5SDimitry Andric     NewRec->addSuperClass(Class,
23060b57cec5SDimitry Andric                           SMRange(Class->getLoc().back(),
23070b57cec5SDimitry Andric                                   Class->getLoc().back()));
23080b57cec5SDimitry Andric 
23090b57cec5SDimitry Andric     // Resolve internal references and store in record keeper
23100b57cec5SDimitry Andric     NewRec->resolveReferences();
23110b57cec5SDimitry Andric     Records.addDef(std::move(NewRecOwner));
23120b57cec5SDimitry Andric 
2313fe6060f1SDimitry Andric     // Check the assertions.
2314fe6060f1SDimitry Andric     NewRec->checkRecordAssertions();
2315fe6060f1SDimitry Andric 
23165f757f3fSDimitry Andric     // Check the assertions.
23175f757f3fSDimitry Andric     NewRec->emitRecordDumps();
23185f757f3fSDimitry Andric 
23190b57cec5SDimitry Andric     Def = DefInit::get(NewRec);
23200b57cec5SDimitry Andric   }
23210b57cec5SDimitry Andric 
23220b57cec5SDimitry Andric   return Def;
23230b57cec5SDimitry Andric }
23240b57cec5SDimitry Andric 
23250b57cec5SDimitry Andric Init *VarDefInit::resolveReferences(Resolver &R) const {
23260b57cec5SDimitry Andric   TrackUnresolvedResolver UR(&R);
23270b57cec5SDimitry Andric   bool Changed = false;
232806c3fb27SDimitry Andric   SmallVector<ArgumentInit *, 8> NewArgs;
23290b57cec5SDimitry Andric   NewArgs.reserve(args_size());
23300b57cec5SDimitry Andric 
233106c3fb27SDimitry Andric   for (ArgumentInit *Arg : args()) {
233206c3fb27SDimitry Andric     auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
23330b57cec5SDimitry Andric     NewArgs.push_back(NewArg);
23340b57cec5SDimitry Andric     Changed |= NewArg != Arg;
23350b57cec5SDimitry Andric   }
23360b57cec5SDimitry Andric 
23370b57cec5SDimitry Andric   if (Changed) {
23380b57cec5SDimitry Andric     auto New = VarDefInit::get(Class, NewArgs);
23390b57cec5SDimitry Andric     if (!UR.foundUnresolved())
23400b57cec5SDimitry Andric       return New->instantiate();
23410b57cec5SDimitry Andric     return New;
23420b57cec5SDimitry Andric   }
23430b57cec5SDimitry Andric   return const_cast<VarDefInit *>(this);
23440b57cec5SDimitry Andric }
23450b57cec5SDimitry Andric 
23460b57cec5SDimitry Andric Init *VarDefInit::Fold() const {
23470b57cec5SDimitry Andric   if (Def)
23480b57cec5SDimitry Andric     return Def;
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   TrackUnresolvedResolver R;
23510b57cec5SDimitry Andric   for (Init *Arg : args())
23520b57cec5SDimitry Andric     Arg->resolveReferences(R);
23530b57cec5SDimitry Andric 
23540b57cec5SDimitry Andric   if (!R.foundUnresolved())
23550b57cec5SDimitry Andric     return const_cast<VarDefInit *>(this)->instantiate();
23560b57cec5SDimitry Andric   return const_cast<VarDefInit *>(this);
23570b57cec5SDimitry Andric }
23580b57cec5SDimitry Andric 
23590b57cec5SDimitry Andric std::string VarDefInit::getAsString() const {
23600b57cec5SDimitry Andric   std::string Result = Class->getNameInitAsString() + "<";
23610b57cec5SDimitry Andric   const char *sep = "";
23620b57cec5SDimitry Andric   for (Init *Arg : args()) {
23630b57cec5SDimitry Andric     Result += sep;
23640b57cec5SDimitry Andric     sep = ", ";
23650b57cec5SDimitry Andric     Result += Arg->getAsString();
23660b57cec5SDimitry Andric   }
23670b57cec5SDimitry Andric   return Result + ">";
23680b57cec5SDimitry Andric }
23690b57cec5SDimitry Andric 
23700b57cec5SDimitry Andric FieldInit *FieldInit::get(Init *R, StringInit *FN) {
237181ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = R->getRecordKeeper().getImpl();
237281ad6265SDimitry Andric   FieldInit *&I = RK.TheFieldInitPool[std::make_pair(R, FN)];
2373349cc55cSDimitry Andric   if (!I)
237481ad6265SDimitry Andric     I = new (RK.Allocator) FieldInit(R, FN);
23750b57cec5SDimitry Andric   return I;
23760b57cec5SDimitry Andric }
23770b57cec5SDimitry Andric 
23780b57cec5SDimitry Andric Init *FieldInit::getBit(unsigned Bit) const {
237981ad6265SDimitry Andric   if (getType() == BitRecTy::get(getRecordKeeper()))
23800b57cec5SDimitry Andric     return const_cast<FieldInit*>(this);
23810b57cec5SDimitry Andric   return VarBitInit::get(const_cast<FieldInit*>(this), Bit);
23820b57cec5SDimitry Andric }
23830b57cec5SDimitry Andric 
23840b57cec5SDimitry Andric Init *FieldInit::resolveReferences(Resolver &R) const {
23850b57cec5SDimitry Andric   Init *NewRec = Rec->resolveReferences(R);
23860b57cec5SDimitry Andric   if (NewRec != Rec)
23870b57cec5SDimitry Andric     return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());
23880b57cec5SDimitry Andric   return const_cast<FieldInit *>(this);
23890b57cec5SDimitry Andric }
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric Init *FieldInit::Fold(Record *CurRec) const {
23920b57cec5SDimitry Andric   if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
23930b57cec5SDimitry Andric     Record *Def = DI->getDef();
23940b57cec5SDimitry Andric     if (Def == CurRec)
23950b57cec5SDimitry Andric       PrintFatalError(CurRec->getLoc(),
23960b57cec5SDimitry Andric                       Twine("Attempting to access field '") +
23970b57cec5SDimitry Andric                       FieldName->getAsUnquotedString() + "' of '" +
23980b57cec5SDimitry Andric                       Rec->getAsString() + "' is a forbidden self-reference");
23990b57cec5SDimitry Andric     Init *FieldVal = Def->getValue(FieldName)->getValue();
2400fe6060f1SDimitry Andric     if (FieldVal->isConcrete())
24010b57cec5SDimitry Andric       return FieldVal;
24020b57cec5SDimitry Andric   }
24030b57cec5SDimitry Andric   return const_cast<FieldInit *>(this);
24040b57cec5SDimitry Andric }
24050b57cec5SDimitry Andric 
24065ffd83dbSDimitry Andric bool FieldInit::isConcrete() const {
24075ffd83dbSDimitry Andric   if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
24085ffd83dbSDimitry Andric     Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
24095ffd83dbSDimitry Andric     return FieldVal->isConcrete();
24105ffd83dbSDimitry Andric   }
24115ffd83dbSDimitry Andric   return false;
24125ffd83dbSDimitry Andric }
24135ffd83dbSDimitry Andric 
24140b57cec5SDimitry Andric static void ProfileCondOpInit(FoldingSetNodeID &ID,
24150b57cec5SDimitry Andric                              ArrayRef<Init *> CondRange,
24160b57cec5SDimitry Andric                              ArrayRef<Init *> ValRange,
24170b57cec5SDimitry Andric                              const RecTy *ValType) {
24180b57cec5SDimitry Andric   assert(CondRange.size() == ValRange.size() &&
24190b57cec5SDimitry Andric          "Number of conditions and values must match!");
24200b57cec5SDimitry Andric   ID.AddPointer(ValType);
24210b57cec5SDimitry Andric   ArrayRef<Init *>::iterator Case = CondRange.begin();
24220b57cec5SDimitry Andric   ArrayRef<Init *>::iterator Val = ValRange.begin();
24230b57cec5SDimitry Andric 
24240b57cec5SDimitry Andric   while (Case != CondRange.end()) {
24250b57cec5SDimitry Andric     ID.AddPointer(*Case++);
24260b57cec5SDimitry Andric     ID.AddPointer(*Val++);
24270b57cec5SDimitry Andric   }
24280b57cec5SDimitry Andric }
24290b57cec5SDimitry Andric 
24300b57cec5SDimitry Andric void CondOpInit::Profile(FoldingSetNodeID &ID) const {
2431bdd1243dSDimitry Andric   ProfileCondOpInit(ID, ArrayRef(getTrailingObjects<Init *>(), NumConds),
2432bdd1243dSDimitry Andric                     ArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds),
24330b57cec5SDimitry Andric                     ValType);
24340b57cec5SDimitry Andric }
24350b57cec5SDimitry Andric 
243681ad6265SDimitry Andric CondOpInit *CondOpInit::get(ArrayRef<Init *> CondRange,
24370b57cec5SDimitry Andric                             ArrayRef<Init *> ValRange, RecTy *Ty) {
24380b57cec5SDimitry Andric   assert(CondRange.size() == ValRange.size() &&
24390b57cec5SDimitry Andric          "Number of conditions and values must match!");
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric   FoldingSetNodeID ID;
24420b57cec5SDimitry Andric   ProfileCondOpInit(ID, CondRange, ValRange, Ty);
24430b57cec5SDimitry Andric 
244481ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl();
24450b57cec5SDimitry Andric   void *IP = nullptr;
244681ad6265SDimitry Andric   if (CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
24470b57cec5SDimitry Andric     return I;
24480b57cec5SDimitry Andric 
244981ad6265SDimitry Andric   void *Mem = RK.Allocator.Allocate(
2450349cc55cSDimitry Andric       totalSizeToAlloc<Init *>(2 * CondRange.size()), alignof(BitsInit));
24510b57cec5SDimitry Andric   CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty);
24520b57cec5SDimitry Andric 
24530b57cec5SDimitry Andric   std::uninitialized_copy(CondRange.begin(), CondRange.end(),
24540b57cec5SDimitry Andric                           I->getTrailingObjects<Init *>());
24550b57cec5SDimitry Andric   std::uninitialized_copy(ValRange.begin(), ValRange.end(),
24560b57cec5SDimitry Andric                           I->getTrailingObjects<Init *>()+CondRange.size());
245781ad6265SDimitry Andric   RK.TheCondOpInitPool.InsertNode(I, IP);
24580b57cec5SDimitry Andric   return I;
24590b57cec5SDimitry Andric }
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric Init *CondOpInit::resolveReferences(Resolver &R) const {
24620b57cec5SDimitry Andric   SmallVector<Init*, 4> NewConds;
24630b57cec5SDimitry Andric   bool Changed = false;
24640b57cec5SDimitry Andric   for (const Init *Case : getConds()) {
24650b57cec5SDimitry Andric     Init *NewCase = Case->resolveReferences(R);
24660b57cec5SDimitry Andric     NewConds.push_back(NewCase);
24670b57cec5SDimitry Andric     Changed |= NewCase != Case;
24680b57cec5SDimitry Andric   }
24690b57cec5SDimitry Andric 
24700b57cec5SDimitry Andric   SmallVector<Init*, 4> NewVals;
24710b57cec5SDimitry Andric   for (const Init *Val : getVals()) {
24720b57cec5SDimitry Andric     Init *NewVal = Val->resolveReferences(R);
24730b57cec5SDimitry Andric     NewVals.push_back(NewVal);
24740b57cec5SDimitry Andric     Changed |= NewVal != Val;
24750b57cec5SDimitry Andric   }
24760b57cec5SDimitry Andric 
24770b57cec5SDimitry Andric   if (Changed)
24780b57cec5SDimitry Andric     return (CondOpInit::get(NewConds, NewVals,
24790b57cec5SDimitry Andric             getValType()))->Fold(R.getCurrentRecord());
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   return const_cast<CondOpInit *>(this);
24820b57cec5SDimitry Andric }
24830b57cec5SDimitry Andric 
24840b57cec5SDimitry Andric Init *CondOpInit::Fold(Record *CurRec) const {
248581ad6265SDimitry Andric   RecordKeeper &RK = getRecordKeeper();
24860b57cec5SDimitry Andric   for ( unsigned i = 0; i < NumConds; ++i) {
24870b57cec5SDimitry Andric     Init *Cond = getCond(i);
24880b57cec5SDimitry Andric     Init *Val = getVal(i);
24890b57cec5SDimitry Andric 
24900b57cec5SDimitry Andric     if (IntInit *CondI = dyn_cast_or_null<IntInit>(
249181ad6265SDimitry Andric             Cond->convertInitializerTo(IntRecTy::get(RK)))) {
24920b57cec5SDimitry Andric       if (CondI->getValue())
24930b57cec5SDimitry Andric         return Val->convertInitializerTo(getValType());
249481ad6265SDimitry Andric     } else {
24950b57cec5SDimitry Andric       return const_cast<CondOpInit *>(this);
24960b57cec5SDimitry Andric     }
249781ad6265SDimitry Andric   }
24980b57cec5SDimitry Andric 
24990b57cec5SDimitry Andric   PrintFatalError(CurRec->getLoc(),
250006c3fb27SDimitry Andric                   CurRec->getNameInitAsString() +
25010b57cec5SDimitry Andric                   " does not have any true condition in:" +
25020b57cec5SDimitry Andric                   this->getAsString());
25030b57cec5SDimitry Andric   return nullptr;
25040b57cec5SDimitry Andric }
25050b57cec5SDimitry Andric 
25060b57cec5SDimitry Andric bool CondOpInit::isConcrete() const {
25070b57cec5SDimitry Andric   for (const Init *Case : getConds())
25080b57cec5SDimitry Andric     if (!Case->isConcrete())
25090b57cec5SDimitry Andric       return false;
25100b57cec5SDimitry Andric 
25110b57cec5SDimitry Andric   for (const Init *Val : getVals())
25120b57cec5SDimitry Andric     if (!Val->isConcrete())
25130b57cec5SDimitry Andric       return false;
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric   return true;
25160b57cec5SDimitry Andric }
25170b57cec5SDimitry Andric 
25180b57cec5SDimitry Andric bool CondOpInit::isComplete() const {
25190b57cec5SDimitry Andric   for (const Init *Case : getConds())
25200b57cec5SDimitry Andric     if (!Case->isComplete())
25210b57cec5SDimitry Andric       return false;
25220b57cec5SDimitry Andric 
25230b57cec5SDimitry Andric   for (const Init *Val : getVals())
25240b57cec5SDimitry Andric     if (!Val->isConcrete())
25250b57cec5SDimitry Andric       return false;
25260b57cec5SDimitry Andric 
25270b57cec5SDimitry Andric   return true;
25280b57cec5SDimitry Andric }
25290b57cec5SDimitry Andric 
25300b57cec5SDimitry Andric std::string CondOpInit::getAsString() const {
25310b57cec5SDimitry Andric   std::string Result = "!cond(";
25320b57cec5SDimitry Andric   for (unsigned i = 0; i < getNumConds(); i++) {
25330b57cec5SDimitry Andric     Result += getCond(i)->getAsString() + ": ";
25340b57cec5SDimitry Andric     Result += getVal(i)->getAsString();
25350b57cec5SDimitry Andric     if (i != getNumConds()-1)
25360b57cec5SDimitry Andric       Result += ", ";
25370b57cec5SDimitry Andric   }
25380b57cec5SDimitry Andric   return Result + ")";
25390b57cec5SDimitry Andric }
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric Init *CondOpInit::getBit(unsigned Bit) const {
25420b57cec5SDimitry Andric   return VarBitInit::get(const_cast<CondOpInit *>(this), Bit);
25430b57cec5SDimitry Andric }
25440b57cec5SDimitry Andric 
25450b57cec5SDimitry Andric static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
25460b57cec5SDimitry Andric                            ArrayRef<Init *> ArgRange,
25470b57cec5SDimitry Andric                            ArrayRef<StringInit *> NameRange) {
25480b57cec5SDimitry Andric   ID.AddPointer(V);
25490b57cec5SDimitry Andric   ID.AddPointer(VN);
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   ArrayRef<Init *>::iterator Arg = ArgRange.begin();
25520b57cec5SDimitry Andric   ArrayRef<StringInit *>::iterator Name = NameRange.begin();
25530b57cec5SDimitry Andric   while (Arg != ArgRange.end()) {
25540b57cec5SDimitry Andric     assert(Name != NameRange.end() && "Arg name underflow!");
25550b57cec5SDimitry Andric     ID.AddPointer(*Arg++);
25560b57cec5SDimitry Andric     ID.AddPointer(*Name++);
25570b57cec5SDimitry Andric   }
25580b57cec5SDimitry Andric   assert(Name == NameRange.end() && "Arg name overflow!");
25590b57cec5SDimitry Andric }
25600b57cec5SDimitry Andric 
2561349cc55cSDimitry Andric DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
25620b57cec5SDimitry Andric                       ArrayRef<StringInit *> NameRange) {
2563bdd1243dSDimitry Andric   assert(ArgRange.size() == NameRange.size());
25640b57cec5SDimitry Andric   FoldingSetNodeID ID;
25650b57cec5SDimitry Andric   ProfileDagInit(ID, V, VN, ArgRange, NameRange);
25660b57cec5SDimitry Andric 
256781ad6265SDimitry Andric   detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl();
25680b57cec5SDimitry Andric   void *IP = nullptr;
256981ad6265SDimitry Andric   if (DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
25700b57cec5SDimitry Andric     return I;
25710b57cec5SDimitry Andric 
257281ad6265SDimitry Andric   void *Mem = RK.Allocator.Allocate(
2573349cc55cSDimitry Andric       totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()),
2574349cc55cSDimitry Andric       alignof(BitsInit));
25750b57cec5SDimitry Andric   DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
25760b57cec5SDimitry Andric   std::uninitialized_copy(ArgRange.begin(), ArgRange.end(),
25770b57cec5SDimitry Andric                           I->getTrailingObjects<Init *>());
25780b57cec5SDimitry Andric   std::uninitialized_copy(NameRange.begin(), NameRange.end(),
25790b57cec5SDimitry Andric                           I->getTrailingObjects<StringInit *>());
258081ad6265SDimitry Andric   RK.TheDagInitPool.InsertNode(I, IP);
25810b57cec5SDimitry Andric   return I;
25820b57cec5SDimitry Andric }
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric DagInit *
25850b57cec5SDimitry Andric DagInit::get(Init *V, StringInit *VN,
25860b57cec5SDimitry Andric              ArrayRef<std::pair<Init*, StringInit*>> args) {
25870b57cec5SDimitry Andric   SmallVector<Init *, 8> Args;
25880b57cec5SDimitry Andric   SmallVector<StringInit *, 8> Names;
25890b57cec5SDimitry Andric 
25900b57cec5SDimitry Andric   for (const auto &Arg : args) {
25910b57cec5SDimitry Andric     Args.push_back(Arg.first);
25920b57cec5SDimitry Andric     Names.push_back(Arg.second);
25930b57cec5SDimitry Andric   }
25940b57cec5SDimitry Andric 
25950b57cec5SDimitry Andric   return DagInit::get(V, VN, Args, Names);
25960b57cec5SDimitry Andric }
25970b57cec5SDimitry Andric 
25980b57cec5SDimitry Andric void DagInit::Profile(FoldingSetNodeID &ID) const {
2599bdd1243dSDimitry Andric   ProfileDagInit(ID, Val, ValName,
2600bdd1243dSDimitry Andric                  ArrayRef(getTrailingObjects<Init *>(), NumArgs),
2601bdd1243dSDimitry Andric                  ArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
26020b57cec5SDimitry Andric }
26030b57cec5SDimitry Andric 
26048bcb0991SDimitry Andric Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const {
26058bcb0991SDimitry Andric   if (DefInit *DefI = dyn_cast<DefInit>(Val))
26068bcb0991SDimitry Andric     return DefI->getDef();
26078bcb0991SDimitry Andric   PrintFatalError(Loc, "Expected record as operator");
26088bcb0991SDimitry Andric   return nullptr;
26098bcb0991SDimitry Andric }
26108bcb0991SDimitry Andric 
261106c3fb27SDimitry Andric std::optional<unsigned> DagInit::getArgNo(StringRef Name) const {
261206c3fb27SDimitry Andric   for (unsigned i = 0, e = getNumArgs(); i < e; ++i) {
261306c3fb27SDimitry Andric     StringInit *ArgName = getArgName(i);
261406c3fb27SDimitry Andric     if (ArgName && ArgName->getValue() == Name)
261506c3fb27SDimitry Andric       return i;
261606c3fb27SDimitry Andric   }
261706c3fb27SDimitry Andric   return std::nullopt;
261806c3fb27SDimitry Andric }
261906c3fb27SDimitry Andric 
26200b57cec5SDimitry Andric Init *DagInit::resolveReferences(Resolver &R) const {
26210b57cec5SDimitry Andric   SmallVector<Init*, 8> NewArgs;
26220b57cec5SDimitry Andric   NewArgs.reserve(arg_size());
26230b57cec5SDimitry Andric   bool ArgsChanged = false;
26240b57cec5SDimitry Andric   for (const Init *Arg : getArgs()) {
26250b57cec5SDimitry Andric     Init *NewArg = Arg->resolveReferences(R);
26260b57cec5SDimitry Andric     NewArgs.push_back(NewArg);
26270b57cec5SDimitry Andric     ArgsChanged |= NewArg != Arg;
26280b57cec5SDimitry Andric   }
26290b57cec5SDimitry Andric 
26300b57cec5SDimitry Andric   Init *Op = Val->resolveReferences(R);
26310b57cec5SDimitry Andric   if (Op != Val || ArgsChanged)
26320b57cec5SDimitry Andric     return DagInit::get(Op, ValName, NewArgs, getArgNames());
26330b57cec5SDimitry Andric 
26340b57cec5SDimitry Andric   return const_cast<DagInit *>(this);
26350b57cec5SDimitry Andric }
26360b57cec5SDimitry Andric 
26370b57cec5SDimitry Andric bool DagInit::isConcrete() const {
26380b57cec5SDimitry Andric   if (!Val->isConcrete())
26390b57cec5SDimitry Andric     return false;
26400b57cec5SDimitry Andric   for (const Init *Elt : getArgs()) {
26410b57cec5SDimitry Andric     if (!Elt->isConcrete())
26420b57cec5SDimitry Andric       return false;
26430b57cec5SDimitry Andric   }
26440b57cec5SDimitry Andric   return true;
26450b57cec5SDimitry Andric }
26460b57cec5SDimitry Andric 
26470b57cec5SDimitry Andric std::string DagInit::getAsString() const {
26480b57cec5SDimitry Andric   std::string Result = "(" + Val->getAsString();
26490b57cec5SDimitry Andric   if (ValName)
26500b57cec5SDimitry Andric     Result += ":" + ValName->getAsUnquotedString();
26510b57cec5SDimitry Andric   if (!arg_empty()) {
26520b57cec5SDimitry Andric     Result += " " + getArg(0)->getAsString();
26530b57cec5SDimitry Andric     if (getArgName(0)) Result += ":$" + getArgName(0)->getAsUnquotedString();
26540b57cec5SDimitry Andric     for (unsigned i = 1, e = getNumArgs(); i != e; ++i) {
26550b57cec5SDimitry Andric       Result += ", " + getArg(i)->getAsString();
26560b57cec5SDimitry Andric       if (getArgName(i)) Result += ":$" + getArgName(i)->getAsUnquotedString();
26570b57cec5SDimitry Andric     }
26580b57cec5SDimitry Andric   }
26590b57cec5SDimitry Andric   return Result + ")";
26600b57cec5SDimitry Andric }
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26630b57cec5SDimitry Andric //    Other implementations
26640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26650b57cec5SDimitry Andric 
2666e8d8bef9SDimitry Andric RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
2667e8d8bef9SDimitry Andric     : Name(N), TyAndKind(T, K) {
266881ad6265SDimitry Andric   setValue(UnsetInit::get(N->getRecordKeeper()));
2669e8d8bef9SDimitry Andric   assert(Value && "Cannot create unset value for current type!");
2670e8d8bef9SDimitry Andric }
2671e8d8bef9SDimitry Andric 
2672e8d8bef9SDimitry Andric // This constructor accepts the same arguments as the above, but also
2673e8d8bef9SDimitry Andric // a source location.
2674e8d8bef9SDimitry Andric RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
2675e8d8bef9SDimitry Andric     : Name(N), Loc(Loc), TyAndKind(T, K) {
267681ad6265SDimitry Andric   setValue(UnsetInit::get(N->getRecordKeeper()));
26770b57cec5SDimitry Andric   assert(Value && "Cannot create unset value for current type!");
26780b57cec5SDimitry Andric }
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric StringRef RecordVal::getName() const {
26810b57cec5SDimitry Andric   return cast<StringInit>(getNameInit())->getValue();
26820b57cec5SDimitry Andric }
26830b57cec5SDimitry Andric 
2684e8d8bef9SDimitry Andric std::string RecordVal::getPrintType() const {
268581ad6265SDimitry Andric   if (getType() == StringRecTy::get(getRecordKeeper())) {
2686e8d8bef9SDimitry Andric     if (auto *StrInit = dyn_cast<StringInit>(Value)) {
2687e8d8bef9SDimitry Andric       if (StrInit->hasCodeFormat())
2688e8d8bef9SDimitry Andric         return "code";
2689e8d8bef9SDimitry Andric       else
2690e8d8bef9SDimitry Andric         return "string";
2691e8d8bef9SDimitry Andric     } else {
2692e8d8bef9SDimitry Andric       return "string";
2693e8d8bef9SDimitry Andric     }
2694e8d8bef9SDimitry Andric   } else {
2695e8d8bef9SDimitry Andric     return TyAndKind.getPointer()->getAsString();
2696e8d8bef9SDimitry Andric   }
2697e8d8bef9SDimitry Andric }
2698e8d8bef9SDimitry Andric 
26990b57cec5SDimitry Andric bool RecordVal::setValue(Init *V) {
27000b57cec5SDimitry Andric   if (V) {
27010b57cec5SDimitry Andric     Value = V->getCastTo(getType());
27020b57cec5SDimitry Andric     if (Value) {
27030b57cec5SDimitry Andric       assert(!isa<TypedInit>(Value) ||
27040b57cec5SDimitry Andric              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
27050b57cec5SDimitry Andric       if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
27060b57cec5SDimitry Andric         if (!isa<BitsInit>(Value)) {
27070b57cec5SDimitry Andric           SmallVector<Init *, 64> Bits;
27080b57cec5SDimitry Andric           Bits.reserve(BTy->getNumBits());
2709e8d8bef9SDimitry Andric           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
2710e8d8bef9SDimitry Andric             Bits.push_back(Value->getBit(I));
271181ad6265SDimitry Andric           Value = BitsInit::get(V->getRecordKeeper(), Bits);
27120b57cec5SDimitry Andric         }
27130b57cec5SDimitry Andric       }
27140b57cec5SDimitry Andric     }
27150b57cec5SDimitry Andric     return Value == nullptr;
27160b57cec5SDimitry Andric   }
27170b57cec5SDimitry Andric   Value = nullptr;
27180b57cec5SDimitry Andric   return false;
27190b57cec5SDimitry Andric }
27200b57cec5SDimitry Andric 
2721e8d8bef9SDimitry Andric // This version of setValue takes a source location and resets the
2722e8d8bef9SDimitry Andric // location in the RecordVal.
2723e8d8bef9SDimitry Andric bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
2724e8d8bef9SDimitry Andric   Loc = NewLoc;
2725e8d8bef9SDimitry Andric   if (V) {
2726e8d8bef9SDimitry Andric     Value = V->getCastTo(getType());
2727e8d8bef9SDimitry Andric     if (Value) {
2728e8d8bef9SDimitry Andric       assert(!isa<TypedInit>(Value) ||
2729e8d8bef9SDimitry Andric              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
2730e8d8bef9SDimitry Andric       if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
2731e8d8bef9SDimitry Andric         if (!isa<BitsInit>(Value)) {
2732e8d8bef9SDimitry Andric           SmallVector<Init *, 64> Bits;
2733e8d8bef9SDimitry Andric           Bits.reserve(BTy->getNumBits());
2734e8d8bef9SDimitry Andric           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
2735e8d8bef9SDimitry Andric             Bits.push_back(Value->getBit(I));
273681ad6265SDimitry Andric           Value = BitsInit::get(getRecordKeeper(), Bits);
2737e8d8bef9SDimitry Andric         }
2738e8d8bef9SDimitry Andric       }
2739e8d8bef9SDimitry Andric     }
2740e8d8bef9SDimitry Andric     return Value == nullptr;
2741e8d8bef9SDimitry Andric   }
2742e8d8bef9SDimitry Andric   Value = nullptr;
2743e8d8bef9SDimitry Andric   return false;
2744e8d8bef9SDimitry Andric }
2745e8d8bef9SDimitry Andric 
27460b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
27471fd87a68SDimitry Andric #include "llvm/TableGen/Record.h"
27480b57cec5SDimitry Andric LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << *this; }
27490b57cec5SDimitry Andric #endif
27500b57cec5SDimitry Andric 
27510b57cec5SDimitry Andric void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
2752e8d8bef9SDimitry Andric   if (isNonconcreteOK()) OS << "field ";
2753e8d8bef9SDimitry Andric   OS << getPrintType() << " " << getNameInitAsString();
27540b57cec5SDimitry Andric 
27550b57cec5SDimitry Andric   if (getValue())
27560b57cec5SDimitry Andric     OS << " = " << *getValue();
27570b57cec5SDimitry Andric 
27580b57cec5SDimitry Andric   if (PrintSem) OS << ";\n";
27590b57cec5SDimitry Andric }
27600b57cec5SDimitry Andric 
2761fcaf7f86SDimitry Andric void Record::updateClassLoc(SMLoc Loc) {
2762fcaf7f86SDimitry Andric   assert(Locs.size() == 1);
2763fcaf7f86SDimitry Andric   ForwardDeclarationLocs.push_back(Locs.front());
2764fcaf7f86SDimitry Andric 
2765fcaf7f86SDimitry Andric   Locs.clear();
2766fcaf7f86SDimitry Andric   Locs.push_back(Loc);
2767fcaf7f86SDimitry Andric }
2768fcaf7f86SDimitry Andric 
27690b57cec5SDimitry Andric void Record::checkName() {
27700b57cec5SDimitry Andric   // Ensure the record name has string type.
27710b57cec5SDimitry Andric   const TypedInit *TypedName = cast<const TypedInit>(Name);
27720b57cec5SDimitry Andric   if (!isa<StringRecTy>(TypedName->getType()))
27730b57cec5SDimitry Andric     PrintFatalError(getLoc(), Twine("Record name '") + Name->getAsString() +
27740b57cec5SDimitry Andric                                   "' is not a string!");
27750b57cec5SDimitry Andric }
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric RecordRecTy *Record::getType() {
27780b57cec5SDimitry Andric   SmallVector<Record *, 4> DirectSCs;
27790b57cec5SDimitry Andric   getDirectSuperClasses(DirectSCs);
278081ad6265SDimitry Andric   return RecordRecTy::get(TrackedRecords, DirectSCs);
27810b57cec5SDimitry Andric }
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric DefInit *Record::getDefInit() {
278481ad6265SDimitry Andric   if (!CorrespondingDefInit) {
278581ad6265SDimitry Andric     CorrespondingDefInit =
278681ad6265SDimitry Andric         new (TrackedRecords.getImpl().Allocator) DefInit(this);
278781ad6265SDimitry Andric   }
2788e8d8bef9SDimitry Andric   return CorrespondingDefInit;
27890b57cec5SDimitry Andric }
27900b57cec5SDimitry Andric 
279181ad6265SDimitry Andric unsigned Record::getNewUID(RecordKeeper &RK) {
279281ad6265SDimitry Andric   return RK.getImpl().LastRecordID++;
279381ad6265SDimitry Andric }
2794349cc55cSDimitry Andric 
27950b57cec5SDimitry Andric void Record::setName(Init *NewName) {
27960b57cec5SDimitry Andric   Name = NewName;
27970b57cec5SDimitry Andric   checkName();
27980b57cec5SDimitry Andric   // DO NOT resolve record values to the name at this point because
27990b57cec5SDimitry Andric   // there might be default values for arguments of this def.  Those
28000b57cec5SDimitry Andric   // arguments might not have been resolved yet so we don't want to
28010b57cec5SDimitry Andric   // prematurely assume values for those arguments were not passed to
28020b57cec5SDimitry Andric   // this def.
28030b57cec5SDimitry Andric   //
28040b57cec5SDimitry Andric   // Nonetheless, it may be that some of this Record's values
28050b57cec5SDimitry Andric   // reference the record name.  Indeed, the reason for having the
28060b57cec5SDimitry Andric   // record name be an Init is to provide this flexibility.  The extra
28070b57cec5SDimitry Andric   // resolve steps after completely instantiating defs takes care of
28080b57cec5SDimitry Andric   // this.  See TGParser::ParseDef and TGParser::ParseDefm.
28090b57cec5SDimitry Andric }
28100b57cec5SDimitry Andric 
2811e8d8bef9SDimitry Andric // NOTE for the next two functions:
2812e8d8bef9SDimitry Andric // Superclasses are in post-order, so the final one is a direct
2813e8d8bef9SDimitry Andric // superclass. All of its transitive superclases immediately precede it,
2814e8d8bef9SDimitry Andric // so we can step through the direct superclasses in reverse order.
2815e8d8bef9SDimitry Andric 
2816e8d8bef9SDimitry Andric bool Record::hasDirectSuperClass(const Record *Superclass) const {
2817e8d8bef9SDimitry Andric   ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
2818e8d8bef9SDimitry Andric 
2819e8d8bef9SDimitry Andric   for (int I = SCs.size() - 1; I >= 0; --I) {
2820e8d8bef9SDimitry Andric     const Record *SC = SCs[I].first;
2821e8d8bef9SDimitry Andric     if (SC == Superclass)
2822e8d8bef9SDimitry Andric       return true;
2823e8d8bef9SDimitry Andric     I -= SC->getSuperClasses().size();
2824e8d8bef9SDimitry Andric   }
2825e8d8bef9SDimitry Andric 
2826e8d8bef9SDimitry Andric   return false;
2827e8d8bef9SDimitry Andric }
2828e8d8bef9SDimitry Andric 
28290b57cec5SDimitry Andric void Record::getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const {
28300b57cec5SDimitry Andric   ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
2831e8d8bef9SDimitry Andric 
28320b57cec5SDimitry Andric   while (!SCs.empty()) {
28330b57cec5SDimitry Andric     Record *SC = SCs.back().first;
28340b57cec5SDimitry Andric     SCs = SCs.drop_back(1 + SC->getSuperClasses().size());
28350b57cec5SDimitry Andric     Classes.push_back(SC);
28360b57cec5SDimitry Andric   }
28370b57cec5SDimitry Andric }
28380b57cec5SDimitry Andric 
28390b57cec5SDimitry Andric void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
2840fe6060f1SDimitry Andric   Init *OldName = getNameInit();
2841fe6060f1SDimitry Andric   Init *NewName = Name->resolveReferences(R);
2842fe6060f1SDimitry Andric   if (NewName != OldName) {
2843fe6060f1SDimitry Andric     // Re-register with RecordKeeper.
2844fe6060f1SDimitry Andric     setName(NewName);
2845fe6060f1SDimitry Andric   }
2846fe6060f1SDimitry Andric 
2847fe6060f1SDimitry Andric   // Resolve the field values.
28480b57cec5SDimitry Andric   for (RecordVal &Value : Values) {
28490b57cec5SDimitry Andric     if (SkipVal == &Value) // Skip resolve the same field as the given one
28500b57cec5SDimitry Andric       continue;
28510b57cec5SDimitry Andric     if (Init *V = Value.getValue()) {
28520b57cec5SDimitry Andric       Init *VR = V->resolveReferences(R);
28530b57cec5SDimitry Andric       if (Value.setValue(VR)) {
28540b57cec5SDimitry Andric         std::string Type;
28550b57cec5SDimitry Andric         if (TypedInit *VRT = dyn_cast<TypedInit>(VR))
28560b57cec5SDimitry Andric           Type =
28570b57cec5SDimitry Andric               (Twine("of type '") + VRT->getType()->getAsString() + "' ").str();
2858fe6060f1SDimitry Andric         PrintFatalError(
2859fe6060f1SDimitry Andric             getLoc(),
2860fe6060f1SDimitry Andric             Twine("Invalid value ") + Type + "found when setting field '" +
2861fe6060f1SDimitry Andric                 Value.getNameInitAsString() + "' of type '" +
28620b57cec5SDimitry Andric                 Value.getType()->getAsString() +
2863fe6060f1SDimitry Andric                 "' after resolving references: " + VR->getAsUnquotedString() +
2864fe6060f1SDimitry Andric                 "\n");
28650b57cec5SDimitry Andric       }
28660b57cec5SDimitry Andric     }
28670b57cec5SDimitry Andric   }
28680b57cec5SDimitry Andric 
2869fe6060f1SDimitry Andric   // Resolve the assertion expressions.
2870fe6060f1SDimitry Andric   for (auto &Assertion : Assertions) {
2871fe6060f1SDimitry Andric     Init *Value = Assertion.Condition->resolveReferences(R);
2872fe6060f1SDimitry Andric     Assertion.Condition = Value;
2873fe6060f1SDimitry Andric     Value = Assertion.Message->resolveReferences(R);
2874fe6060f1SDimitry Andric     Assertion.Message = Value;
2875fe6060f1SDimitry Andric   }
28765f757f3fSDimitry Andric   // Resolve the dump expressions.
28775f757f3fSDimitry Andric   for (auto &Dump : Dumps) {
28785f757f3fSDimitry Andric     Init *Value = Dump.Message->resolveReferences(R);
28795f757f3fSDimitry Andric     Dump.Message = Value;
28805f757f3fSDimitry Andric   }
2881fe6060f1SDimitry Andric }
2882fe6060f1SDimitry Andric 
2883fe6060f1SDimitry Andric void Record::resolveReferences(Init *NewName) {
28840b57cec5SDimitry Andric   RecordResolver R(*this);
2885fe6060f1SDimitry Andric   R.setName(NewName);
28860b57cec5SDimitry Andric   R.setFinal(true);
28870b57cec5SDimitry Andric   resolveReferences(R);
28880b57cec5SDimitry Andric }
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
28910b57cec5SDimitry Andric LLVM_DUMP_METHOD void Record::dump() const { errs() << *this; }
28920b57cec5SDimitry Andric #endif
28930b57cec5SDimitry Andric 
28940b57cec5SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
28950b57cec5SDimitry Andric   OS << R.getNameInitAsString();
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric   ArrayRef<Init *> TArgs = R.getTemplateArgs();
28980b57cec5SDimitry Andric   if (!TArgs.empty()) {
28990b57cec5SDimitry Andric     OS << "<";
29000b57cec5SDimitry Andric     bool NeedComma = false;
29010b57cec5SDimitry Andric     for (const Init *TA : TArgs) {
29020b57cec5SDimitry Andric       if (NeedComma) OS << ", ";
29030b57cec5SDimitry Andric       NeedComma = true;
29040b57cec5SDimitry Andric       const RecordVal *RV = R.getValue(TA);
29050b57cec5SDimitry Andric       assert(RV && "Template argument record not found??");
29060b57cec5SDimitry Andric       RV->print(OS, false);
29070b57cec5SDimitry Andric     }
29080b57cec5SDimitry Andric     OS << ">";
29090b57cec5SDimitry Andric   }
29100b57cec5SDimitry Andric 
29110b57cec5SDimitry Andric   OS << " {";
29120b57cec5SDimitry Andric   ArrayRef<std::pair<Record *, SMRange>> SC = R.getSuperClasses();
29130b57cec5SDimitry Andric   if (!SC.empty()) {
29140b57cec5SDimitry Andric     OS << "\t//";
29150b57cec5SDimitry Andric     for (const auto &SuperPair : SC)
29160b57cec5SDimitry Andric       OS << " " << SuperPair.first->getNameInitAsString();
29170b57cec5SDimitry Andric   }
29180b57cec5SDimitry Andric   OS << "\n";
29190b57cec5SDimitry Andric 
29200b57cec5SDimitry Andric   for (const RecordVal &Val : R.getValues())
2921e8d8bef9SDimitry Andric     if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
29220b57cec5SDimitry Andric       OS << Val;
29230b57cec5SDimitry Andric   for (const RecordVal &Val : R.getValues())
2924e8d8bef9SDimitry Andric     if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
29250b57cec5SDimitry Andric       OS << Val;
29260b57cec5SDimitry Andric 
29270b57cec5SDimitry Andric   return OS << "}\n";
29280b57cec5SDimitry Andric }
29290b57cec5SDimitry Andric 
2930e8d8bef9SDimitry Andric SMLoc Record::getFieldLoc(StringRef FieldName) const {
2931e8d8bef9SDimitry Andric   const RecordVal *R = getValue(FieldName);
2932e8d8bef9SDimitry Andric   if (!R)
2933e8d8bef9SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
2934e8d8bef9SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
2935e8d8bef9SDimitry Andric   return R->getLoc();
2936e8d8bef9SDimitry Andric }
2937e8d8bef9SDimitry Andric 
29380b57cec5SDimitry Andric Init *Record::getValueInit(StringRef FieldName) const {
29390b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
29400b57cec5SDimitry Andric   if (!R || !R->getValue())
29410b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
29420b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
29430b57cec5SDimitry Andric   return R->getValue();
29440b57cec5SDimitry Andric }
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric StringRef Record::getValueAsString(StringRef FieldName) const {
2947bdd1243dSDimitry Andric   std::optional<StringRef> S = getValueAsOptionalString(FieldName);
294881ad6265SDimitry Andric   if (!S)
29490b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
29500b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
2951bdd1243dSDimitry Andric   return *S;
2952e8d8bef9SDimitry Andric }
2953e8d8bef9SDimitry Andric 
2954bdd1243dSDimitry Andric std::optional<StringRef>
2955e8d8bef9SDimitry Andric Record::getValueAsOptionalString(StringRef FieldName) const {
2956e8d8bef9SDimitry Andric   const RecordVal *R = getValue(FieldName);
2957e8d8bef9SDimitry Andric   if (!R || !R->getValue())
2958bdd1243dSDimitry Andric     return std::nullopt;
2959e8d8bef9SDimitry Andric   if (isa<UnsetInit>(R->getValue()))
2960bdd1243dSDimitry Andric     return std::nullopt;
29610b57cec5SDimitry Andric 
29620b57cec5SDimitry Andric   if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
29630b57cec5SDimitry Andric     return SI->getValue();
29640b57cec5SDimitry Andric 
2965e8d8bef9SDimitry Andric   PrintFatalError(getLoc(),
2966e8d8bef9SDimitry Andric                   "Record `" + getName() + "', ` field `" + FieldName +
2967e8d8bef9SDimitry Andric                       "' exists but does not have a string initializer!");
29680b57cec5SDimitry Andric }
29690b57cec5SDimitry Andric 
29700b57cec5SDimitry Andric BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
29710b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
29720b57cec5SDimitry Andric   if (!R || !R->getValue())
29730b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
29740b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric   if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
29770b57cec5SDimitry Andric     return BI;
2978e8d8bef9SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
2979e8d8bef9SDimitry Andric                                 "' exists but does not have a bits value");
29800b57cec5SDimitry Andric }
29810b57cec5SDimitry Andric 
29820b57cec5SDimitry Andric ListInit *Record::getValueAsListInit(StringRef FieldName) const {
29830b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
29840b57cec5SDimitry Andric   if (!R || !R->getValue())
29850b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
29860b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
29870b57cec5SDimitry Andric 
29880b57cec5SDimitry Andric   if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
29890b57cec5SDimitry Andric     return LI;
2990e8d8bef9SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
2991e8d8bef9SDimitry Andric                                 "' exists but does not have a list value");
29920b57cec5SDimitry Andric }
29930b57cec5SDimitry Andric 
29940b57cec5SDimitry Andric std::vector<Record*>
29950b57cec5SDimitry Andric Record::getValueAsListOfDefs(StringRef FieldName) const {
29960b57cec5SDimitry Andric   ListInit *List = getValueAsListInit(FieldName);
29970b57cec5SDimitry Andric   std::vector<Record*> Defs;
29980b57cec5SDimitry Andric   for (Init *I : List->getValues()) {
29990b57cec5SDimitry Andric     if (DefInit *DI = dyn_cast<DefInit>(I))
30000b57cec5SDimitry Andric       Defs.push_back(DI->getDef());
30010b57cec5SDimitry Andric     else
30020b57cec5SDimitry Andric       PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
30030b57cec5SDimitry Andric         FieldName + "' list is not entirely DefInit!");
30040b57cec5SDimitry Andric   }
30050b57cec5SDimitry Andric   return Defs;
30060b57cec5SDimitry Andric }
30070b57cec5SDimitry Andric 
30080b57cec5SDimitry Andric int64_t Record::getValueAsInt(StringRef FieldName) const {
30090b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
30100b57cec5SDimitry Andric   if (!R || !R->getValue())
30110b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
30120b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
30130b57cec5SDimitry Andric 
30140b57cec5SDimitry Andric   if (IntInit *II = dyn_cast<IntInit>(R->getValue()))
30150b57cec5SDimitry Andric     return II->getValue();
30160b57cec5SDimitry Andric   PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" +
30170b57cec5SDimitry Andric                                 FieldName +
3018e8d8bef9SDimitry Andric                                 "' exists but does not have an int value: " +
30190b57cec5SDimitry Andric                                 R->getValue()->getAsString());
30200b57cec5SDimitry Andric }
30210b57cec5SDimitry Andric 
30220b57cec5SDimitry Andric std::vector<int64_t>
30230b57cec5SDimitry Andric Record::getValueAsListOfInts(StringRef FieldName) const {
30240b57cec5SDimitry Andric   ListInit *List = getValueAsListInit(FieldName);
30250b57cec5SDimitry Andric   std::vector<int64_t> Ints;
30260b57cec5SDimitry Andric   for (Init *I : List->getValues()) {
30270b57cec5SDimitry Andric     if (IntInit *II = dyn_cast<IntInit>(I))
30280b57cec5SDimitry Andric       Ints.push_back(II->getValue());
30290b57cec5SDimitry Andric     else
30300b57cec5SDimitry Andric       PrintFatalError(getLoc(),
30310b57cec5SDimitry Andric                       Twine("Record `") + getName() + "', field `" + FieldName +
3032e8d8bef9SDimitry Andric                           "' exists but does not have a list of ints value: " +
30330b57cec5SDimitry Andric                           I->getAsString());
30340b57cec5SDimitry Andric   }
30350b57cec5SDimitry Andric   return Ints;
30360b57cec5SDimitry Andric }
30370b57cec5SDimitry Andric 
30380b57cec5SDimitry Andric std::vector<StringRef>
30390b57cec5SDimitry Andric Record::getValueAsListOfStrings(StringRef FieldName) const {
30400b57cec5SDimitry Andric   ListInit *List = getValueAsListInit(FieldName);
30410b57cec5SDimitry Andric   std::vector<StringRef> Strings;
30420b57cec5SDimitry Andric   for (Init *I : List->getValues()) {
30430b57cec5SDimitry Andric     if (StringInit *SI = dyn_cast<StringInit>(I))
30440b57cec5SDimitry Andric       Strings.push_back(SI->getValue());
30450b57cec5SDimitry Andric     else
30460b57cec5SDimitry Andric       PrintFatalError(getLoc(),
30470b57cec5SDimitry Andric                       Twine("Record `") + getName() + "', field `" + FieldName +
3048e8d8bef9SDimitry Andric                           "' exists but does not have a list of strings value: " +
30490b57cec5SDimitry Andric                           I->getAsString());
30500b57cec5SDimitry Andric   }
30510b57cec5SDimitry Andric   return Strings;
30520b57cec5SDimitry Andric }
30530b57cec5SDimitry Andric 
30540b57cec5SDimitry Andric Record *Record::getValueAsDef(StringRef FieldName) const {
30550b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
30560b57cec5SDimitry Andric   if (!R || !R->getValue())
30570b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
30580b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
30590b57cec5SDimitry Andric 
30600b57cec5SDimitry Andric   if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
30610b57cec5SDimitry Andric     return DI->getDef();
30620b57cec5SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
30630b57cec5SDimitry Andric     FieldName + "' does not have a def initializer!");
30640b57cec5SDimitry Andric }
30650b57cec5SDimitry Andric 
3066480093f4SDimitry Andric Record *Record::getValueAsOptionalDef(StringRef FieldName) const {
3067480093f4SDimitry Andric   const RecordVal *R = getValue(FieldName);
3068480093f4SDimitry Andric   if (!R || !R->getValue())
3069480093f4SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
3070480093f4SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
3071480093f4SDimitry Andric 
3072480093f4SDimitry Andric   if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
3073480093f4SDimitry Andric     return DI->getDef();
3074480093f4SDimitry Andric   if (isa<UnsetInit>(R->getValue()))
3075480093f4SDimitry Andric     return nullptr;
3076480093f4SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3077480093f4SDimitry Andric     FieldName + "' does not have either a def initializer or '?'!");
3078480093f4SDimitry Andric }
3079480093f4SDimitry Andric 
3080480093f4SDimitry Andric 
30810b57cec5SDimitry Andric bool Record::getValueAsBit(StringRef FieldName) const {
30820b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
30830b57cec5SDimitry Andric   if (!R || !R->getValue())
30840b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
30850b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
30860b57cec5SDimitry Andric 
30870b57cec5SDimitry Andric   if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
30880b57cec5SDimitry Andric     return BI->getValue();
30890b57cec5SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
30900b57cec5SDimitry Andric     FieldName + "' does not have a bit initializer!");
30910b57cec5SDimitry Andric }
30920b57cec5SDimitry Andric 
30930b57cec5SDimitry Andric bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
30940b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
30950b57cec5SDimitry Andric   if (!R || !R->getValue())
30960b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
30970b57cec5SDimitry Andric       "' does not have a field named `" + FieldName.str() + "'!\n");
30980b57cec5SDimitry Andric 
30990b57cec5SDimitry Andric   if (isa<UnsetInit>(R->getValue())) {
31000b57cec5SDimitry Andric     Unset = true;
31010b57cec5SDimitry Andric     return false;
31020b57cec5SDimitry Andric   }
31030b57cec5SDimitry Andric   Unset = false;
31040b57cec5SDimitry Andric   if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
31050b57cec5SDimitry Andric     return BI->getValue();
31060b57cec5SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
31070b57cec5SDimitry Andric     FieldName + "' does not have a bit initializer!");
31080b57cec5SDimitry Andric }
31090b57cec5SDimitry Andric 
31100b57cec5SDimitry Andric DagInit *Record::getValueAsDag(StringRef FieldName) const {
31110b57cec5SDimitry Andric   const RecordVal *R = getValue(FieldName);
31120b57cec5SDimitry Andric   if (!R || !R->getValue())
31130b57cec5SDimitry Andric     PrintFatalError(getLoc(), "Record `" + getName() +
31140b57cec5SDimitry Andric       "' does not have a field named `" + FieldName + "'!\n");
31150b57cec5SDimitry Andric 
31160b57cec5SDimitry Andric   if (DagInit *DI = dyn_cast<DagInit>(R->getValue()))
31170b57cec5SDimitry Andric     return DI;
31180b57cec5SDimitry Andric   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
31190b57cec5SDimitry Andric     FieldName + "' does not have a dag initializer!");
31200b57cec5SDimitry Andric }
31210b57cec5SDimitry Andric 
3122fe6060f1SDimitry Andric // Check all record assertions: For each one, resolve the condition
3123fe6060f1SDimitry Andric // and message, then call CheckAssert().
3124fe6060f1SDimitry Andric // Note: The condition and message are probably already resolved,
3125fe6060f1SDimitry Andric //       but resolving again allows calls before records are resolved.
3126fe6060f1SDimitry Andric void Record::checkRecordAssertions() {
3127fe6060f1SDimitry Andric   RecordResolver R(*this);
3128fe6060f1SDimitry Andric   R.setFinal(true);
3129fe6060f1SDimitry Andric 
3130349cc55cSDimitry Andric   for (const auto &Assertion : getAssertions()) {
3131fe6060f1SDimitry Andric     Init *Condition = Assertion.Condition->resolveReferences(R);
3132fe6060f1SDimitry Andric     Init *Message = Assertion.Message->resolveReferences(R);
3133fe6060f1SDimitry Andric     CheckAssert(Assertion.Loc, Condition, Message);
3134fe6060f1SDimitry Andric   }
3135fe6060f1SDimitry Andric }
3136fe6060f1SDimitry Andric 
31375f757f3fSDimitry Andric void Record::emitRecordDumps() {
31385f757f3fSDimitry Andric   RecordResolver R(*this);
31395f757f3fSDimitry Andric   R.setFinal(true);
31405f757f3fSDimitry Andric 
31415f757f3fSDimitry Andric   for (const auto &Dump : getDumps()) {
31425f757f3fSDimitry Andric     Init *Message = Dump.Message->resolveReferences(R);
31435f757f3fSDimitry Andric     dumpMessage(Dump.Loc, Message);
31445f757f3fSDimitry Andric   }
31455f757f3fSDimitry Andric }
31465f757f3fSDimitry Andric 
3147349cc55cSDimitry Andric // Report a warning if the record has unused template arguments.
3148349cc55cSDimitry Andric void Record::checkUnusedTemplateArgs() {
3149349cc55cSDimitry Andric   for (const Init *TA : getTemplateArgs()) {
3150349cc55cSDimitry Andric     const RecordVal *Arg = getValue(TA);
3151349cc55cSDimitry Andric     if (!Arg->isUsed())
3152349cc55cSDimitry Andric       PrintWarning(Arg->getLoc(),
3153349cc55cSDimitry Andric                    "unused template argument: " + Twine(Arg->getName()));
3154349cc55cSDimitry Andric   }
3155349cc55cSDimitry Andric }
3156349cc55cSDimitry Andric 
315781ad6265SDimitry Andric RecordKeeper::RecordKeeper()
315881ad6265SDimitry Andric     : Impl(std::make_unique<detail::RecordKeeperImpl>(*this)) {}
315981ad6265SDimitry Andric RecordKeeper::~RecordKeeper() = default;
316081ad6265SDimitry Andric 
31610b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
31620b57cec5SDimitry Andric LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
31630b57cec5SDimitry Andric #endif
31640b57cec5SDimitry Andric 
31650b57cec5SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
31660b57cec5SDimitry Andric   OS << "------------- Classes -----------------\n";
31670b57cec5SDimitry Andric   for (const auto &C : RK.getClasses())
31680b57cec5SDimitry Andric     OS << "class " << *C.second;
31690b57cec5SDimitry Andric 
31700b57cec5SDimitry Andric   OS << "------------- Defs -----------------\n";
31710b57cec5SDimitry Andric   for (const auto &D : RK.getDefs())
31720b57cec5SDimitry Andric     OS << "def " << *D.second;
31730b57cec5SDimitry Andric   return OS;
31740b57cec5SDimitry Andric }
31750b57cec5SDimitry Andric 
31760b57cec5SDimitry Andric /// GetNewAnonymousName - Generate a unique anonymous name that can be used as
31770b57cec5SDimitry Andric /// an identifier.
31780b57cec5SDimitry Andric Init *RecordKeeper::getNewAnonymousName() {
317981ad6265SDimitry Andric   return AnonymousNameInit::get(*this, getImpl().AnonCounter++);
31800b57cec5SDimitry Andric }
31810b57cec5SDimitry Andric 
3182e8d8bef9SDimitry Andric // These functions implement the phase timing facility. Starting a timer
3183e8d8bef9SDimitry Andric // when one is already running stops the running one.
3184e8d8bef9SDimitry Andric 
3185e8d8bef9SDimitry Andric void RecordKeeper::startTimer(StringRef Name) {
3186e8d8bef9SDimitry Andric   if (TimingGroup) {
3187e8d8bef9SDimitry Andric     if (LastTimer && LastTimer->isRunning()) {
3188e8d8bef9SDimitry Andric       LastTimer->stopTimer();
3189e8d8bef9SDimitry Andric       if (BackendTimer) {
3190e8d8bef9SDimitry Andric         LastTimer->clear();
3191e8d8bef9SDimitry Andric         BackendTimer = false;
3192e8d8bef9SDimitry Andric       }
3193e8d8bef9SDimitry Andric     }
3194e8d8bef9SDimitry Andric 
3195e8d8bef9SDimitry Andric     LastTimer = new Timer("", Name, *TimingGroup);
3196e8d8bef9SDimitry Andric     LastTimer->startTimer();
3197e8d8bef9SDimitry Andric   }
3198e8d8bef9SDimitry Andric }
3199e8d8bef9SDimitry Andric 
3200e8d8bef9SDimitry Andric void RecordKeeper::stopTimer() {
3201e8d8bef9SDimitry Andric   if (TimingGroup) {
3202e8d8bef9SDimitry Andric     assert(LastTimer && "No phase timer was started");
3203e8d8bef9SDimitry Andric     LastTimer->stopTimer();
3204e8d8bef9SDimitry Andric   }
3205e8d8bef9SDimitry Andric }
3206e8d8bef9SDimitry Andric 
3207e8d8bef9SDimitry Andric void RecordKeeper::startBackendTimer(StringRef Name) {
3208e8d8bef9SDimitry Andric   if (TimingGroup) {
3209e8d8bef9SDimitry Andric     startTimer(Name);
3210e8d8bef9SDimitry Andric     BackendTimer = true;
3211e8d8bef9SDimitry Andric   }
3212e8d8bef9SDimitry Andric }
3213e8d8bef9SDimitry Andric 
3214e8d8bef9SDimitry Andric void RecordKeeper::stopBackendTimer() {
3215e8d8bef9SDimitry Andric   if (TimingGroup) {
3216e8d8bef9SDimitry Andric     if (BackendTimer) {
3217e8d8bef9SDimitry Andric       stopTimer();
3218e8d8bef9SDimitry Andric       BackendTimer = false;
3219e8d8bef9SDimitry Andric     }
3220e8d8bef9SDimitry Andric   }
3221e8d8bef9SDimitry Andric }
3222e8d8bef9SDimitry Andric 
322381ad6265SDimitry Andric std::vector<Record *>
322481ad6265SDimitry Andric RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
3225e8d8bef9SDimitry Andric   // We cache the record vectors for single classes. Many backends request
3226e8d8bef9SDimitry Andric   // the same vectors multiple times.
3227e8d8bef9SDimitry Andric   auto Pair = ClassRecordsMap.try_emplace(ClassName);
3228e8d8bef9SDimitry Andric   if (Pair.second)
3229bdd1243dSDimitry Andric     Pair.first->second = getAllDerivedDefinitions(ArrayRef(ClassName));
3230e8d8bef9SDimitry Andric 
3231e8d8bef9SDimitry Andric   return Pair.first->second;
3232e8d8bef9SDimitry Andric }
3233e8d8bef9SDimitry Andric 
3234e8d8bef9SDimitry Andric std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
3235e8d8bef9SDimitry Andric     ArrayRef<StringRef> ClassNames) const {
3236e8d8bef9SDimitry Andric   SmallVector<Record *, 2> ClassRecs;
3237e8d8bef9SDimitry Andric   std::vector<Record *> Defs;
3238e8d8bef9SDimitry Andric 
3239e8d8bef9SDimitry Andric   assert(ClassNames.size() > 0 && "At least one class must be passed.");
3240e8d8bef9SDimitry Andric   for (const auto &ClassName : ClassNames) {
32410b57cec5SDimitry Andric     Record *Class = getClass(ClassName);
32420b57cec5SDimitry Andric     if (!Class)
3243e8d8bef9SDimitry Andric       PrintFatalError("The class '" + ClassName + "' is not defined\n");
3244e8d8bef9SDimitry Andric     ClassRecs.push_back(Class);
3245e8d8bef9SDimitry Andric   }
32460b57cec5SDimitry Andric 
3247e8d8bef9SDimitry Andric   for (const auto &OneDef : getDefs()) {
3248e8d8bef9SDimitry Andric     if (all_of(ClassRecs, [&OneDef](const Record *Class) {
3249e8d8bef9SDimitry Andric                             return OneDef.second->isSubClassOf(Class);
3250e8d8bef9SDimitry Andric                           }))
3251e8d8bef9SDimitry Andric       Defs.push_back(OneDef.second.get());
3252e8d8bef9SDimitry Andric   }
32530b57cec5SDimitry Andric 
3254*0fca6ea1SDimitry Andric   llvm::sort(Defs, LessRecord());
325506c3fb27SDimitry Andric 
32560b57cec5SDimitry Andric   return Defs;
32570b57cec5SDimitry Andric }
32580b57cec5SDimitry Andric 
325981ad6265SDimitry Andric std::vector<Record *>
326081ad6265SDimitry Andric RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const {
326181ad6265SDimitry Andric   return getClass(ClassName) ? getAllDerivedDefinitions(ClassName)
326281ad6265SDimitry Andric                              : std::vector<Record *>();
326381ad6265SDimitry Andric }
326481ad6265SDimitry Andric 
32650b57cec5SDimitry Andric Init *MapResolver::resolve(Init *VarName) {
32660b57cec5SDimitry Andric   auto It = Map.find(VarName);
32670b57cec5SDimitry Andric   if (It == Map.end())
32680b57cec5SDimitry Andric     return nullptr;
32690b57cec5SDimitry Andric 
32700b57cec5SDimitry Andric   Init *I = It->second.V;
32710b57cec5SDimitry Andric 
32720b57cec5SDimitry Andric   if (!It->second.Resolved && Map.size() > 1) {
32730b57cec5SDimitry Andric     // Resolve mutual references among the mapped variables, but prevent
32740b57cec5SDimitry Andric     // infinite recursion.
32750b57cec5SDimitry Andric     Map.erase(It);
32760b57cec5SDimitry Andric     I = I->resolveReferences(*this);
32770b57cec5SDimitry Andric     Map[VarName] = {I, true};
32780b57cec5SDimitry Andric   }
32790b57cec5SDimitry Andric 
32800b57cec5SDimitry Andric   return I;
32810b57cec5SDimitry Andric }
32820b57cec5SDimitry Andric 
32830b57cec5SDimitry Andric Init *RecordResolver::resolve(Init *VarName) {
32840b57cec5SDimitry Andric   Init *Val = Cache.lookup(VarName);
32850b57cec5SDimitry Andric   if (Val)
32860b57cec5SDimitry Andric     return Val;
32870b57cec5SDimitry Andric 
3288fe6060f1SDimitry Andric   if (llvm::is_contained(Stack, VarName))
32890b57cec5SDimitry Andric     return nullptr; // prevent infinite recursion
32900b57cec5SDimitry Andric 
32910b57cec5SDimitry Andric   if (RecordVal *RV = getCurrentRecord()->getValue(VarName)) {
32920b57cec5SDimitry Andric     if (!isa<UnsetInit>(RV->getValue())) {
32930b57cec5SDimitry Andric       Val = RV->getValue();
32940b57cec5SDimitry Andric       Stack.push_back(VarName);
32950b57cec5SDimitry Andric       Val = Val->resolveReferences(*this);
32960b57cec5SDimitry Andric       Stack.pop_back();
32970b57cec5SDimitry Andric     }
3298fe6060f1SDimitry Andric   } else if (Name && VarName == getCurrentRecord()->getNameInit()) {
3299fe6060f1SDimitry Andric     Stack.push_back(VarName);
3300fe6060f1SDimitry Andric     Val = Name->resolveReferences(*this);
3301fe6060f1SDimitry Andric     Stack.pop_back();
33020b57cec5SDimitry Andric   }
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric   Cache[VarName] = Val;
33050b57cec5SDimitry Andric   return Val;
33060b57cec5SDimitry Andric }
33070b57cec5SDimitry Andric 
33080b57cec5SDimitry Andric Init *TrackUnresolvedResolver::resolve(Init *VarName) {
33090b57cec5SDimitry Andric   Init *I = nullptr;
33100b57cec5SDimitry Andric 
33110b57cec5SDimitry Andric   if (R) {
33120b57cec5SDimitry Andric     I = R->resolve(VarName);
33130b57cec5SDimitry Andric     if (I && !FoundUnresolved) {
33140b57cec5SDimitry Andric       // Do not recurse into the resolved initializer, as that would change
33150b57cec5SDimitry Andric       // the behavior of the resolver we're delegating, but do check to see
33160b57cec5SDimitry Andric       // if there are unresolved variables remaining.
33170b57cec5SDimitry Andric       TrackUnresolvedResolver Sub;
33180b57cec5SDimitry Andric       I->resolveReferences(Sub);
33190b57cec5SDimitry Andric       FoundUnresolved |= Sub.FoundUnresolved;
33200b57cec5SDimitry Andric     }
33210b57cec5SDimitry Andric   }
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric   if (!I)
33240b57cec5SDimitry Andric     FoundUnresolved = true;
33250b57cec5SDimitry Andric   return I;
33260b57cec5SDimitry Andric }
33270b57cec5SDimitry Andric 
33280b57cec5SDimitry Andric Init *HasReferenceResolver::resolve(Init *VarName)
33290b57cec5SDimitry Andric {
33300b57cec5SDimitry Andric   if (VarName == VarNameToTrack)
33310b57cec5SDimitry Andric     Found = true;
33320b57cec5SDimitry Andric   return nullptr;
33330b57cec5SDimitry Andric }
3334