xref: /freebsd/contrib/llvm-project/llvm/lib/TableGen/Record.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- Record.cpp - Record implementation ---------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Implement the tablegen record classes.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/TableGen/Record.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/FoldingSet.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/Support/Allocator.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/Regex.h"
29 #include "llvm/Support/SMLoc.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include "llvm/TableGen/Error.h"
32 #include "llvm/TableGen/TGTimer.h"
33 #include <cassert>
34 #include <cstdint>
35 #include <map>
36 #include <memory>
37 #include <string>
38 #include <utility>
39 #include <vector>
40 
41 using namespace llvm;
42 
43 #define DEBUG_TYPE "tblgen-records"
44 
45 //===----------------------------------------------------------------------===//
46 //    Context
47 //===----------------------------------------------------------------------===//
48 
49 namespace llvm {
50 namespace detail {
51 /// This class represents the internal implementation of the RecordKeeper.
52 /// It contains all of the contextual static state of the Record classes. It is
53 /// kept out-of-line to simplify dependencies, and also make it easier for
54 /// internal classes to access the uniquer state of the keeper.
55 struct RecordKeeperImpl {
RecordKeeperImplllvm::detail::RecordKeeperImpl56   RecordKeeperImpl(RecordKeeper &RK)
57       : SharedBitRecTy(RK), SharedIntRecTy(RK), SharedStringRecTy(RK),
58         SharedDagRecTy(RK), AnyRecord(RK, {}), TheUnsetInit(RK),
59         TrueBitInit(true, &SharedBitRecTy),
60         FalseBitInit(false, &SharedBitRecTy), StringInitStringPool(Allocator),
61         StringInitCodePool(Allocator), AnonCounter(0), LastRecordID(0) {}
62 
63   BumpPtrAllocator Allocator;
64   std::vector<BitsRecTy *> SharedBitsRecTys;
65   BitRecTy SharedBitRecTy;
66   IntRecTy SharedIntRecTy;
67   StringRecTy SharedStringRecTy;
68   DagRecTy SharedDagRecTy;
69 
70   RecordRecTy AnyRecord;
71   UnsetInit TheUnsetInit;
72   BitInit TrueBitInit;
73   BitInit FalseBitInit;
74 
75   FoldingSet<ArgumentInit> TheArgumentInitPool;
76   FoldingSet<BitsInit> TheBitsInitPool;
77   std::map<int64_t, IntInit *> TheIntInitPool;
78   StringMap<const StringInit *, BumpPtrAllocator &> StringInitStringPool;
79   StringMap<const StringInit *, BumpPtrAllocator &> StringInitCodePool;
80   FoldingSet<ListInit> TheListInitPool;
81   FoldingSet<UnOpInit> TheUnOpInitPool;
82   FoldingSet<BinOpInit> TheBinOpInitPool;
83   FoldingSet<TernOpInit> TheTernOpInitPool;
84   FoldingSet<FoldOpInit> TheFoldOpInitPool;
85   FoldingSet<IsAOpInit> TheIsAOpInitPool;
86   FoldingSet<ExistsOpInit> TheExistsOpInitPool;
87   FoldingSet<InstancesOpInit> TheInstancesOpInitPool;
88   DenseMap<std::pair<const RecTy *, const Init *>, VarInit *> TheVarInitPool;
89   DenseMap<std::pair<const TypedInit *, unsigned>, VarBitInit *>
90       TheVarBitInitPool;
91   FoldingSet<VarDefInit> TheVarDefInitPool;
92   DenseMap<std::pair<const Init *, const StringInit *>, FieldInit *>
93       TheFieldInitPool;
94   FoldingSet<CondOpInit> TheCondOpInitPool;
95   FoldingSet<DagInit> TheDagInitPool;
96   FoldingSet<RecordRecTy> RecordTypePool;
97 
98   unsigned AnonCounter;
99   unsigned LastRecordID;
100 
101   void dumpAllocationStats(raw_ostream &OS) const;
102 };
103 } // namespace detail
104 } // namespace llvm
105 
dumpAllocationStats(raw_ostream & OS) const106 void detail::RecordKeeperImpl::dumpAllocationStats(raw_ostream &OS) const {
107   // Dump memory allocation related stats.
108   OS << "TheArgumentInitPool size = " << TheArgumentInitPool.size() << '\n';
109   OS << "TheBitsInitPool size = " << TheBitsInitPool.size() << '\n';
110   OS << "TheIntInitPool size = " << TheIntInitPool.size() << '\n';
111   OS << "StringInitStringPool size = " << StringInitStringPool.size() << '\n';
112   OS << "StringInitCodePool size = " << StringInitCodePool.size() << '\n';
113   OS << "TheListInitPool size = " << TheListInitPool.size() << '\n';
114   OS << "TheUnOpInitPool size = " << TheUnOpInitPool.size() << '\n';
115   OS << "TheBinOpInitPool size = " << TheBinOpInitPool.size() << '\n';
116   OS << "TheTernOpInitPool size = " << TheTernOpInitPool.size() << '\n';
117   OS << "TheFoldOpInitPool size = " << TheFoldOpInitPool.size() << '\n';
118   OS << "TheIsAOpInitPool size = " << TheIsAOpInitPool.size() << '\n';
119   OS << "TheExistsOpInitPool size = " << TheExistsOpInitPool.size() << '\n';
120   OS << "TheCondOpInitPool size = " << TheCondOpInitPool.size() << '\n';
121   OS << "TheDagInitPool size = " << TheDagInitPool.size() << '\n';
122   OS << "RecordTypePool size = " << RecordTypePool.size() << '\n';
123   OS << "TheVarInitPool size = " << TheVarInitPool.size() << '\n';
124   OS << "TheVarBitInitPool size = " << TheVarBitInitPool.size() << '\n';
125   OS << "TheVarDefInitPool size = " << TheVarDefInitPool.size() << '\n';
126   OS << "TheFieldInitPool size = " << TheFieldInitPool.size() << '\n';
127   OS << "Bytes allocated = " << Allocator.getBytesAllocated() << '\n';
128   OS << "Total allocator memory = " << Allocator.getTotalMemory() << "\n\n";
129 
130   OS << "Number of records instantiated = " << LastRecordID << '\n';
131   OS << "Number of anonymous records = " << AnonCounter << '\n';
132 }
133 
134 //===----------------------------------------------------------------------===//
135 //    Type implementations
136 //===----------------------------------------------------------------------===//
137 
138 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const139 LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); }
140 #endif
141 
getListTy() const142 const ListRecTy *RecTy::getListTy() const {
143   if (!ListTy)
144     ListTy = new (RK.getImpl().Allocator) ListRecTy(this);
145   return ListTy;
146 }
147 
typeIsConvertibleTo(const RecTy * RHS) const148 bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const {
149   assert(RHS && "NULL pointer");
150   return Kind == RHS->getRecTyKind();
151 }
152 
typeIsA(const RecTy * RHS) const153 bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; }
154 
get(RecordKeeper & RK)155 const BitRecTy *BitRecTy::get(RecordKeeper &RK) {
156   return &RK.getImpl().SharedBitRecTy;
157 }
158 
typeIsConvertibleTo(const RecTy * RHS) const159 bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
160   if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind)
161     return true;
162   if (const auto *BitsTy = dyn_cast<BitsRecTy>(RHS))
163     return BitsTy->getNumBits() == 1;
164   return false;
165 }
166 
get(RecordKeeper & RK,unsigned Sz)167 const BitsRecTy *BitsRecTy::get(RecordKeeper &RK, unsigned Sz) {
168   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
169   if (Sz >= RKImpl.SharedBitsRecTys.size())
170     RKImpl.SharedBitsRecTys.resize(Sz + 1);
171   BitsRecTy *&Ty = RKImpl.SharedBitsRecTys[Sz];
172   if (!Ty)
173     Ty = new (RKImpl.Allocator) BitsRecTy(RK, Sz);
174   return Ty;
175 }
176 
getAsString() const177 std::string BitsRecTy::getAsString() const {
178   return "bits<" + utostr(Size) + ">";
179 }
180 
typeIsConvertibleTo(const RecTy * RHS) const181 bool BitsRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
182   if (RecTy::typeIsConvertibleTo(RHS)) //argument and the sender are same type
183     return cast<BitsRecTy>(RHS)->Size == Size;
184   RecTyKind kind = RHS->getRecTyKind();
185   return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind);
186 }
187 
get(RecordKeeper & RK)188 const IntRecTy *IntRecTy::get(RecordKeeper &RK) {
189   return &RK.getImpl().SharedIntRecTy;
190 }
191 
typeIsConvertibleTo(const RecTy * RHS) const192 bool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
193   RecTyKind kind = RHS->getRecTyKind();
194   return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind;
195 }
196 
get(RecordKeeper & RK)197 const StringRecTy *StringRecTy::get(RecordKeeper &RK) {
198   return &RK.getImpl().SharedStringRecTy;
199 }
200 
getAsString() const201 std::string StringRecTy::getAsString() const {
202   return "string";
203 }
204 
typeIsConvertibleTo(const RecTy * RHS) const205 bool StringRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
206   RecTyKind Kind = RHS->getRecTyKind();
207   return Kind == StringRecTyKind;
208 }
209 
getAsString() const210 std::string ListRecTy::getAsString() const {
211   return "list<" + ElementTy->getAsString() + ">";
212 }
213 
typeIsConvertibleTo(const RecTy * RHS) const214 bool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
215   if (const auto *ListTy = dyn_cast<ListRecTy>(RHS))
216     return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
217   return false;
218 }
219 
typeIsA(const RecTy * RHS) const220 bool ListRecTy::typeIsA(const RecTy *RHS) const {
221   if (const auto *RHSl = dyn_cast<ListRecTy>(RHS))
222     return getElementType()->typeIsA(RHSl->getElementType());
223   return false;
224 }
225 
get(RecordKeeper & RK)226 const DagRecTy *DagRecTy::get(RecordKeeper &RK) {
227   return &RK.getImpl().SharedDagRecTy;
228 }
229 
getAsString() const230 std::string DagRecTy::getAsString() const {
231   return "dag";
232 }
233 
ProfileRecordRecTy(FoldingSetNodeID & ID,ArrayRef<const Record * > Classes)234 static void ProfileRecordRecTy(FoldingSetNodeID &ID,
235                                ArrayRef<const Record *> Classes) {
236   ID.AddInteger(Classes.size());
237   for (const Record *R : Classes)
238     ID.AddPointer(R);
239 }
240 
RecordRecTy(RecordKeeper & RK,ArrayRef<const Record * > Classes)241 RecordRecTy::RecordRecTy(RecordKeeper &RK, ArrayRef<const Record *> Classes)
242     : RecTy(RecordRecTyKind, RK), NumClasses(Classes.size()) {
243   llvm::uninitialized_copy(Classes, getTrailingObjects());
244 }
245 
get(RecordKeeper & RK,ArrayRef<const Record * > UnsortedClasses)246 const RecordRecTy *RecordRecTy::get(RecordKeeper &RK,
247                                     ArrayRef<const Record *> UnsortedClasses) {
248   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
249   if (UnsortedClasses.empty())
250     return &RKImpl.AnyRecord;
251 
252   FoldingSet<RecordRecTy> &ThePool = RKImpl.RecordTypePool;
253 
254   SmallVector<const Record *, 4> Classes(UnsortedClasses);
255   llvm::sort(Classes, [](const Record *LHS, const Record *RHS) {
256     return LHS->getNameInitAsString() < RHS->getNameInitAsString();
257   });
258 
259   FoldingSetNodeID ID;
260   ProfileRecordRecTy(ID, Classes);
261 
262   void *IP = nullptr;
263   if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos(ID, IP))
264     return Ty;
265 
266 #ifndef NDEBUG
267   // Check for redundancy.
268   for (unsigned i = 0; i < Classes.size(); ++i) {
269     for (unsigned j = 0; j < Classes.size(); ++j) {
270       assert(i == j || !Classes[i]->isSubClassOf(Classes[j]));
271     }
272     assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
273   }
274 #endif
275 
276   void *Mem = RKImpl.Allocator.Allocate(
277       totalSizeToAlloc<const Record *>(Classes.size()), alignof(RecordRecTy));
278   RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes);
279   ThePool.InsertNode(Ty, IP);
280   return Ty;
281 }
282 
get(const Record * Class)283 const RecordRecTy *RecordRecTy::get(const Record *Class) {
284   assert(Class && "unexpected null class");
285   return get(Class->getRecords(), {Class});
286 }
287 
Profile(FoldingSetNodeID & ID) const288 void RecordRecTy::Profile(FoldingSetNodeID &ID) const {
289   ProfileRecordRecTy(ID, getClasses());
290 }
291 
getAsString() const292 std::string RecordRecTy::getAsString() const {
293   if (NumClasses == 1)
294     return getClasses()[0]->getNameInitAsString();
295 
296   std::string Str = "{";
297   ListSeparator LS;
298   for (const Record *R : getClasses()) {
299     Str += LS;
300     Str += R->getNameInitAsString();
301   }
302   Str += "}";
303   return Str;
304 }
305 
isSubClassOf(const Record * Class) const306 bool RecordRecTy::isSubClassOf(const Record *Class) const {
307   return llvm::any_of(getClasses(), [Class](const Record *MySuperClass) {
308     return MySuperClass == Class || MySuperClass->isSubClassOf(Class);
309   });
310 }
311 
typeIsConvertibleTo(const RecTy * RHS) const312 bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
313   if (this == RHS)
314     return true;
315 
316   const auto *RTy = dyn_cast<RecordRecTy>(RHS);
317   if (!RTy)
318     return false;
319 
320   return llvm::all_of(RTy->getClasses(), [this](const Record *TargetClass) {
321     return isSubClassOf(TargetClass);
322   });
323 }
324 
typeIsA(const RecTy * RHS) const325 bool RecordRecTy::typeIsA(const RecTy *RHS) const {
326   return typeIsConvertibleTo(RHS);
327 }
328 
resolveRecordTypes(const RecordRecTy * T1,const RecordRecTy * T2)329 static const RecordRecTy *resolveRecordTypes(const RecordRecTy *T1,
330                                              const RecordRecTy *T2) {
331   SmallVector<const Record *, 4> CommonSuperClasses;
332   SmallVector<const Record *, 4> Stack(T1->getClasses());
333 
334   while (!Stack.empty()) {
335     const Record *R = Stack.pop_back_val();
336 
337     if (T2->isSubClassOf(R))
338       CommonSuperClasses.push_back(R);
339     else
340       llvm::append_range(Stack, make_first_range(R->getDirectSuperClasses()));
341   }
342 
343   return RecordRecTy::get(T1->getRecordKeeper(), CommonSuperClasses);
344 }
345 
resolveTypes(const RecTy * T1,const RecTy * T2)346 const RecTy *llvm::resolveTypes(const RecTy *T1, const RecTy *T2) {
347   if (T1 == T2)
348     return T1;
349 
350   if (const auto *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
351     if (const auto *RecTy2 = dyn_cast<RecordRecTy>(T2))
352       return resolveRecordTypes(RecTy1, RecTy2);
353   }
354 
355   assert(T1 != nullptr && "Invalid record type");
356   if (T1->typeIsConvertibleTo(T2))
357     return T2;
358 
359   assert(T2 != nullptr && "Invalid record type");
360   if (T2->typeIsConvertibleTo(T1))
361     return T1;
362 
363   if (const auto *ListTy1 = dyn_cast<ListRecTy>(T1)) {
364     if (const auto *ListTy2 = dyn_cast<ListRecTy>(T2)) {
365       const RecTy *NewType =
366           resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());
367       if (NewType)
368         return NewType->getListTy();
369     }
370   }
371 
372   return nullptr;
373 }
374 
375 //===----------------------------------------------------------------------===//
376 //    Initializer implementations
377 //===----------------------------------------------------------------------===//
378 
anchor()379 void Init::anchor() {}
380 
381 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const382 LLVM_DUMP_METHOD void Init::dump() const { return print(errs()); }
383 #endif
384 
getRecordKeeper() const385 RecordKeeper &Init::getRecordKeeper() const {
386   if (auto *TyInit = dyn_cast<TypedInit>(this))
387     return TyInit->getType()->getRecordKeeper();
388   if (auto *ArgInit = dyn_cast<ArgumentInit>(this))
389     return ArgInit->getRecordKeeper();
390   return cast<UnsetInit>(this)->getRecordKeeper();
391 }
392 
get(RecordKeeper & RK)393 UnsetInit *UnsetInit::get(RecordKeeper &RK) {
394   return &RK.getImpl().TheUnsetInit;
395 }
396 
getCastTo(const RecTy * Ty) const397 const Init *UnsetInit::getCastTo(const RecTy *Ty) const { return this; }
398 
convertInitializerTo(const RecTy * Ty) const399 const Init *UnsetInit::convertInitializerTo(const RecTy *Ty) const {
400   return this;
401 }
402 
ProfileArgumentInit(FoldingSetNodeID & ID,const Init * Value,ArgAuxType Aux)403 static void ProfileArgumentInit(FoldingSetNodeID &ID, const Init *Value,
404                                 ArgAuxType Aux) {
405   auto I = Aux.index();
406   ID.AddInteger(I);
407   if (I == ArgumentInit::Positional)
408     ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
409   if (I == ArgumentInit::Named)
410     ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
411   ID.AddPointer(Value);
412 }
413 
Profile(FoldingSetNodeID & ID) const414 void ArgumentInit::Profile(FoldingSetNodeID &ID) const {
415   ProfileArgumentInit(ID, Value, Aux);
416 }
417 
get(const Init * Value,ArgAuxType Aux)418 const ArgumentInit *ArgumentInit::get(const Init *Value, ArgAuxType Aux) {
419   FoldingSetNodeID ID;
420   ProfileArgumentInit(ID, Value, Aux);
421 
422   RecordKeeper &RK = Value->getRecordKeeper();
423   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
424   void *IP = nullptr;
425   if (const ArgumentInit *I =
426           RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
427     return I;
428 
429   ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value, Aux);
430   RKImpl.TheArgumentInitPool.InsertNode(I, IP);
431   return I;
432 }
433 
resolveReferences(Resolver & R) const434 const Init *ArgumentInit::resolveReferences(Resolver &R) const {
435   const Init *NewValue = Value->resolveReferences(R);
436   if (NewValue != Value)
437     return cloneWithValue(NewValue);
438 
439   return this;
440 }
441 
get(RecordKeeper & RK,bool V)442 BitInit *BitInit::get(RecordKeeper &RK, bool V) {
443   return V ? &RK.getImpl().TrueBitInit : &RK.getImpl().FalseBitInit;
444 }
445 
convertInitializerTo(const RecTy * Ty) const446 const Init *BitInit::convertInitializerTo(const RecTy *Ty) const {
447   if (isa<BitRecTy>(Ty))
448     return this;
449 
450   if (isa<IntRecTy>(Ty))
451     return IntInit::get(getRecordKeeper(), getValue());
452 
453   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
454     // Can only convert single bit.
455     if (BRT->getNumBits() == 1)
456       return BitsInit::get(getRecordKeeper(), this);
457   }
458 
459   return nullptr;
460 }
461 
ProfileBitsInit(FoldingSetNodeID & ID,ArrayRef<const Init * > Range)462 static void ProfileBitsInit(FoldingSetNodeID &ID,
463                             ArrayRef<const Init *> Range) {
464   ID.AddInteger(Range.size());
465 
466   for (const Init *I : Range)
467     ID.AddPointer(I);
468 }
469 
BitsInit(RecordKeeper & RK,ArrayRef<const Init * > Bits)470 BitsInit::BitsInit(RecordKeeper &RK, ArrayRef<const Init *> Bits)
471     : TypedInit(IK_BitsInit, BitsRecTy::get(RK, Bits.size())),
472       NumBits(Bits.size()) {
473   llvm::uninitialized_copy(Bits, getTrailingObjects());
474 }
475 
get(RecordKeeper & RK,ArrayRef<const Init * > Bits)476 BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<const Init *> Bits) {
477   FoldingSetNodeID ID;
478   ProfileBitsInit(ID, Bits);
479 
480   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
481   void *IP = nullptr;
482   if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
483     return I;
484 
485   void *Mem = RKImpl.Allocator.Allocate(
486       totalSizeToAlloc<const Init *>(Bits.size()), alignof(BitsInit));
487   BitsInit *I = new (Mem) BitsInit(RK, Bits);
488   RKImpl.TheBitsInitPool.InsertNode(I, IP);
489   return I;
490 }
491 
Profile(FoldingSetNodeID & ID) const492 void BitsInit::Profile(FoldingSetNodeID &ID) const {
493   ProfileBitsInit(ID, getBits());
494 }
495 
convertInitializerTo(const RecTy * Ty) const496 const Init *BitsInit::convertInitializerTo(const RecTy *Ty) const {
497   if (isa<BitRecTy>(Ty)) {
498     if (getNumBits() != 1) return nullptr; // Only accept if just one bit!
499     return getBit(0);
500   }
501 
502   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
503     // If the number of bits is right, return it. Otherwise we need to expand
504     // or truncate.
505     if (getNumBits() != BRT->getNumBits()) return nullptr;
506     return this;
507   }
508 
509   if (isa<IntRecTy>(Ty)) {
510     std::optional<int64_t> Result = convertInitializerToInt();
511     if (Result)
512       return IntInit::get(getRecordKeeper(), *Result);
513   }
514 
515   return nullptr;
516 }
517 
convertInitializerToInt() const518 std::optional<int64_t> BitsInit::convertInitializerToInt() const {
519   int64_t Result = 0;
520   for (auto [Idx, InitV] : enumerate(getBits()))
521     if (auto *Bit = dyn_cast<BitInit>(InitV))
522       Result |= static_cast<int64_t>(Bit->getValue()) << Idx;
523     else
524       return std::nullopt;
525   return Result;
526 }
527 
528 const Init *
convertInitializerBitRange(ArrayRef<unsigned> Bits) const529 BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
530   SmallVector<const Init *, 16> NewBits(Bits.size());
531 
532   for (auto [Bit, NewBit] : zip_equal(Bits, NewBits)) {
533     if (Bit >= getNumBits())
534       return nullptr;
535     NewBit = getBit(Bit);
536   }
537   return BitsInit::get(getRecordKeeper(), NewBits);
538 }
539 
isComplete() const540 bool BitsInit::isComplete() const {
541   return all_of(getBits(), [](const Init *Bit) { return Bit->isComplete(); });
542 }
allInComplete() const543 bool BitsInit::allInComplete() const {
544   return all_of(getBits(), [](const Init *Bit) { return !Bit->isComplete(); });
545 }
isConcrete() const546 bool BitsInit::isConcrete() const {
547   return all_of(getBits(), [](const Init *Bit) { return Bit->isConcrete(); });
548 }
549 
getAsString() const550 std::string BitsInit::getAsString() const {
551   std::string Result = "{ ";
552   ListSeparator LS;
553   for (const Init *Bit : reverse(getBits())) {
554     Result += LS;
555     if (Bit)
556       Result += Bit->getAsString();
557     else
558       Result += "*";
559   }
560   return Result + " }";
561 }
562 
563 // resolveReferences - If there are any field references that refer to fields
564 // that have been filled in, we can propagate the values now.
resolveReferences(Resolver & R) const565 const Init *BitsInit::resolveReferences(Resolver &R) const {
566   bool Changed = false;
567   SmallVector<const Init *, 16> NewBits(getNumBits());
568 
569   const Init *CachedBitVarRef = nullptr;
570   const Init *CachedBitVarResolved = nullptr;
571 
572   for (auto [CurBit, NewBit] : zip_equal(getBits(), NewBits)) {
573     NewBit = CurBit;
574 
575     if (const auto *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
576       if (CurBitVar->getBitVar() != CachedBitVarRef) {
577         CachedBitVarRef = CurBitVar->getBitVar();
578         CachedBitVarResolved = CachedBitVarRef->resolveReferences(R);
579       }
580       assert(CachedBitVarResolved && "Unresolved bitvar reference");
581       NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum());
582     } else {
583       // getBit(0) implicitly converts int and bits<1> values to bit.
584       NewBit = CurBit->resolveReferences(R)->getBit(0);
585     }
586 
587     if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
588       NewBit = CurBit;
589     Changed |= CurBit != NewBit;
590   }
591 
592   if (Changed)
593     return BitsInit::get(getRecordKeeper(), NewBits);
594 
595   return this;
596 }
597 
get(RecordKeeper & RK,int64_t V)598 IntInit *IntInit::get(RecordKeeper &RK, int64_t V) {
599   IntInit *&I = RK.getImpl().TheIntInitPool[V];
600   if (!I)
601     I = new (RK.getImpl().Allocator) IntInit(RK, V);
602   return I;
603 }
604 
getAsString() const605 std::string IntInit::getAsString() const {
606   return itostr(Value);
607 }
608 
canFitInBitfield(int64_t Value,unsigned NumBits)609 static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
610   // For example, with NumBits == 4, we permit Values from [-7 .. 15].
611   return (NumBits >= sizeof(Value) * 8) ||
612          (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
613 }
614 
convertInitializerTo(const RecTy * Ty) const615 const Init *IntInit::convertInitializerTo(const RecTy *Ty) const {
616   if (isa<IntRecTy>(Ty))
617     return this;
618 
619   if (isa<BitRecTy>(Ty)) {
620     int64_t Val = getValue();
621     if (Val != 0 && Val != 1) return nullptr;  // Only accept 0 or 1 for a bit!
622     return BitInit::get(getRecordKeeper(), Val != 0);
623   }
624 
625   if (const auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
626     int64_t Value = getValue();
627     // Make sure this bitfield is large enough to hold the integer value.
628     if (!canFitInBitfield(Value, BRT->getNumBits()))
629       return nullptr;
630 
631     SmallVector<const Init *, 16> NewBits(BRT->getNumBits());
632     for (unsigned i = 0; i != BRT->getNumBits(); ++i)
633       NewBits[i] =
634           BitInit::get(getRecordKeeper(), Value & ((i < 64) ? (1LL << i) : 0));
635 
636     return BitsInit::get(getRecordKeeper(), NewBits);
637   }
638 
639   return nullptr;
640 }
641 
convertInitializerBitRange(ArrayRef<unsigned> Bits) const642 const Init *IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
643   SmallVector<const Init *, 16> NewBits(Bits.size());
644 
645   for (auto [Bit, NewBit] : zip_equal(Bits, NewBits)) {
646     if (Bit >= 64)
647       return nullptr;
648 
649     NewBit = BitInit::get(getRecordKeeper(), Value & (INT64_C(1) << Bit));
650   }
651   return BitsInit::get(getRecordKeeper(), NewBits);
652 }
653 
get(RecordKeeper & RK,unsigned V)654 AnonymousNameInit *AnonymousNameInit::get(RecordKeeper &RK, unsigned V) {
655   return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V);
656 }
657 
getNameInit() const658 const StringInit *AnonymousNameInit::getNameInit() const {
659   return StringInit::get(getRecordKeeper(), getAsString());
660 }
661 
getAsString() const662 std::string AnonymousNameInit::getAsString() const {
663   return "anonymous_" + utostr(Value);
664 }
665 
resolveReferences(Resolver & R) const666 const Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
667   auto *Old = this;
668   auto *New = R.resolve(Old);
669   New = New ? New : Old;
670   if (R.isFinal())
671     if (const auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
672       return Anonymous->getNameInit();
673   return New;
674 }
675 
get(RecordKeeper & RK,StringRef V,StringFormat Fmt)676 const StringInit *StringInit::get(RecordKeeper &RK, StringRef V,
677                                   StringFormat Fmt) {
678   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
679   auto &InitMap = Fmt == SF_String ? RKImpl.StringInitStringPool
680                                    : RKImpl.StringInitCodePool;
681   auto &Entry = *InitMap.try_emplace(V, nullptr).first;
682   if (!Entry.second)
683     Entry.second = new (RKImpl.Allocator) StringInit(RK, Entry.getKey(), Fmt);
684   return Entry.second;
685 }
686 
convertInitializerTo(const RecTy * Ty) const687 const Init *StringInit::convertInitializerTo(const RecTy *Ty) const {
688   if (isa<StringRecTy>(Ty))
689     return this;
690 
691   return nullptr;
692 }
693 
ProfileListInit(FoldingSetNodeID & ID,ArrayRef<const Init * > Elements,const RecTy * EltTy)694 static void ProfileListInit(FoldingSetNodeID &ID,
695                             ArrayRef<const Init *> Elements,
696                             const RecTy *EltTy) {
697   ID.AddInteger(Elements.size());
698   ID.AddPointer(EltTy);
699 
700   for (const Init *E : Elements)
701     ID.AddPointer(E);
702 }
703 
ListInit(ArrayRef<const Init * > Elements,const RecTy * EltTy)704 ListInit::ListInit(ArrayRef<const Init *> Elements, const RecTy *EltTy)
705     : TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
706       NumElements(Elements.size()) {
707   llvm::uninitialized_copy(Elements, getTrailingObjects());
708 }
709 
get(ArrayRef<const Init * > Elements,const RecTy * EltTy)710 const ListInit *ListInit::get(ArrayRef<const Init *> Elements,
711                               const RecTy *EltTy) {
712   FoldingSetNodeID ID;
713   ProfileListInit(ID, Elements, EltTy);
714 
715   detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl();
716   void *IP = nullptr;
717   if (const ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
718     return I;
719 
720   assert(Elements.empty() || !isa<TypedInit>(Elements[0]) ||
721          cast<TypedInit>(Elements[0])->getType()->typeIsConvertibleTo(EltTy));
722 
723   void *Mem = RK.Allocator.Allocate(
724       totalSizeToAlloc<const Init *>(Elements.size()), alignof(ListInit));
725   ListInit *I = new (Mem) ListInit(Elements, EltTy);
726   RK.TheListInitPool.InsertNode(I, IP);
727   return I;
728 }
729 
Profile(FoldingSetNodeID & ID) const730 void ListInit::Profile(FoldingSetNodeID &ID) const {
731   const RecTy *EltTy = cast<ListRecTy>(getType())->getElementType();
732   ProfileListInit(ID, getElements(), EltTy);
733 }
734 
convertInitializerTo(const RecTy * Ty) const735 const Init *ListInit::convertInitializerTo(const RecTy *Ty) const {
736   if (getType() == Ty)
737     return this;
738 
739   if (const auto *LRT = dyn_cast<ListRecTy>(Ty)) {
740     SmallVector<const Init *, 8> Elements;
741     Elements.reserve(size());
742 
743     // Verify that all of the elements of the list are subclasses of the
744     // appropriate class!
745     bool Changed = false;
746     const RecTy *ElementType = LRT->getElementType();
747     for (const Init *I : getElements())
748       if (const Init *CI = I->convertInitializerTo(ElementType)) {
749         Elements.push_back(CI);
750         if (CI != I)
751           Changed = true;
752       } else {
753         return nullptr;
754       }
755 
756     if (!Changed)
757       return this;
758     return ListInit::get(Elements, ElementType);
759   }
760 
761   return nullptr;
762 }
763 
getElementAsRecord(unsigned Idx) const764 const Record *ListInit::getElementAsRecord(unsigned Idx) const {
765   const auto *DI = dyn_cast<DefInit>(getElement(Idx));
766   if (!DI)
767     PrintFatalError("Expected record in list!");
768   return DI->getDef();
769 }
770 
resolveReferences(Resolver & R) const771 const Init *ListInit::resolveReferences(Resolver &R) const {
772   SmallVector<const Init *, 8> Resolved;
773   Resolved.reserve(size());
774   bool Changed = false;
775 
776   for (const Init *CurElt : getElements()) {
777     const Init *E = CurElt->resolveReferences(R);
778     Changed |= E != CurElt;
779     Resolved.push_back(E);
780   }
781 
782   if (Changed)
783     return ListInit::get(Resolved, getElementType());
784   return this;
785 }
786 
isComplete() const787 bool ListInit::isComplete() const {
788   return all_of(*this,
789                 [](const Init *Element) { return Element->isComplete(); });
790 }
791 
isConcrete() const792 bool ListInit::isConcrete() const {
793   return all_of(*this,
794                 [](const Init *Element) { return Element->isConcrete(); });
795 }
796 
getAsString() const797 std::string ListInit::getAsString() const {
798   std::string Result = "[";
799   ListSeparator LS;
800   for (const Init *Element : *this) {
801     Result += LS;
802     Result += Element->getAsString();
803   }
804   return Result + "]";
805 }
806 
getBit(unsigned Bit) const807 const Init *OpInit::getBit(unsigned Bit) const {
808   if (getType() == BitRecTy::get(getRecordKeeper()))
809     return this;
810   return VarBitInit::get(this, Bit);
811 }
812 
ProfileUnOpInit(FoldingSetNodeID & ID,unsigned Opcode,const Init * Op,const RecTy * Type)813 static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode,
814                             const Init *Op, const RecTy *Type) {
815   ID.AddInteger(Opcode);
816   ID.AddPointer(Op);
817   ID.AddPointer(Type);
818 }
819 
get(UnaryOp Opc,const Init * LHS,const RecTy * Type)820 const UnOpInit *UnOpInit::get(UnaryOp Opc, const Init *LHS, const RecTy *Type) {
821   FoldingSetNodeID ID;
822   ProfileUnOpInit(ID, Opc, LHS, Type);
823 
824   detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl();
825   void *IP = nullptr;
826   if (const UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
827     return I;
828 
829   UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type);
830   RK.TheUnOpInitPool.InsertNode(I, IP);
831   return I;
832 }
833 
Profile(FoldingSetNodeID & ID) const834 void UnOpInit::Profile(FoldingSetNodeID &ID) const {
835   ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
836 }
837 
Fold(const Record * CurRec,bool IsFinal) const838 const Init *UnOpInit::Fold(const Record *CurRec, bool IsFinal) const {
839   RecordKeeper &RK = getRecordKeeper();
840   switch (getOpcode()) {
841   case REPR:
842     if (LHS->isConcrete()) {
843       // If it is a Record, print the full content.
844       if (const auto *Def = dyn_cast<DefInit>(LHS)) {
845         std::string S;
846         raw_string_ostream OS(S);
847         OS << *Def->getDef();
848         return StringInit::get(RK, S);
849       } else {
850         // Otherwise, print the value of the variable.
851         //
852         // NOTE: we could recursively !repr the elements of a list,
853         // but that could produce a lot of output when printing a
854         // defset.
855         return StringInit::get(RK, LHS->getAsString());
856       }
857     }
858     break;
859   case TOLOWER:
860     if (const auto *LHSs = dyn_cast<StringInit>(LHS))
861       return StringInit::get(RK, LHSs->getValue().lower());
862     break;
863   case TOUPPER:
864     if (const auto *LHSs = dyn_cast<StringInit>(LHS))
865       return StringInit::get(RK, LHSs->getValue().upper());
866     break;
867   case CAST:
868     if (isa<StringRecTy>(getType())) {
869       if (const auto *LHSs = dyn_cast<StringInit>(LHS))
870         return LHSs;
871 
872       if (const auto *LHSd = dyn_cast<DefInit>(LHS))
873         return StringInit::get(RK, LHSd->getAsString());
874 
875       if (const auto *LHSi = dyn_cast_or_null<IntInit>(
876               LHS->convertInitializerTo(IntRecTy::get(RK))))
877         return StringInit::get(RK, LHSi->getAsString());
878 
879     } else if (isa<RecordRecTy>(getType())) {
880       if (const auto *Name = dyn_cast<StringInit>(LHS)) {
881         const Record *D = RK.getDef(Name->getValue());
882         if (!D && CurRec) {
883           // Self-references are allowed, but their resolution is delayed until
884           // the final resolve to ensure that we get the correct type for them.
885           auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
886           if (Name == CurRec->getNameInit() ||
887               (Anonymous && Name == Anonymous->getNameInit())) {
888             if (!IsFinal)
889               break;
890             D = CurRec;
891           }
892         }
893 
894         auto PrintFatalErrorHelper = [CurRec](const Twine &T) {
895           if (CurRec)
896             PrintFatalError(CurRec->getLoc(), T);
897           else
898             PrintFatalError(T);
899         };
900 
901         if (!D) {
902           if (IsFinal) {
903             PrintFatalErrorHelper(Twine("Undefined reference to record: '") +
904                                   Name->getValue() + "'\n");
905           }
906           break;
907         }
908 
909         DefInit *DI = D->getDefInit();
910         if (!DI->getType()->typeIsA(getType())) {
911           PrintFatalErrorHelper(Twine("Expected type '") +
912                                 getType()->getAsString() + "', got '" +
913                                 DI->getType()->getAsString() + "' in: " +
914                                 getAsString() + "\n");
915         }
916         return DI;
917       }
918     }
919 
920     if (const Init *NewInit = LHS->convertInitializerTo(getType()))
921       return NewInit;
922     break;
923 
924   case INITIALIZED:
925     if (isa<UnsetInit>(LHS))
926       return IntInit::get(RK, 0);
927     if (LHS->isConcrete())
928       return IntInit::get(RK, 1);
929     break;
930 
931   case NOT:
932     if (const auto *LHSi = dyn_cast_or_null<IntInit>(
933             LHS->convertInitializerTo(IntRecTy::get(RK))))
934       return IntInit::get(RK, LHSi->getValue() ? 0 : 1);
935     break;
936 
937   case HEAD:
938     if (const auto *LHSl = dyn_cast<ListInit>(LHS)) {
939       assert(!LHSl->empty() && "Empty list in head");
940       return LHSl->getElement(0);
941     }
942     break;
943 
944   case TAIL:
945     if (const auto *LHSl = dyn_cast<ListInit>(LHS)) {
946       assert(!LHSl->empty() && "Empty list in tail");
947       // Note the slice(1). We can't just pass the result of getElements()
948       // directly.
949       return ListInit::get(LHSl->getElements().slice(1),
950                            LHSl->getElementType());
951     }
952     break;
953 
954   case SIZE:
955     if (const auto *LHSl = dyn_cast<ListInit>(LHS))
956       return IntInit::get(RK, LHSl->size());
957     if (const auto *LHSd = dyn_cast<DagInit>(LHS))
958       return IntInit::get(RK, LHSd->arg_size());
959     if (const auto *LHSs = dyn_cast<StringInit>(LHS))
960       return IntInit::get(RK, LHSs->getValue().size());
961     break;
962 
963   case EMPTY:
964     if (const auto *LHSl = dyn_cast<ListInit>(LHS))
965       return IntInit::get(RK, LHSl->empty());
966     if (const auto *LHSd = dyn_cast<DagInit>(LHS))
967       return IntInit::get(RK, LHSd->arg_empty());
968     if (const auto *LHSs = dyn_cast<StringInit>(LHS))
969       return IntInit::get(RK, LHSs->getValue().empty());
970     break;
971 
972   case GETDAGOP:
973     if (const auto *Dag = dyn_cast<DagInit>(LHS)) {
974       // TI is not necessarily a def due to the late resolution in multiclasses,
975       // but has to be a TypedInit.
976       auto *TI = cast<TypedInit>(Dag->getOperator());
977       if (!TI->getType()->typeIsA(getType())) {
978         PrintFatalError(CurRec->getLoc(),
979                         Twine("Expected type '") + getType()->getAsString() +
980                             "', got '" + TI->getType()->getAsString() +
981                             "' in: " + getAsString() + "\n");
982       } else {
983         return Dag->getOperator();
984       }
985     }
986     break;
987 
988   case LOG2:
989     if (const auto *LHSi = dyn_cast_or_null<IntInit>(
990             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
991       int64_t LHSv = LHSi->getValue();
992       if (LHSv <= 0) {
993         PrintFatalError(CurRec->getLoc(),
994                         "Illegal operation: logtwo is undefined "
995                         "on arguments less than or equal to 0");
996       } else {
997         uint64_t Log = Log2_64(LHSv);
998         assert(Log <= INT64_MAX &&
999                "Log of an int64_t must be smaller than INT64_MAX");
1000         return IntInit::get(RK, static_cast<int64_t>(Log));
1001       }
1002     }
1003     break;
1004 
1005   case LISTFLATTEN:
1006     if (const auto *LHSList = dyn_cast<ListInit>(LHS)) {
1007       const auto *InnerListTy = dyn_cast<ListRecTy>(LHSList->getElementType());
1008       // list of non-lists, !listflatten() is a NOP.
1009       if (!InnerListTy)
1010         return LHS;
1011 
1012       auto Flatten =
1013           [](const ListInit *List) -> std::optional<std::vector<const Init *>> {
1014         std::vector<const Init *> Flattened;
1015         // Concatenate elements of all the inner lists.
1016         for (const Init *InnerInit : List->getElements()) {
1017           const auto *InnerList = dyn_cast<ListInit>(InnerInit);
1018           if (!InnerList)
1019             return std::nullopt;
1020           llvm::append_range(Flattened, InnerList->getElements());
1021         };
1022         return Flattened;
1023       };
1024 
1025       auto Flattened = Flatten(LHSList);
1026       if (Flattened)
1027         return ListInit::get(*Flattened, InnerListTy->getElementType());
1028     }
1029     break;
1030   }
1031   return this;
1032 }
1033 
resolveReferences(Resolver & R) const1034 const Init *UnOpInit::resolveReferences(Resolver &R) const {
1035   const Init *lhs = LHS->resolveReferences(R);
1036 
1037   if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
1038     return (UnOpInit::get(getOpcode(), lhs, getType()))
1039         ->Fold(R.getCurrentRecord(), R.isFinal());
1040   return this;
1041 }
1042 
getAsString() const1043 std::string UnOpInit::getAsString() const {
1044   std::string Result;
1045   switch (getOpcode()) {
1046   case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
1047   case NOT: Result = "!not"; break;
1048   case HEAD: Result = "!head"; break;
1049   case TAIL: Result = "!tail"; break;
1050   case SIZE: Result = "!size"; break;
1051   case EMPTY: Result = "!empty"; break;
1052   case GETDAGOP: Result = "!getdagop"; break;
1053   case LOG2 : Result = "!logtwo"; break;
1054   case LISTFLATTEN:
1055     Result = "!listflatten";
1056     break;
1057   case REPR:
1058     Result = "!repr";
1059     break;
1060   case TOLOWER:
1061     Result = "!tolower";
1062     break;
1063   case TOUPPER:
1064     Result = "!toupper";
1065     break;
1066   case INITIALIZED:
1067     Result = "!initialized";
1068     break;
1069   }
1070   return Result + "(" + LHS->getAsString() + ")";
1071 }
1072 
ProfileBinOpInit(FoldingSetNodeID & ID,unsigned Opcode,const Init * LHS,const Init * RHS,const RecTy * Type)1073 static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode,
1074                              const Init *LHS, const Init *RHS,
1075                              const RecTy *Type) {
1076   ID.AddInteger(Opcode);
1077   ID.AddPointer(LHS);
1078   ID.AddPointer(RHS);
1079   ID.AddPointer(Type);
1080 }
1081 
get(BinaryOp Opc,const Init * LHS,const Init * RHS,const RecTy * Type)1082 const BinOpInit *BinOpInit::get(BinaryOp Opc, const Init *LHS, const Init *RHS,
1083                                 const RecTy *Type) {
1084   FoldingSetNodeID ID;
1085   ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
1086 
1087   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
1088   void *IP = nullptr;
1089   if (const BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
1090     return I;
1091 
1092   BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);
1093   RK.TheBinOpInitPool.InsertNode(I, IP);
1094   return I;
1095 }
1096 
Profile(FoldingSetNodeID & ID) const1097 void BinOpInit::Profile(FoldingSetNodeID &ID) const {
1098   ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
1099 }
1100 
ConcatStringInits(const StringInit * I0,const StringInit * I1)1101 static const StringInit *ConcatStringInits(const StringInit *I0,
1102                                            const StringInit *I1) {
1103   SmallString<80> Concat(I0->getValue());
1104   Concat.append(I1->getValue());
1105   return StringInit::get(
1106       I0->getRecordKeeper(), Concat,
1107       StringInit::determineFormat(I0->getFormat(), I1->getFormat()));
1108 }
1109 
interleaveStringList(const ListInit * List,const StringInit * Delim)1110 static const StringInit *interleaveStringList(const ListInit *List,
1111                                               const StringInit *Delim) {
1112   if (List->size() == 0)
1113     return StringInit::get(List->getRecordKeeper(), "");
1114   const auto *Element = dyn_cast<StringInit>(List->getElement(0));
1115   if (!Element)
1116     return nullptr;
1117   SmallString<80> Result(Element->getValue());
1118   StringInit::StringFormat Fmt = StringInit::SF_String;
1119 
1120   for (const Init *Elem : List->getElements().drop_front()) {
1121     Result.append(Delim->getValue());
1122     const auto *Element = dyn_cast<StringInit>(Elem);
1123     if (!Element)
1124       return nullptr;
1125     Result.append(Element->getValue());
1126     Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
1127   }
1128   return StringInit::get(List->getRecordKeeper(), Result, Fmt);
1129 }
1130 
interleaveIntList(const ListInit * List,const StringInit * Delim)1131 static const StringInit *interleaveIntList(const ListInit *List,
1132                                            const StringInit *Delim) {
1133   RecordKeeper &RK = List->getRecordKeeper();
1134   if (List->size() == 0)
1135     return StringInit::get(RK, "");
1136   const auto *Element = dyn_cast_or_null<IntInit>(
1137       List->getElement(0)->convertInitializerTo(IntRecTy::get(RK)));
1138   if (!Element)
1139     return nullptr;
1140   SmallString<80> Result(Element->getAsString());
1141 
1142   for (const Init *Elem : List->getElements().drop_front()) {
1143     Result.append(Delim->getValue());
1144     const auto *Element = dyn_cast_or_null<IntInit>(
1145         Elem->convertInitializerTo(IntRecTy::get(RK)));
1146     if (!Element)
1147       return nullptr;
1148     Result.append(Element->getAsString());
1149   }
1150   return StringInit::get(RK, Result);
1151 }
1152 
getStrConcat(const Init * I0,const Init * I1)1153 const Init *BinOpInit::getStrConcat(const Init *I0, const Init *I1) {
1154   // Shortcut for the common case of concatenating two strings.
1155   if (const auto *I0s = dyn_cast<StringInit>(I0))
1156     if (const auto *I1s = dyn_cast<StringInit>(I1))
1157       return ConcatStringInits(I0s, I1s);
1158   return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1,
1159                         StringRecTy::get(I0->getRecordKeeper()));
1160 }
1161 
ConcatListInits(const ListInit * LHS,const ListInit * RHS)1162 static const ListInit *ConcatListInits(const ListInit *LHS,
1163                                        const ListInit *RHS) {
1164   SmallVector<const Init *, 8> Args;
1165   llvm::append_range(Args, *LHS);
1166   llvm::append_range(Args, *RHS);
1167   return ListInit::get(Args, LHS->getElementType());
1168 }
1169 
getListConcat(const TypedInit * LHS,const Init * RHS)1170 const Init *BinOpInit::getListConcat(const TypedInit *LHS, const Init *RHS) {
1171   assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list");
1172 
1173   // Shortcut for the common case of concatenating two lists.
1174   if (const auto *LHSList = dyn_cast<ListInit>(LHS))
1175     if (const auto *RHSList = dyn_cast<ListInit>(RHS))
1176       return ConcatListInits(LHSList, RHSList);
1177   return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
1178 }
1179 
CompareInit(unsigned Opc,const Init * LHS,const Init * RHS) const1180 std::optional<bool> BinOpInit::CompareInit(unsigned Opc, const Init *LHS,
1181                                            const Init *RHS) const {
1182   // First see if we have two bit, bits, or int.
1183   const auto *LHSi = dyn_cast_or_null<IntInit>(
1184       LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1185   const auto *RHSi = dyn_cast_or_null<IntInit>(
1186       RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1187 
1188   if (LHSi && RHSi) {
1189     bool Result;
1190     switch (Opc) {
1191     case EQ:
1192       Result = LHSi->getValue() == RHSi->getValue();
1193       break;
1194     case NE:
1195       Result = LHSi->getValue() != RHSi->getValue();
1196       break;
1197     case LE:
1198       Result = LHSi->getValue() <= RHSi->getValue();
1199       break;
1200     case LT:
1201       Result = LHSi->getValue() < RHSi->getValue();
1202       break;
1203     case GE:
1204       Result = LHSi->getValue() >= RHSi->getValue();
1205       break;
1206     case GT:
1207       Result = LHSi->getValue() > RHSi->getValue();
1208       break;
1209     default:
1210       llvm_unreachable("unhandled comparison");
1211     }
1212     return Result;
1213   }
1214 
1215   // Next try strings.
1216   const auto *LHSs = dyn_cast<StringInit>(LHS);
1217   const auto *RHSs = dyn_cast<StringInit>(RHS);
1218 
1219   if (LHSs && RHSs) {
1220     bool Result;
1221     switch (Opc) {
1222     case EQ:
1223       Result = LHSs->getValue() == RHSs->getValue();
1224       break;
1225     case NE:
1226       Result = LHSs->getValue() != RHSs->getValue();
1227       break;
1228     case LE:
1229       Result = LHSs->getValue() <= RHSs->getValue();
1230       break;
1231     case LT:
1232       Result = LHSs->getValue() < RHSs->getValue();
1233       break;
1234     case GE:
1235       Result = LHSs->getValue() >= RHSs->getValue();
1236       break;
1237     case GT:
1238       Result = LHSs->getValue() > RHSs->getValue();
1239       break;
1240     default:
1241       llvm_unreachable("unhandled comparison");
1242     }
1243     return Result;
1244   }
1245 
1246   // Finally, !eq and !ne can be used with records.
1247   if (Opc == EQ || Opc == NE) {
1248     const auto *LHSd = dyn_cast<DefInit>(LHS);
1249     const auto *RHSd = dyn_cast<DefInit>(RHS);
1250     if (LHSd && RHSd)
1251       return (Opc == EQ) ? LHSd == RHSd : LHSd != RHSd;
1252   }
1253 
1254   return std::nullopt;
1255 }
1256 
1257 static std::optional<unsigned>
getDagArgNoByKey(const DagInit * Dag,const Init * Key,std::string & Error)1258 getDagArgNoByKey(const DagInit *Dag, const Init *Key, std::string &Error) {
1259   // Accessor by index
1260   if (const auto *Idx = dyn_cast<IntInit>(Key)) {
1261     int64_t Pos = Idx->getValue();
1262     if (Pos < 0) {
1263       // The index is negative.
1264       Error =
1265           (Twine("index ") + std::to_string(Pos) + Twine(" is negative")).str();
1266       return std::nullopt;
1267     }
1268     if (Pos >= Dag->getNumArgs()) {
1269       // The index is out-of-range.
1270       Error = (Twine("index ") + std::to_string(Pos) +
1271                " is out of range (dag has " +
1272                std::to_string(Dag->getNumArgs()) + " arguments)")
1273                   .str();
1274       return std::nullopt;
1275     }
1276     return Pos;
1277   }
1278   assert(isa<StringInit>(Key));
1279   // Accessor by name
1280   const auto *Name = dyn_cast<StringInit>(Key);
1281   auto ArgNo = Dag->getArgNo(Name->getValue());
1282   if (!ArgNo) {
1283     // The key is not found.
1284     Error = (Twine("key '") + Name->getValue() + Twine("' is not found")).str();
1285     return std::nullopt;
1286   }
1287   return *ArgNo;
1288 }
1289 
Fold(const Record * CurRec) const1290 const Init *BinOpInit::Fold(const Record *CurRec) const {
1291   switch (getOpcode()) {
1292   case CONCAT: {
1293     const auto *LHSs = dyn_cast<DagInit>(LHS);
1294     const auto *RHSs = dyn_cast<DagInit>(RHS);
1295     if (LHSs && RHSs) {
1296       const auto *LOp = dyn_cast<DefInit>(LHSs->getOperator());
1297       const auto *ROp = dyn_cast<DefInit>(RHSs->getOperator());
1298       if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
1299           (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
1300         break;
1301       if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1302         PrintFatalError(Twine("Concatenated Dag operators do not match: '") +
1303                         LHSs->getAsString() + "' vs. '" + RHSs->getAsString() +
1304                         "'");
1305       }
1306       const Init *Op = LOp ? LOp : ROp;
1307       if (!Op)
1308         Op = UnsetInit::get(getRecordKeeper());
1309 
1310       SmallVector<std::pair<const Init *, const StringInit *>, 8> Args;
1311       llvm::append_range(Args, LHSs->getArgAndNames());
1312       llvm::append_range(Args, RHSs->getArgAndNames());
1313       return DagInit::get(Op, Args);
1314     }
1315     break;
1316   }
1317   case MATCH: {
1318     const auto *StrInit = dyn_cast<StringInit>(LHS);
1319     if (!StrInit)
1320       return this;
1321 
1322     const auto *RegexInit = dyn_cast<StringInit>(RHS);
1323     if (!RegexInit)
1324       return this;
1325 
1326     StringRef RegexStr = RegexInit->getValue();
1327     llvm::Regex Matcher(RegexStr);
1328     if (!Matcher.isValid())
1329       PrintFatalError(Twine("invalid regex '") + RegexStr + Twine("'"));
1330 
1331     return BitInit::get(LHS->getRecordKeeper(),
1332                         Matcher.match(StrInit->getValue()));
1333   }
1334   case LISTCONCAT: {
1335     const auto *LHSs = dyn_cast<ListInit>(LHS);
1336     const auto *RHSs = dyn_cast<ListInit>(RHS);
1337     if (LHSs && RHSs) {
1338       SmallVector<const Init *, 8> Args;
1339       llvm::append_range(Args, *LHSs);
1340       llvm::append_range(Args, *RHSs);
1341       return ListInit::get(Args, LHSs->getElementType());
1342     }
1343     break;
1344   }
1345   case LISTSPLAT: {
1346     const auto *Value = dyn_cast<TypedInit>(LHS);
1347     const auto *Size = dyn_cast<IntInit>(RHS);
1348     if (Value && Size) {
1349       SmallVector<const Init *, 8> Args(Size->getValue(), Value);
1350       return ListInit::get(Args, Value->getType());
1351     }
1352     break;
1353   }
1354   case LISTREMOVE: {
1355     const auto *LHSs = dyn_cast<ListInit>(LHS);
1356     const auto *RHSs = dyn_cast<ListInit>(RHS);
1357     if (LHSs && RHSs) {
1358       SmallVector<const Init *, 8> Args;
1359       for (const Init *EltLHS : *LHSs) {
1360         bool Found = false;
1361         for (const Init *EltRHS : *RHSs) {
1362           if (std::optional<bool> Result = CompareInit(EQ, EltLHS, EltRHS)) {
1363             if (*Result) {
1364               Found = true;
1365               break;
1366             }
1367           }
1368         }
1369         if (!Found)
1370           Args.push_back(EltLHS);
1371       }
1372       return ListInit::get(Args, LHSs->getElementType());
1373     }
1374     break;
1375   }
1376   case LISTELEM: {
1377     const auto *TheList = dyn_cast<ListInit>(LHS);
1378     const auto *Idx = dyn_cast<IntInit>(RHS);
1379     if (!TheList || !Idx)
1380       break;
1381     auto i = Idx->getValue();
1382     if (i < 0 || i >= (ssize_t)TheList->size())
1383       break;
1384     return TheList->getElement(i);
1385   }
1386   case LISTSLICE: {
1387     const auto *TheList = dyn_cast<ListInit>(LHS);
1388     const auto *SliceIdxs = dyn_cast<ListInit>(RHS);
1389     if (!TheList || !SliceIdxs)
1390       break;
1391     SmallVector<const Init *, 8> Args;
1392     Args.reserve(SliceIdxs->size());
1393     for (auto *I : *SliceIdxs) {
1394       auto *II = dyn_cast<IntInit>(I);
1395       if (!II)
1396         goto unresolved;
1397       auto i = II->getValue();
1398       if (i < 0 || i >= (ssize_t)TheList->size())
1399         goto unresolved;
1400       Args.push_back(TheList->getElement(i));
1401     }
1402     return ListInit::get(Args, TheList->getElementType());
1403   }
1404   case RANGEC: {
1405     const auto *LHSi = dyn_cast<IntInit>(LHS);
1406     const auto *RHSi = dyn_cast<IntInit>(RHS);
1407     if (!LHSi || !RHSi)
1408       break;
1409 
1410     int64_t Start = LHSi->getValue();
1411     int64_t End = RHSi->getValue();
1412     SmallVector<const Init *, 8> Args;
1413     if (getOpcode() == RANGEC) {
1414       // Closed interval
1415       if (Start <= End) {
1416         // Ascending order
1417         Args.reserve(End - Start + 1);
1418         for (auto i = Start; i <= End; ++i)
1419           Args.push_back(IntInit::get(getRecordKeeper(), i));
1420       } else {
1421         // Descending order
1422         Args.reserve(Start - End + 1);
1423         for (auto i = Start; i >= End; --i)
1424           Args.push_back(IntInit::get(getRecordKeeper(), i));
1425       }
1426     } else if (Start < End) {
1427       // Half-open interval (excludes `End`)
1428       Args.reserve(End - Start);
1429       for (auto i = Start; i < End; ++i)
1430         Args.push_back(IntInit::get(getRecordKeeper(), i));
1431     } else {
1432       // Empty set
1433     }
1434     return ListInit::get(Args, LHSi->getType());
1435   }
1436   case STRCONCAT: {
1437     const auto *LHSs = dyn_cast<StringInit>(LHS);
1438     const auto *RHSs = dyn_cast<StringInit>(RHS);
1439     if (LHSs && RHSs)
1440       return ConcatStringInits(LHSs, RHSs);
1441     break;
1442   }
1443   case INTERLEAVE: {
1444     const auto *List = dyn_cast<ListInit>(LHS);
1445     const auto *Delim = dyn_cast<StringInit>(RHS);
1446     if (List && Delim) {
1447       const StringInit *Result;
1448       if (isa<StringRecTy>(List->getElementType()))
1449         Result = interleaveStringList(List, Delim);
1450       else
1451         Result = interleaveIntList(List, Delim);
1452       if (Result)
1453         return Result;
1454     }
1455     break;
1456   }
1457   case EQ:
1458   case NE:
1459   case LE:
1460   case LT:
1461   case GE:
1462   case GT: {
1463     if (std::optional<bool> Result = CompareInit(getOpcode(), LHS, RHS))
1464       return BitInit::get(getRecordKeeper(), *Result);
1465     break;
1466   }
1467   case GETDAGARG: {
1468     const auto *Dag = dyn_cast<DagInit>(LHS);
1469     if (Dag && isa<IntInit, StringInit>(RHS)) {
1470       std::string Error;
1471       auto ArgNo = getDagArgNoByKey(Dag, RHS, Error);
1472       if (!ArgNo)
1473         PrintFatalError(CurRec->getLoc(), "!getdagarg " + Error);
1474 
1475       assert(*ArgNo < Dag->getNumArgs());
1476 
1477       const Init *Arg = Dag->getArg(*ArgNo);
1478       if (const auto *TI = dyn_cast<TypedInit>(Arg))
1479         if (!TI->getType()->typeIsConvertibleTo(getType()))
1480           return UnsetInit::get(Dag->getRecordKeeper());
1481       return Arg;
1482     }
1483     break;
1484   }
1485   case GETDAGNAME: {
1486     const auto *Dag = dyn_cast<DagInit>(LHS);
1487     const auto *Idx = dyn_cast<IntInit>(RHS);
1488     if (Dag && Idx) {
1489       int64_t Pos = Idx->getValue();
1490       if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1491         // The index is out-of-range.
1492         PrintError(CurRec->getLoc(),
1493                    Twine("!getdagname index is out of range 0...") +
1494                        std::to_string(Dag->getNumArgs() - 1) + ": " +
1495                        std::to_string(Pos));
1496       }
1497       const Init *ArgName = Dag->getArgName(Pos);
1498       if (!ArgName)
1499         return UnsetInit::get(getRecordKeeper());
1500       return ArgName;
1501     }
1502     break;
1503   }
1504   case SETDAGOP: {
1505     const auto *Dag = dyn_cast<DagInit>(LHS);
1506     const auto *Op = dyn_cast<DefInit>(RHS);
1507     if (Dag && Op)
1508       return DagInit::get(Op, Dag->getArgs(), Dag->getArgNames());
1509     break;
1510   }
1511   case ADD:
1512   case SUB:
1513   case MUL:
1514   case DIV:
1515   case AND:
1516   case OR:
1517   case XOR:
1518   case SHL:
1519   case SRA:
1520   case SRL: {
1521     const auto *LHSi = dyn_cast_or_null<IntInit>(
1522         LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1523     const auto *RHSi = dyn_cast_or_null<IntInit>(
1524         RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
1525     if (LHSi && RHSi) {
1526       int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
1527       int64_t Result;
1528       switch (getOpcode()) {
1529       default: llvm_unreachable("Bad opcode!");
1530       case ADD: Result = LHSv + RHSv; break;
1531       case SUB: Result = LHSv - RHSv; break;
1532       case MUL: Result = LHSv * RHSv; break;
1533       case DIV:
1534         if (RHSv == 0)
1535           PrintFatalError(CurRec->getLoc(),
1536                           "Illegal operation: division by zero");
1537         else if (LHSv == INT64_MIN && RHSv == -1)
1538           PrintFatalError(CurRec->getLoc(),
1539                           "Illegal operation: INT64_MIN / -1");
1540         else
1541           Result = LHSv / RHSv;
1542         break;
1543       case AND: Result = LHSv & RHSv; break;
1544       case OR:  Result = LHSv | RHSv; break;
1545       case XOR: Result = LHSv ^ RHSv; break;
1546       case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
1547       case SRA: Result = LHSv >> RHSv; break;
1548       case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
1549       }
1550       return IntInit::get(getRecordKeeper(), Result);
1551     }
1552     break;
1553   }
1554   }
1555 unresolved:
1556   return this;
1557 }
1558 
resolveReferences(Resolver & R) const1559 const Init *BinOpInit::resolveReferences(Resolver &R) const {
1560   const Init *NewLHS = LHS->resolveReferences(R);
1561 
1562   unsigned Opc = getOpcode();
1563   if (Opc == AND || Opc == OR) {
1564     // Short-circuit. Regardless whether this is a logical or bitwise
1565     // AND/OR.
1566     // Ideally we could also short-circuit `!or(true, ...)`, but it's
1567     // difficult to do it right without knowing if rest of the operands
1568     // are all `bit` or not. Therefore, we're only implementing a relatively
1569     // limited version of short-circuit against all ones (`true` is casted
1570     // to 1 rather than all ones before we evaluate `!or`).
1571     if (const auto *LHSi = dyn_cast_or_null<IntInit>(
1572             NewLHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
1573       if ((Opc == AND && !LHSi->getValue()) ||
1574           (Opc == OR && LHSi->getValue() == -1))
1575         return LHSi;
1576     }
1577   }
1578 
1579   const Init *NewRHS = RHS->resolveReferences(R);
1580 
1581   if (LHS != NewLHS || RHS != NewRHS)
1582     return (BinOpInit::get(getOpcode(), NewLHS, NewRHS, getType()))
1583         ->Fold(R.getCurrentRecord());
1584   return this;
1585 }
1586 
getAsString() const1587 std::string BinOpInit::getAsString() const {
1588   std::string Result;
1589   switch (getOpcode()) {
1590   case LISTELEM:
1591   case LISTSLICE:
1592     return LHS->getAsString() + "[" + RHS->getAsString() + "]";
1593   case RANGEC:
1594     return LHS->getAsString() + "..." + RHS->getAsString();
1595   case CONCAT: Result = "!con"; break;
1596   case MATCH:
1597     Result = "!match";
1598     break;
1599   case ADD: Result = "!add"; break;
1600   case SUB: Result = "!sub"; break;
1601   case MUL: Result = "!mul"; break;
1602   case DIV: Result = "!div"; break;
1603   case AND: Result = "!and"; break;
1604   case OR: Result = "!or"; break;
1605   case XOR: Result = "!xor"; break;
1606   case SHL: Result = "!shl"; break;
1607   case SRA: Result = "!sra"; break;
1608   case SRL: Result = "!srl"; break;
1609   case EQ: Result = "!eq"; break;
1610   case NE: Result = "!ne"; break;
1611   case LE: Result = "!le"; break;
1612   case LT: Result = "!lt"; break;
1613   case GE: Result = "!ge"; break;
1614   case GT: Result = "!gt"; break;
1615   case LISTCONCAT: Result = "!listconcat"; break;
1616   case LISTSPLAT: Result = "!listsplat"; break;
1617   case LISTREMOVE:
1618     Result = "!listremove";
1619     break;
1620   case STRCONCAT: Result = "!strconcat"; break;
1621   case INTERLEAVE: Result = "!interleave"; break;
1622   case SETDAGOP: Result = "!setdagop"; break;
1623   case GETDAGARG:
1624     Result = "!getdagarg<" + getType()->getAsString() + ">";
1625     break;
1626   case GETDAGNAME:
1627     Result = "!getdagname";
1628     break;
1629   }
1630   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
1631 }
1632 
ProfileTernOpInit(FoldingSetNodeID & ID,unsigned Opcode,const Init * LHS,const Init * MHS,const Init * RHS,const RecTy * Type)1633 static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode,
1634                               const Init *LHS, const Init *MHS, const Init *RHS,
1635                               const RecTy *Type) {
1636   ID.AddInteger(Opcode);
1637   ID.AddPointer(LHS);
1638   ID.AddPointer(MHS);
1639   ID.AddPointer(RHS);
1640   ID.AddPointer(Type);
1641 }
1642 
get(TernaryOp Opc,const Init * LHS,const Init * MHS,const Init * RHS,const RecTy * Type)1643 const TernOpInit *TernOpInit::get(TernaryOp Opc, const Init *LHS,
1644                                   const Init *MHS, const Init *RHS,
1645                                   const RecTy *Type) {
1646   FoldingSetNodeID ID;
1647   ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
1648 
1649   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
1650   void *IP = nullptr;
1651   if (TernOpInit *I = RK.TheTernOpInitPool.FindNodeOrInsertPos(ID, IP))
1652     return I;
1653 
1654   TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
1655   RK.TheTernOpInitPool.InsertNode(I, IP);
1656   return I;
1657 }
1658 
Profile(FoldingSetNodeID & ID) const1659 void TernOpInit::Profile(FoldingSetNodeID &ID) const {
1660   ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType());
1661 }
1662 
ItemApply(const Init * LHS,const Init * MHSe,const Init * RHS,const Record * CurRec)1663 static const Init *ItemApply(const Init *LHS, const Init *MHSe, const Init *RHS,
1664                              const Record *CurRec) {
1665   MapResolver R(CurRec);
1666   R.set(LHS, MHSe);
1667   return RHS->resolveReferences(R);
1668 }
1669 
ForeachDagApply(const Init * LHS,const DagInit * MHSd,const Init * RHS,const Record * CurRec)1670 static const Init *ForeachDagApply(const Init *LHS, const DagInit *MHSd,
1671                                    const Init *RHS, const Record *CurRec) {
1672   bool Change = false;
1673   const Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
1674   if (Val != MHSd->getOperator())
1675     Change = true;
1676 
1677   SmallVector<std::pair<const Init *, const StringInit *>, 8> NewArgs;
1678   for (auto [Arg, ArgName] : MHSd->getArgAndNames()) {
1679     const Init *NewArg;
1680 
1681     if (const auto *Argd = dyn_cast<DagInit>(Arg))
1682       NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec);
1683     else
1684       NewArg = ItemApply(LHS, Arg, RHS, CurRec);
1685 
1686     NewArgs.emplace_back(NewArg, ArgName);
1687     if (Arg != NewArg)
1688       Change = true;
1689   }
1690 
1691   if (Change)
1692     return DagInit::get(Val, MHSd->getName(), NewArgs);
1693   return MHSd;
1694 }
1695 
1696 // Applies RHS to all elements of MHS, using LHS as a temp variable.
ForeachHelper(const Init * LHS,const Init * MHS,const Init * RHS,const RecTy * Type,const Record * CurRec)1697 static const Init *ForeachHelper(const Init *LHS, const Init *MHS,
1698                                  const Init *RHS, const RecTy *Type,
1699                                  const Record *CurRec) {
1700   if (const auto *MHSd = dyn_cast<DagInit>(MHS))
1701     return ForeachDagApply(LHS, MHSd, RHS, CurRec);
1702 
1703   if (const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1704     SmallVector<const Init *, 8> NewList(MHSl->begin(), MHSl->end());
1705 
1706     for (const Init *&Item : NewList) {
1707       const Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
1708       if (NewItem != Item)
1709         Item = NewItem;
1710     }
1711     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
1712   }
1713 
1714   return nullptr;
1715 }
1716 
1717 // Evaluates RHS for all elements of MHS, using LHS as a temp variable.
1718 // Creates a new list with the elements that evaluated to true.
FilterHelper(const Init * LHS,const Init * MHS,const Init * RHS,const RecTy * Type,const Record * CurRec)1719 static const Init *FilterHelper(const Init *LHS, const Init *MHS,
1720                                 const Init *RHS, const RecTy *Type,
1721                                 const Record *CurRec) {
1722   if (const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1723     SmallVector<const Init *, 8> NewList;
1724 
1725     for (const Init *Item : MHSl->getElements()) {
1726       const Init *Include = ItemApply(LHS, Item, RHS, CurRec);
1727       if (!Include)
1728         return nullptr;
1729       if (const auto *IncludeInt =
1730               dyn_cast_or_null<IntInit>(Include->convertInitializerTo(
1731                   IntRecTy::get(LHS->getRecordKeeper())))) {
1732         if (IncludeInt->getValue())
1733           NewList.push_back(Item);
1734       } else {
1735         return nullptr;
1736       }
1737     }
1738     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
1739   }
1740 
1741   return nullptr;
1742 }
1743 
Fold(const Record * CurRec) const1744 const Init *TernOpInit::Fold(const Record *CurRec) const {
1745   RecordKeeper &RK = getRecordKeeper();
1746   switch (getOpcode()) {
1747   case SUBST: {
1748     const auto *LHSd = dyn_cast<DefInit>(LHS);
1749     const auto *LHSv = dyn_cast<VarInit>(LHS);
1750     const auto *LHSs = dyn_cast<StringInit>(LHS);
1751 
1752     const auto *MHSd = dyn_cast<DefInit>(MHS);
1753     const auto *MHSv = dyn_cast<VarInit>(MHS);
1754     const auto *MHSs = dyn_cast<StringInit>(MHS);
1755 
1756     const auto *RHSd = dyn_cast<DefInit>(RHS);
1757     const auto *RHSv = dyn_cast<VarInit>(RHS);
1758     const auto *RHSs = dyn_cast<StringInit>(RHS);
1759 
1760     if (LHSd && MHSd && RHSd) {
1761       const Record *Val = RHSd->getDef();
1762       if (LHSd->getAsString() == RHSd->getAsString())
1763         Val = MHSd->getDef();
1764       return Val->getDefInit();
1765     }
1766     if (LHSv && MHSv && RHSv) {
1767       std::string Val = RHSv->getName().str();
1768       if (LHSv->getAsString() == RHSv->getAsString())
1769         Val = MHSv->getName().str();
1770       return VarInit::get(Val, getType());
1771     }
1772     if (LHSs && MHSs && RHSs) {
1773       std::string Val = RHSs->getValue().str();
1774 
1775       std::string::size_type Idx = 0;
1776       while (true) {
1777         std::string::size_type Found = Val.find(LHSs->getValue(), Idx);
1778         if (Found == std::string::npos)
1779           break;
1780         Val.replace(Found, LHSs->getValue().size(), MHSs->getValue().str());
1781         Idx = Found + MHSs->getValue().size();
1782       }
1783 
1784       return StringInit::get(RK, Val);
1785     }
1786     break;
1787   }
1788 
1789   case FOREACH: {
1790     if (const Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec))
1791       return Result;
1792     break;
1793   }
1794 
1795   case FILTER: {
1796     if (const Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
1797       return Result;
1798     break;
1799   }
1800 
1801   case IF: {
1802     if (const auto *LHSi = dyn_cast_or_null<IntInit>(
1803             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
1804       if (LHSi->getValue())
1805         return MHS;
1806       return RHS;
1807     }
1808     break;
1809   }
1810 
1811   case DAG: {
1812     const auto *MHSl = dyn_cast<ListInit>(MHS);
1813     const auto *RHSl = dyn_cast<ListInit>(RHS);
1814     bool MHSok = MHSl || isa<UnsetInit>(MHS);
1815     bool RHSok = RHSl || isa<UnsetInit>(RHS);
1816 
1817     if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1818       break; // Typically prevented by the parser, but might happen with template args
1819 
1820     if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
1821       SmallVector<std::pair<const Init *, const StringInit *>, 8> Children;
1822       unsigned Size = MHSl ? MHSl->size() : RHSl->size();
1823       for (unsigned i = 0; i != Size; ++i) {
1824         const Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK);
1825         const Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK);
1826         if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
1827           return this;
1828         Children.emplace_back(Node, dyn_cast<StringInit>(Name));
1829       }
1830       return DagInit::get(LHS, Children);
1831     }
1832     break;
1833   }
1834 
1835   case RANGE: {
1836     const auto *LHSi = dyn_cast<IntInit>(LHS);
1837     const auto *MHSi = dyn_cast<IntInit>(MHS);
1838     const auto *RHSi = dyn_cast<IntInit>(RHS);
1839     if (!LHSi || !MHSi || !RHSi)
1840       break;
1841 
1842     auto Start = LHSi->getValue();
1843     auto End = MHSi->getValue();
1844     auto Step = RHSi->getValue();
1845     if (Step == 0)
1846       PrintError(CurRec->getLoc(), "Step of !range can't be 0");
1847 
1848     SmallVector<const Init *, 8> Args;
1849     if (Start < End && Step > 0) {
1850       Args.reserve((End - Start) / Step);
1851       for (auto I = Start; I < End; I += Step)
1852         Args.push_back(IntInit::get(getRecordKeeper(), I));
1853     } else if (Start > End && Step < 0) {
1854       Args.reserve((Start - End) / -Step);
1855       for (auto I = Start; I > End; I += Step)
1856         Args.push_back(IntInit::get(getRecordKeeper(), I));
1857     } else {
1858       // Empty set
1859     }
1860     return ListInit::get(Args, LHSi->getType());
1861   }
1862 
1863   case SUBSTR: {
1864     const auto *LHSs = dyn_cast<StringInit>(LHS);
1865     const auto *MHSi = dyn_cast<IntInit>(MHS);
1866     const auto *RHSi = dyn_cast<IntInit>(RHS);
1867     if (LHSs && MHSi && RHSi) {
1868       int64_t StringSize = LHSs->getValue().size();
1869       int64_t Start = MHSi->getValue();
1870       int64_t Length = RHSi->getValue();
1871       if (Start < 0 || Start > StringSize)
1872         PrintError(CurRec->getLoc(),
1873                    Twine("!substr start position is out of range 0...") +
1874                        std::to_string(StringSize) + ": " +
1875                        std::to_string(Start));
1876       if (Length < 0)
1877         PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
1878       return StringInit::get(RK, LHSs->getValue().substr(Start, Length),
1879                              LHSs->getFormat());
1880     }
1881     break;
1882   }
1883 
1884   case FIND: {
1885     const auto *LHSs = dyn_cast<StringInit>(LHS);
1886     const auto *MHSs = dyn_cast<StringInit>(MHS);
1887     const auto *RHSi = dyn_cast<IntInit>(RHS);
1888     if (LHSs && MHSs && RHSi) {
1889       int64_t SourceSize = LHSs->getValue().size();
1890       int64_t Start = RHSi->getValue();
1891       if (Start < 0 || Start > SourceSize)
1892         PrintError(CurRec->getLoc(),
1893                    Twine("!find start position is out of range 0...") +
1894                        std::to_string(SourceSize) + ": " +
1895                        std::to_string(Start));
1896       auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1897       if (I == std::string::npos)
1898         return IntInit::get(RK, -1);
1899       return IntInit::get(RK, I);
1900     }
1901     break;
1902   }
1903 
1904   case SETDAGARG: {
1905     const auto *Dag = dyn_cast<DagInit>(LHS);
1906     if (Dag && isa<IntInit, StringInit>(MHS)) {
1907       std::string Error;
1908       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
1909       if (!ArgNo)
1910         PrintFatalError(CurRec->getLoc(), "!setdagarg " + Error);
1911 
1912       assert(*ArgNo < Dag->getNumArgs());
1913 
1914       SmallVector<const Init *, 8> Args(Dag->getArgs());
1915       Args[*ArgNo] = RHS;
1916       return DagInit::get(Dag->getOperator(), Dag->getName(), Args,
1917                           Dag->getArgNames());
1918     }
1919     break;
1920   }
1921 
1922   case SETDAGNAME: {
1923     const auto *Dag = dyn_cast<DagInit>(LHS);
1924     if (Dag && isa<IntInit, StringInit>(MHS)) {
1925       std::string Error;
1926       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
1927       if (!ArgNo)
1928         PrintFatalError(CurRec->getLoc(), "!setdagname " + Error);
1929 
1930       assert(*ArgNo < Dag->getNumArgs());
1931 
1932       SmallVector<const StringInit *, 8> Names(Dag->getArgNames());
1933       Names[*ArgNo] = dyn_cast<StringInit>(RHS);
1934       return DagInit::get(Dag->getOperator(), Dag->getName(), Dag->getArgs(),
1935                           Names);
1936     }
1937     break;
1938   }
1939   }
1940 
1941   return this;
1942 }
1943 
resolveReferences(Resolver & R) const1944 const Init *TernOpInit::resolveReferences(Resolver &R) const {
1945   const Init *lhs = LHS->resolveReferences(R);
1946 
1947   if (getOpcode() == IF && lhs != LHS) {
1948     if (const auto *Value = dyn_cast_or_null<IntInit>(
1949             lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
1950       // Short-circuit
1951       if (Value->getValue())
1952         return MHS->resolveReferences(R);
1953       return RHS->resolveReferences(R);
1954     }
1955   }
1956 
1957   const Init *mhs = MHS->resolveReferences(R);
1958   const Init *rhs;
1959 
1960   if (getOpcode() == FOREACH || getOpcode() == FILTER) {
1961     ShadowResolver SR(R);
1962     SR.addShadow(lhs);
1963     rhs = RHS->resolveReferences(SR);
1964   } else {
1965     rhs = RHS->resolveReferences(R);
1966   }
1967 
1968   if (LHS != lhs || MHS != mhs || RHS != rhs)
1969     return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType()))
1970         ->Fold(R.getCurrentRecord());
1971   return this;
1972 }
1973 
getAsString() const1974 std::string TernOpInit::getAsString() const {
1975   std::string Result;
1976   bool UnquotedLHS = false;
1977   switch (getOpcode()) {
1978   case DAG: Result = "!dag"; break;
1979   case FILTER: Result = "!filter"; UnquotedLHS = true; break;
1980   case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
1981   case IF: Result = "!if"; break;
1982   case RANGE:
1983     Result = "!range";
1984     break;
1985   case SUBST: Result = "!subst"; break;
1986   case SUBSTR: Result = "!substr"; break;
1987   case FIND: Result = "!find"; break;
1988   case SETDAGARG:
1989     Result = "!setdagarg";
1990     break;
1991   case SETDAGNAME:
1992     Result = "!setdagname";
1993     break;
1994   }
1995   return (Result + "(" +
1996           (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
1997           ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")");
1998 }
1999 
ProfileFoldOpInit(FoldingSetNodeID & ID,const Init * Start,const Init * List,const Init * A,const Init * B,const Init * Expr,const RecTy * Type)2000 static void ProfileFoldOpInit(FoldingSetNodeID &ID, const Init *Start,
2001                               const Init *List, const Init *A, const Init *B,
2002                               const Init *Expr, const RecTy *Type) {
2003   ID.AddPointer(Start);
2004   ID.AddPointer(List);
2005   ID.AddPointer(A);
2006   ID.AddPointer(B);
2007   ID.AddPointer(Expr);
2008   ID.AddPointer(Type);
2009 }
2010 
get(const Init * Start,const Init * List,const Init * A,const Init * B,const Init * Expr,const RecTy * Type)2011 const FoldOpInit *FoldOpInit::get(const Init *Start, const Init *List,
2012                                   const Init *A, const Init *B,
2013                                   const Init *Expr, const RecTy *Type) {
2014   FoldingSetNodeID ID;
2015   ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
2016 
2017   detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl();
2018   void *IP = nullptr;
2019   if (const FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
2020     return I;
2021 
2022   FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
2023   RK.TheFoldOpInitPool.InsertNode(I, IP);
2024   return I;
2025 }
2026 
Profile(FoldingSetNodeID & ID) const2027 void FoldOpInit::Profile(FoldingSetNodeID &ID) const {
2028   ProfileFoldOpInit(ID, Start, List, A, B, Expr, getType());
2029 }
2030 
Fold(const Record * CurRec) const2031 const Init *FoldOpInit::Fold(const Record *CurRec) const {
2032   if (const auto *LI = dyn_cast<ListInit>(List)) {
2033     const Init *Accum = Start;
2034     for (const Init *Elt : *LI) {
2035       MapResolver R(CurRec);
2036       R.set(A, Accum);
2037       R.set(B, Elt);
2038       Accum = Expr->resolveReferences(R);
2039     }
2040     return Accum;
2041   }
2042   return this;
2043 }
2044 
resolveReferences(Resolver & R) const2045 const Init *FoldOpInit::resolveReferences(Resolver &R) const {
2046   const Init *NewStart = Start->resolveReferences(R);
2047   const Init *NewList = List->resolveReferences(R);
2048   ShadowResolver SR(R);
2049   SR.addShadow(A);
2050   SR.addShadow(B);
2051   const Init *NewExpr = Expr->resolveReferences(SR);
2052 
2053   if (Start == NewStart && List == NewList && Expr == NewExpr)
2054     return this;
2055 
2056   return get(NewStart, NewList, A, B, NewExpr, getType())
2057       ->Fold(R.getCurrentRecord());
2058 }
2059 
getBit(unsigned Bit) const2060 const Init *FoldOpInit::getBit(unsigned Bit) const {
2061   return VarBitInit::get(this, Bit);
2062 }
2063 
getAsString() const2064 std::string FoldOpInit::getAsString() const {
2065   return (Twine("!foldl(") + Start->getAsString() + ", " + List->getAsString() +
2066           ", " + A->getAsUnquotedString() + ", " + B->getAsUnquotedString() +
2067           ", " + Expr->getAsString() + ")")
2068       .str();
2069 }
2070 
ProfileIsAOpInit(FoldingSetNodeID & ID,const RecTy * CheckType,const Init * Expr)2071 static void ProfileIsAOpInit(FoldingSetNodeID &ID, const RecTy *CheckType,
2072                              const Init *Expr) {
2073   ID.AddPointer(CheckType);
2074   ID.AddPointer(Expr);
2075 }
2076 
get(const RecTy * CheckType,const Init * Expr)2077 const IsAOpInit *IsAOpInit::get(const RecTy *CheckType, const Init *Expr) {
2078 
2079   FoldingSetNodeID ID;
2080   ProfileIsAOpInit(ID, CheckType, Expr);
2081 
2082   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
2083   void *IP = nullptr;
2084   if (const IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
2085     return I;
2086 
2087   IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);
2088   RK.TheIsAOpInitPool.InsertNode(I, IP);
2089   return I;
2090 }
2091 
Profile(FoldingSetNodeID & ID) const2092 void IsAOpInit::Profile(FoldingSetNodeID &ID) const {
2093   ProfileIsAOpInit(ID, CheckType, Expr);
2094 }
2095 
Fold() const2096 const Init *IsAOpInit::Fold() const {
2097   if (const auto *TI = dyn_cast<TypedInit>(Expr)) {
2098     // Is the expression type known to be (a subclass of) the desired type?
2099     if (TI->getType()->typeIsConvertibleTo(CheckType))
2100       return IntInit::get(getRecordKeeper(), 1);
2101 
2102     if (isa<RecordRecTy>(CheckType)) {
2103       // If the target type is not a subclass of the expression type once the
2104       // expression has been made concrete, or if the expression has fully
2105       // resolved to a record, we know that it can't be of the required type.
2106       if ((!CheckType->typeIsConvertibleTo(TI->getType()) &&
2107            Expr->isConcrete()) ||
2108           isa<DefInit>(Expr))
2109         return IntInit::get(getRecordKeeper(), 0);
2110     } else {
2111       // We treat non-record types as not castable.
2112       return IntInit::get(getRecordKeeper(), 0);
2113     }
2114   }
2115   return this;
2116 }
2117 
resolveReferences(Resolver & R) const2118 const Init *IsAOpInit::resolveReferences(Resolver &R) const {
2119   const Init *NewExpr = Expr->resolveReferences(R);
2120   if (Expr != NewExpr)
2121     return get(CheckType, NewExpr)->Fold();
2122   return this;
2123 }
2124 
getBit(unsigned Bit) const2125 const Init *IsAOpInit::getBit(unsigned Bit) const {
2126   return VarBitInit::get(this, Bit);
2127 }
2128 
getAsString() const2129 std::string IsAOpInit::getAsString() const {
2130   return (Twine("!isa<") + CheckType->getAsString() + ">(" +
2131           Expr->getAsString() + ")")
2132       .str();
2133 }
2134 
ProfileExistsOpInit(FoldingSetNodeID & ID,const RecTy * CheckType,const Init * Expr)2135 static void ProfileExistsOpInit(FoldingSetNodeID &ID, const RecTy *CheckType,
2136                                 const Init *Expr) {
2137   ID.AddPointer(CheckType);
2138   ID.AddPointer(Expr);
2139 }
2140 
get(const RecTy * CheckType,const Init * Expr)2141 const ExistsOpInit *ExistsOpInit::get(const RecTy *CheckType,
2142                                       const Init *Expr) {
2143   FoldingSetNodeID ID;
2144   ProfileExistsOpInit(ID, CheckType, Expr);
2145 
2146   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
2147   void *IP = nullptr;
2148   if (const ExistsOpInit *I =
2149           RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
2150     return I;
2151 
2152   ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);
2153   RK.TheExistsOpInitPool.InsertNode(I, IP);
2154   return I;
2155 }
2156 
Profile(FoldingSetNodeID & ID) const2157 void ExistsOpInit::Profile(FoldingSetNodeID &ID) const {
2158   ProfileExistsOpInit(ID, CheckType, Expr);
2159 }
2160 
Fold(const Record * CurRec,bool IsFinal) const2161 const Init *ExistsOpInit::Fold(const Record *CurRec, bool IsFinal) const {
2162   if (const auto *Name = dyn_cast<StringInit>(Expr)) {
2163     // Look up all defined records to see if we can find one.
2164     const Record *D = CheckType->getRecordKeeper().getDef(Name->getValue());
2165     if (D) {
2166       // Check if types are compatible.
2167       return IntInit::get(getRecordKeeper(),
2168                           D->getDefInit()->getType()->typeIsA(CheckType));
2169     }
2170 
2171     if (CurRec) {
2172       // Self-references are allowed, but their resolution is delayed until
2173       // the final resolve to ensure that we get the correct type for them.
2174       auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
2175       if (Name == CurRec->getNameInit() ||
2176           (Anonymous && Name == Anonymous->getNameInit())) {
2177         if (!IsFinal)
2178           return this;
2179 
2180         // No doubt that there exists a record, so we should check if types are
2181         // compatible.
2182         return IntInit::get(getRecordKeeper(),
2183                             CurRec->getType()->typeIsA(CheckType));
2184       }
2185     }
2186 
2187     if (IsFinal)
2188       return IntInit::get(getRecordKeeper(), 0);
2189   }
2190   return this;
2191 }
2192 
resolveReferences(Resolver & R) const2193 const Init *ExistsOpInit::resolveReferences(Resolver &R) const {
2194   const Init *NewExpr = Expr->resolveReferences(R);
2195   if (Expr != NewExpr || R.isFinal())
2196     return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal());
2197   return this;
2198 }
2199 
getBit(unsigned Bit) const2200 const Init *ExistsOpInit::getBit(unsigned Bit) const {
2201   return VarBitInit::get(this, Bit);
2202 }
2203 
getAsString() const2204 std::string ExistsOpInit::getAsString() const {
2205   return (Twine("!exists<") + CheckType->getAsString() + ">(" +
2206           Expr->getAsString() + ")")
2207       .str();
2208 }
2209 
ProfileInstancesOpInit(FoldingSetNodeID & ID,const RecTy * Type,const Init * Regex)2210 static void ProfileInstancesOpInit(FoldingSetNodeID &ID, const RecTy *Type,
2211                                    const Init *Regex) {
2212   ID.AddPointer(Type);
2213   ID.AddPointer(Regex);
2214 }
2215 
get(const RecTy * Type,const Init * Regex)2216 const InstancesOpInit *InstancesOpInit::get(const RecTy *Type,
2217                                             const Init *Regex) {
2218   FoldingSetNodeID ID;
2219   ProfileInstancesOpInit(ID, Type, Regex);
2220 
2221   detail::RecordKeeperImpl &RK = Regex->getRecordKeeper().getImpl();
2222   void *IP = nullptr;
2223   if (const InstancesOpInit *I =
2224           RK.TheInstancesOpInitPool.FindNodeOrInsertPos(ID, IP))
2225     return I;
2226 
2227   InstancesOpInit *I = new (RK.Allocator) InstancesOpInit(Type, Regex);
2228   RK.TheInstancesOpInitPool.InsertNode(I, IP);
2229   return I;
2230 }
2231 
Profile(FoldingSetNodeID & ID) const2232 void InstancesOpInit::Profile(FoldingSetNodeID &ID) const {
2233   ProfileInstancesOpInit(ID, Type, Regex);
2234 }
2235 
Fold(const Record * CurRec,bool IsFinal) const2236 const Init *InstancesOpInit::Fold(const Record *CurRec, bool IsFinal) const {
2237   if (CurRec && !IsFinal)
2238     return this;
2239 
2240   const auto *RegexInit = dyn_cast<StringInit>(Regex);
2241   if (!RegexInit)
2242     return this;
2243 
2244   StringRef RegexStr = RegexInit->getValue();
2245   llvm::Regex Matcher(RegexStr);
2246   if (!Matcher.isValid())
2247     PrintFatalError(Twine("invalid regex '") + RegexStr + Twine("'"));
2248 
2249   const RecordKeeper &RK = Type->getRecordKeeper();
2250   SmallVector<Init *, 8> Selected;
2251   for (auto &Def : RK.getAllDerivedDefinitionsIfDefined(Type->getAsString()))
2252     if (Matcher.match(Def->getName()))
2253       Selected.push_back(Def->getDefInit());
2254 
2255   return ListInit::get(Selected, Type);
2256 }
2257 
resolveReferences(Resolver & R) const2258 const Init *InstancesOpInit::resolveReferences(Resolver &R) const {
2259   const Init *NewRegex = Regex->resolveReferences(R);
2260   if (Regex != NewRegex || R.isFinal())
2261     return get(Type, NewRegex)->Fold(R.getCurrentRecord(), R.isFinal());
2262   return this;
2263 }
2264 
getBit(unsigned Bit) const2265 const Init *InstancesOpInit::getBit(unsigned Bit) const {
2266   return VarBitInit::get(this, Bit);
2267 }
2268 
getAsString() const2269 std::string InstancesOpInit::getAsString() const {
2270   return "!instances<" + Type->getAsString() + ">(" + Regex->getAsString() +
2271          ")";
2272 }
2273 
getFieldType(const StringInit * FieldName) const2274 const RecTy *TypedInit::getFieldType(const StringInit *FieldName) const {
2275   if (const auto *RecordType = dyn_cast<RecordRecTy>(getType())) {
2276     for (const Record *Rec : RecordType->getClasses()) {
2277       if (const RecordVal *Field = Rec->getValue(FieldName))
2278         return Field->getType();
2279     }
2280   }
2281   return nullptr;
2282 }
2283 
convertInitializerTo(const RecTy * Ty) const2284 const Init *TypedInit::convertInitializerTo(const RecTy *Ty) const {
2285   if (getType() == Ty || getType()->typeIsA(Ty))
2286     return this;
2287 
2288   if (isa<BitRecTy>(getType()) && isa<BitsRecTy>(Ty) &&
2289       cast<BitsRecTy>(Ty)->getNumBits() == 1)
2290     return BitsInit::get(getRecordKeeper(), {this});
2291 
2292   return nullptr;
2293 }
2294 
2295 const Init *
convertInitializerBitRange(ArrayRef<unsigned> Bits) const2296 TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
2297   const auto *T = dyn_cast<BitsRecTy>(getType());
2298   if (!T) return nullptr;  // Cannot subscript a non-bits variable.
2299   unsigned NumBits = T->getNumBits();
2300 
2301   SmallVector<const Init *, 16> NewBits;
2302   NewBits.reserve(Bits.size());
2303   for (unsigned Bit : Bits) {
2304     if (Bit >= NumBits)
2305       return nullptr;
2306 
2307     NewBits.push_back(VarBitInit::get(this, Bit));
2308   }
2309   return BitsInit::get(getRecordKeeper(), NewBits);
2310 }
2311 
getCastTo(const RecTy * Ty) const2312 const Init *TypedInit::getCastTo(const RecTy *Ty) const {
2313   // Handle the common case quickly
2314   if (getType() == Ty || getType()->typeIsA(Ty))
2315     return this;
2316 
2317   if (const Init *Converted = convertInitializerTo(Ty)) {
2318     assert(!isa<TypedInit>(Converted) ||
2319            cast<TypedInit>(Converted)->getType()->typeIsA(Ty));
2320     return Converted;
2321   }
2322 
2323   if (!getType()->typeIsConvertibleTo(Ty))
2324     return nullptr;
2325 
2326   return UnOpInit::get(UnOpInit::CAST, this, Ty)->Fold(nullptr);
2327 }
2328 
get(StringRef VN,const RecTy * T)2329 const VarInit *VarInit::get(StringRef VN, const RecTy *T) {
2330   const Init *Value = StringInit::get(T->getRecordKeeper(), VN);
2331   return VarInit::get(Value, T);
2332 }
2333 
get(const Init * VN,const RecTy * T)2334 const VarInit *VarInit::get(const Init *VN, const RecTy *T) {
2335   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
2336   VarInit *&I = RK.TheVarInitPool[{T, VN}];
2337   if (!I)
2338     I = new (RK.Allocator) VarInit(VN, T);
2339   return I;
2340 }
2341 
getName() const2342 StringRef VarInit::getName() const {
2343   const auto *NameString = cast<StringInit>(getNameInit());
2344   return NameString->getValue();
2345 }
2346 
getBit(unsigned Bit) const2347 const Init *VarInit::getBit(unsigned Bit) const {
2348   if (getType() == BitRecTy::get(getRecordKeeper()))
2349     return this;
2350   return VarBitInit::get(this, Bit);
2351 }
2352 
resolveReferences(Resolver & R) const2353 const Init *VarInit::resolveReferences(Resolver &R) const {
2354   if (const Init *Val = R.resolve(VarName))
2355     return Val;
2356   return this;
2357 }
2358 
get(const TypedInit * T,unsigned B)2359 const VarBitInit *VarBitInit::get(const TypedInit *T, unsigned B) {
2360   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
2361   VarBitInit *&I = RK.TheVarBitInitPool[{T, B}];
2362   if (!I)
2363     I = new (RK.Allocator) VarBitInit(T, B);
2364   return I;
2365 }
2366 
getAsString() const2367 std::string VarBitInit::getAsString() const {
2368   return TI->getAsString() + "{" + utostr(Bit) + "}";
2369 }
2370 
resolveReferences(Resolver & R) const2371 const Init *VarBitInit::resolveReferences(Resolver &R) const {
2372   const Init *I = TI->resolveReferences(R);
2373   if (TI != I)
2374     return I->getBit(getBitNum());
2375 
2376   return this;
2377 }
2378 
DefInit(const Record * D)2379 DefInit::DefInit(const Record *D)
2380     : TypedInit(IK_DefInit, D->getType()), Def(D) {}
2381 
convertInitializerTo(const RecTy * Ty) const2382 const Init *DefInit::convertInitializerTo(const RecTy *Ty) const {
2383   if (auto *RRT = dyn_cast<RecordRecTy>(Ty))
2384     if (getType()->typeIsConvertibleTo(RRT))
2385       return this;
2386   return nullptr;
2387 }
2388 
getFieldType(const StringInit * FieldName) const2389 const RecTy *DefInit::getFieldType(const StringInit *FieldName) const {
2390   if (const RecordVal *RV = Def->getValue(FieldName))
2391     return RV->getType();
2392   return nullptr;
2393 }
2394 
getAsString() const2395 std::string DefInit::getAsString() const { return Def->getName().str(); }
2396 
ProfileVarDefInit(FoldingSetNodeID & ID,const Record * Class,ArrayRef<const ArgumentInit * > Args)2397 static void ProfileVarDefInit(FoldingSetNodeID &ID, const Record *Class,
2398                               ArrayRef<const ArgumentInit *> Args) {
2399   ID.AddInteger(Args.size());
2400   ID.AddPointer(Class);
2401 
2402   for (const Init *I : Args)
2403     ID.AddPointer(I);
2404 }
2405 
VarDefInit(SMLoc Loc,const Record * Class,ArrayRef<const ArgumentInit * > Args)2406 VarDefInit::VarDefInit(SMLoc Loc, const Record *Class,
2407                        ArrayRef<const ArgumentInit *> Args)
2408     : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Loc(Loc), Class(Class),
2409       NumArgs(Args.size()) {
2410   llvm::uninitialized_copy(Args, getTrailingObjects());
2411 }
2412 
get(SMLoc Loc,const Record * Class,ArrayRef<const ArgumentInit * > Args)2413 const VarDefInit *VarDefInit::get(SMLoc Loc, const Record *Class,
2414                                   ArrayRef<const ArgumentInit *> Args) {
2415   FoldingSetNodeID ID;
2416   ProfileVarDefInit(ID, Class, Args);
2417 
2418   detail::RecordKeeperImpl &RK = Class->getRecords().getImpl();
2419   void *IP = nullptr;
2420   if (const VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
2421     return I;
2422 
2423   void *Mem = RK.Allocator.Allocate(
2424       totalSizeToAlloc<const ArgumentInit *>(Args.size()), alignof(VarDefInit));
2425   VarDefInit *I = new (Mem) VarDefInit(Loc, Class, Args);
2426   RK.TheVarDefInitPool.InsertNode(I, IP);
2427   return I;
2428 }
2429 
Profile(FoldingSetNodeID & ID) const2430 void VarDefInit::Profile(FoldingSetNodeID &ID) const {
2431   ProfileVarDefInit(ID, Class, args());
2432 }
2433 
instantiate()2434 const DefInit *VarDefInit::instantiate() {
2435   if (Def)
2436     return Def;
2437 
2438   RecordKeeper &Records = Class->getRecords();
2439   auto NewRecOwner = std::make_unique<Record>(
2440       Records.getNewAnonymousName(), Loc, Records, Record::RK_AnonymousDef);
2441   Record *NewRec = NewRecOwner.get();
2442 
2443   // Copy values from class to instance
2444   for (const RecordVal &Val : Class->getValues())
2445     NewRec->addValue(Val);
2446 
2447   // Copy assertions from class to instance.
2448   NewRec->appendAssertions(Class);
2449 
2450   // Copy dumps from class to instance.
2451   NewRec->appendDumps(Class);
2452 
2453   // Substitute and resolve template arguments
2454   ArrayRef<const Init *> TArgs = Class->getTemplateArgs();
2455   MapResolver R(NewRec);
2456 
2457   for (const Init *Arg : TArgs) {
2458     R.set(Arg, NewRec->getValue(Arg)->getValue());
2459     NewRec->removeValue(Arg);
2460   }
2461 
2462   for (auto *Arg : args()) {
2463     if (Arg->isPositional())
2464       R.set(TArgs[Arg->getIndex()], Arg->getValue());
2465     if (Arg->isNamed())
2466       R.set(Arg->getName(), Arg->getValue());
2467   }
2468 
2469   NewRec->resolveReferences(R);
2470 
2471   // Add superclass.
2472   NewRec->addDirectSuperClass(
2473       Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
2474 
2475   // Resolve internal references and store in record keeper
2476   NewRec->resolveReferences();
2477   Records.addDef(std::move(NewRecOwner));
2478 
2479   // Check the assertions.
2480   NewRec->checkRecordAssertions();
2481 
2482   // Check the assertions.
2483   NewRec->emitRecordDumps();
2484 
2485   return Def = NewRec->getDefInit();
2486 }
2487 
resolveReferences(Resolver & R) const2488 const Init *VarDefInit::resolveReferences(Resolver &R) const {
2489   TrackUnresolvedResolver UR(&R);
2490   bool Changed = false;
2491   SmallVector<const ArgumentInit *, 8> NewArgs;
2492   NewArgs.reserve(args_size());
2493 
2494   for (const ArgumentInit *Arg : args()) {
2495     const auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
2496     NewArgs.push_back(NewArg);
2497     Changed |= NewArg != Arg;
2498   }
2499 
2500   if (Changed) {
2501     auto *New = VarDefInit::get(Loc, Class, NewArgs);
2502     if (!UR.foundUnresolved())
2503       return const_cast<VarDefInit *>(New)->instantiate();
2504     return New;
2505   }
2506   return this;
2507 }
2508 
Fold() const2509 const Init *VarDefInit::Fold() const {
2510   if (Def)
2511     return Def;
2512 
2513   TrackUnresolvedResolver R;
2514   for (const Init *Arg : args())
2515     Arg->resolveReferences(R);
2516 
2517   if (!R.foundUnresolved())
2518     return const_cast<VarDefInit *>(this)->instantiate();
2519   return this;
2520 }
2521 
getAsString() const2522 std::string VarDefInit::getAsString() const {
2523   std::string Result = Class->getNameInitAsString() + "<";
2524   ListSeparator LS;
2525   for (const Init *Arg : args()) {
2526     Result += LS;
2527     Result += Arg->getAsString();
2528   }
2529   return Result + ">";
2530 }
2531 
get(const Init * R,const StringInit * FN)2532 const FieldInit *FieldInit::get(const Init *R, const StringInit *FN) {
2533   detail::RecordKeeperImpl &RK = R->getRecordKeeper().getImpl();
2534   FieldInit *&I = RK.TheFieldInitPool[{R, FN}];
2535   if (!I)
2536     I = new (RK.Allocator) FieldInit(R, FN);
2537   return I;
2538 }
2539 
getBit(unsigned Bit) const2540 const Init *FieldInit::getBit(unsigned Bit) const {
2541   if (getType() == BitRecTy::get(getRecordKeeper()))
2542     return this;
2543   return VarBitInit::get(this, Bit);
2544 }
2545 
resolveReferences(Resolver & R) const2546 const Init *FieldInit::resolveReferences(Resolver &R) const {
2547   const Init *NewRec = Rec->resolveReferences(R);
2548   if (NewRec != Rec)
2549     return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());
2550   return this;
2551 }
2552 
Fold(const Record * CurRec) const2553 const Init *FieldInit::Fold(const Record *CurRec) const {
2554   if (const auto *DI = dyn_cast<DefInit>(Rec)) {
2555     const Record *Def = DI->getDef();
2556     if (Def == CurRec)
2557       PrintFatalError(CurRec->getLoc(),
2558                       Twine("Attempting to access field '") +
2559                       FieldName->getAsUnquotedString() + "' of '" +
2560                       Rec->getAsString() + "' is a forbidden self-reference");
2561     const Init *FieldVal = Def->getValue(FieldName)->getValue();
2562     if (FieldVal->isConcrete())
2563       return FieldVal;
2564   }
2565   return this;
2566 }
2567 
isConcrete() const2568 bool FieldInit::isConcrete() const {
2569   if (const auto *DI = dyn_cast<DefInit>(Rec)) {
2570     const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2571     return FieldVal->isConcrete();
2572   }
2573   return false;
2574 }
2575 
ProfileCondOpInit(FoldingSetNodeID & ID,ArrayRef<const Init * > Conds,ArrayRef<const Init * > Vals,const RecTy * ValType)2576 static void ProfileCondOpInit(FoldingSetNodeID &ID,
2577                               ArrayRef<const Init *> Conds,
2578                               ArrayRef<const Init *> Vals,
2579                               const RecTy *ValType) {
2580   assert(Conds.size() == Vals.size() &&
2581          "Number of conditions and values must match!");
2582   ID.AddPointer(ValType);
2583 
2584   for (const auto &[Cond, Val] : zip(Conds, Vals)) {
2585     ID.AddPointer(Cond);
2586     ID.AddPointer(Val);
2587   }
2588 }
2589 
CondOpInit(ArrayRef<const Init * > Conds,ArrayRef<const Init * > Values,const RecTy * Type)2590 CondOpInit::CondOpInit(ArrayRef<const Init *> Conds,
2591                        ArrayRef<const Init *> Values, const RecTy *Type)
2592     : TypedInit(IK_CondOpInit, Type), NumConds(Conds.size()), ValType(Type) {
2593   const Init **TrailingObjects = getTrailingObjects();
2594   llvm::uninitialized_copy(Conds, TrailingObjects);
2595   llvm::uninitialized_copy(Values, TrailingObjects + NumConds);
2596 }
2597 
Profile(FoldingSetNodeID & ID) const2598 void CondOpInit::Profile(FoldingSetNodeID &ID) const {
2599   ProfileCondOpInit(ID, getConds(), getVals(), ValType);
2600 }
2601 
get(ArrayRef<const Init * > Conds,ArrayRef<const Init * > Values,const RecTy * Ty)2602 const CondOpInit *CondOpInit::get(ArrayRef<const Init *> Conds,
2603                                   ArrayRef<const Init *> Values,
2604                                   const RecTy *Ty) {
2605   assert(Conds.size() == Values.size() &&
2606          "Number of conditions and values must match!");
2607 
2608   FoldingSetNodeID ID;
2609   ProfileCondOpInit(ID, Conds, Values, Ty);
2610 
2611   detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl();
2612   void *IP = nullptr;
2613   if (const CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
2614     return I;
2615 
2616   void *Mem = RK.Allocator.Allocate(
2617       totalSizeToAlloc<const Init *>(2 * Conds.size()), alignof(CondOpInit));
2618   CondOpInit *I = new (Mem) CondOpInit(Conds, Values, Ty);
2619   RK.TheCondOpInitPool.InsertNode(I, IP);
2620   return I;
2621 }
2622 
resolveReferences(Resolver & R) const2623 const Init *CondOpInit::resolveReferences(Resolver &R) const {
2624   SmallVector<const Init *, 4> NewConds;
2625   SmallVector<const Init *, 4> NewVals;
2626 
2627   bool Changed = false;
2628   for (auto [Cond, Val] : getCondAndVals()) {
2629     const Init *NewCond = Cond->resolveReferences(R);
2630     NewConds.push_back(NewCond);
2631     Changed |= NewCond != Cond;
2632 
2633     const Init *NewVal = Val->resolveReferences(R);
2634     NewVals.push_back(NewVal);
2635     Changed |= NewVal != Val;
2636   }
2637 
2638   if (Changed)
2639     return (CondOpInit::get(NewConds, NewVals,
2640             getValType()))->Fold(R.getCurrentRecord());
2641 
2642   return this;
2643 }
2644 
Fold(const Record * CurRec) const2645 const Init *CondOpInit::Fold(const Record *CurRec) const {
2646   RecordKeeper &RK = getRecordKeeper();
2647   for (auto [Cond, Val] : getCondAndVals()) {
2648     if (const auto *CondI = dyn_cast_or_null<IntInit>(
2649             Cond->convertInitializerTo(IntRecTy::get(RK)))) {
2650       if (CondI->getValue())
2651         return Val->convertInitializerTo(getValType());
2652     } else {
2653       return this;
2654     }
2655   }
2656 
2657   PrintFatalError(CurRec->getLoc(),
2658                   CurRec->getNameInitAsString() +
2659                   " does not have any true condition in:" +
2660                   this->getAsString());
2661   return nullptr;
2662 }
2663 
isConcrete() const2664 bool CondOpInit::isConcrete() const {
2665   return all_of(getCondAndVals(), [](const auto &Pair) {
2666     return std::get<0>(Pair)->isConcrete() && std::get<1>(Pair)->isConcrete();
2667   });
2668 }
2669 
isComplete() const2670 bool CondOpInit::isComplete() const {
2671   return all_of(getCondAndVals(), [](const auto &Pair) {
2672     return std::get<0>(Pair)->isComplete() && std::get<1>(Pair)->isComplete();
2673   });
2674 }
2675 
getAsString() const2676 std::string CondOpInit::getAsString() const {
2677   std::string Result = "!cond(";
2678   ListSeparator LS;
2679   for (auto [Cond, Val] : getCondAndVals()) {
2680     Result += LS;
2681     Result += Cond->getAsString() + ": ";
2682     Result += Val->getAsString();
2683   }
2684   return Result + ")";
2685 }
2686 
getBit(unsigned Bit) const2687 const Init *CondOpInit::getBit(unsigned Bit) const {
2688   return VarBitInit::get(this, Bit);
2689 }
2690 
ProfileDagInit(FoldingSetNodeID & ID,const Init * V,const StringInit * VN,ArrayRef<const Init * > Args,ArrayRef<const StringInit * > ArgNames)2691 static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V,
2692                            const StringInit *VN, ArrayRef<const Init *> Args,
2693                            ArrayRef<const StringInit *> ArgNames) {
2694   ID.AddPointer(V);
2695   ID.AddPointer(VN);
2696 
2697   for (auto [Arg, Name] : zip_equal(Args, ArgNames)) {
2698     ID.AddPointer(Arg);
2699     ID.AddPointer(Name);
2700   }
2701 }
2702 
DagInit(const Init * V,const StringInit * VN,ArrayRef<const Init * > Args,ArrayRef<const StringInit * > ArgNames)2703 DagInit::DagInit(const Init *V, const StringInit *VN,
2704                  ArrayRef<const Init *> Args,
2705                  ArrayRef<const StringInit *> ArgNames)
2706     : TypedInit(IK_DagInit, DagRecTy::get(V->getRecordKeeper())), Val(V),
2707       ValName(VN), NumArgs(Args.size()) {
2708   llvm::uninitialized_copy(Args, getTrailingObjects<const Init *>());
2709   llvm::uninitialized_copy(ArgNames, getTrailingObjects<const StringInit *>());
2710 }
2711 
get(const Init * V,const StringInit * VN,ArrayRef<const Init * > Args,ArrayRef<const StringInit * > ArgNames)2712 const DagInit *DagInit::get(const Init *V, const StringInit *VN,
2713                             ArrayRef<const Init *> Args,
2714                             ArrayRef<const StringInit *> ArgNames) {
2715   assert(Args.size() == ArgNames.size() &&
2716          "Number of DAG args and arg names must match!");
2717 
2718   FoldingSetNodeID ID;
2719   ProfileDagInit(ID, V, VN, Args, ArgNames);
2720 
2721   detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl();
2722   void *IP = nullptr;
2723   if (const DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
2724     return I;
2725 
2726   void *Mem =
2727       RK.Allocator.Allocate(totalSizeToAlloc<const Init *, const StringInit *>(
2728                                 Args.size(), ArgNames.size()),
2729                             alignof(DagInit));
2730   DagInit *I = new (Mem) DagInit(V, VN, Args, ArgNames);
2731   RK.TheDagInitPool.InsertNode(I, IP);
2732   return I;
2733 }
2734 
get(const Init * V,const StringInit * VN,ArrayRef<std::pair<const Init *,const StringInit * >> ArgAndNames)2735 const DagInit *DagInit::get(
2736     const Init *V, const StringInit *VN,
2737     ArrayRef<std::pair<const Init *, const StringInit *>> ArgAndNames) {
2738   SmallVector<const Init *, 8> Args(make_first_range(ArgAndNames));
2739   SmallVector<const StringInit *, 8> Names(make_second_range(ArgAndNames));
2740   return DagInit::get(V, VN, Args, Names);
2741 }
2742 
Profile(FoldingSetNodeID & ID) const2743 void DagInit::Profile(FoldingSetNodeID &ID) const {
2744   ProfileDagInit(ID, Val, ValName, getArgs(), getArgNames());
2745 }
2746 
getOperatorAsDef(ArrayRef<SMLoc> Loc) const2747 const Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const {
2748   if (const auto *DefI = dyn_cast<DefInit>(Val))
2749     return DefI->getDef();
2750   PrintFatalError(Loc, "Expected record as operator");
2751   return nullptr;
2752 }
2753 
getArgNo(StringRef Name) const2754 std::optional<unsigned> DagInit::getArgNo(StringRef Name) const {
2755   ArrayRef<const StringInit *> ArgNames = getArgNames();
2756   auto It = llvm::find_if(ArgNames, [Name](const StringInit *ArgName) {
2757     return ArgName && ArgName->getValue() == Name;
2758   });
2759   if (It == ArgNames.end())
2760     return std::nullopt;
2761   return std::distance(ArgNames.begin(), It);
2762 }
2763 
resolveReferences(Resolver & R) const2764 const Init *DagInit::resolveReferences(Resolver &R) const {
2765   SmallVector<const Init *, 8> NewArgs;
2766   NewArgs.reserve(arg_size());
2767   bool ArgsChanged = false;
2768   for (const Init *Arg : getArgs()) {
2769     const Init *NewArg = Arg->resolveReferences(R);
2770     NewArgs.push_back(NewArg);
2771     ArgsChanged |= NewArg != Arg;
2772   }
2773 
2774   const Init *Op = Val->resolveReferences(R);
2775   if (Op != Val || ArgsChanged)
2776     return DagInit::get(Op, ValName, NewArgs, getArgNames());
2777 
2778   return this;
2779 }
2780 
isConcrete() const2781 bool DagInit::isConcrete() const {
2782   if (!Val->isConcrete())
2783     return false;
2784   return all_of(getArgs(), [](const Init *Elt) { return Elt->isConcrete(); });
2785 }
2786 
getAsString() const2787 std::string DagInit::getAsString() const {
2788   std::string Result = "(" + Val->getAsString();
2789   if (ValName)
2790     Result += ":$" + ValName->getAsUnquotedString();
2791   if (!arg_empty()) {
2792     Result += " ";
2793     ListSeparator LS;
2794     for (auto [Arg, Name] : getArgAndNames()) {
2795       Result += LS;
2796       Result += Arg->getAsString();
2797       if (Name)
2798         Result += ":$" + Name->getAsUnquotedString();
2799     }
2800   }
2801   return Result + ")";
2802 }
2803 
2804 //===----------------------------------------------------------------------===//
2805 //    Other implementations
2806 //===----------------------------------------------------------------------===//
2807 
RecordVal(const Init * N,const RecTy * T,FieldKind K)2808 RecordVal::RecordVal(const Init *N, const RecTy *T, FieldKind K)
2809     : Name(N), TyAndKind(T, K) {
2810   setValue(UnsetInit::get(N->getRecordKeeper()));
2811   assert(Value && "Cannot create unset value for current type!");
2812 }
2813 
2814 // This constructor accepts the same arguments as the above, but also
2815 // a source location.
RecordVal(const Init * N,SMLoc Loc,const RecTy * T,FieldKind K)2816 RecordVal::RecordVal(const Init *N, SMLoc Loc, const RecTy *T, FieldKind K)
2817     : Name(N), Loc(Loc), TyAndKind(T, K) {
2818   setValue(UnsetInit::get(N->getRecordKeeper()));
2819   assert(Value && "Cannot create unset value for current type!");
2820 }
2821 
getName() const2822 StringRef RecordVal::getName() const {
2823   return cast<StringInit>(getNameInit())->getValue();
2824 }
2825 
getPrintType() const2826 std::string RecordVal::getPrintType() const {
2827   if (getType() == StringRecTy::get(getRecordKeeper())) {
2828     if (const auto *StrInit = dyn_cast<StringInit>(Value)) {
2829       if (StrInit->hasCodeFormat())
2830         return "code";
2831       else
2832         return "string";
2833     } else {
2834       return "string";
2835     }
2836   } else {
2837     return TyAndKind.getPointer()->getAsString();
2838   }
2839 }
2840 
setValue(const Init * V)2841 bool RecordVal::setValue(const Init *V) {
2842   if (!V) {
2843     Value = nullptr;
2844     return false;
2845   }
2846 
2847   Value = V->getCastTo(getType());
2848   if (!Value)
2849     return true;
2850 
2851   assert(!isa<TypedInit>(Value) ||
2852          cast<TypedInit>(Value)->getType()->typeIsA(getType()));
2853   if (const auto *BTy = dyn_cast<BitsRecTy>(getType())) {
2854     if (isa<BitsInit>(Value))
2855       return false;
2856     SmallVector<const Init *, 64> Bits(BTy->getNumBits());
2857     for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
2858       Bits[I] = Value->getBit(I);
2859     Value = BitsInit::get(V->getRecordKeeper(), Bits);
2860   }
2861 
2862   return false;
2863 }
2864 
2865 // This version of setValue takes a source location and resets the
2866 // location in the RecordVal.
setValue(const Init * V,SMLoc NewLoc)2867 bool RecordVal::setValue(const Init *V, SMLoc NewLoc) {
2868   Loc = NewLoc;
2869   return setValue(V);
2870 }
2871 
2872 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2873 LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << *this; }
2874 #endif
2875 
print(raw_ostream & OS,bool PrintSem) const2876 void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
2877   if (isNonconcreteOK()) OS << "field ";
2878   OS << getPrintType() << " " << getNameInitAsString();
2879 
2880   if (getValue())
2881     OS << " = " << *getValue();
2882 
2883   if (PrintSem) OS << ";\n";
2884 }
2885 
updateClassLoc(SMLoc Loc)2886 void Record::updateClassLoc(SMLoc Loc) {
2887   assert(Locs.size() == 1);
2888   ForwardDeclarationLocs.push_back(Locs.front());
2889 
2890   Locs.clear();
2891   Locs.push_back(Loc);
2892 }
2893 
checkName()2894 void Record::checkName() {
2895   // Ensure the record name has string type.
2896   const auto *TypedName = cast<const TypedInit>(Name);
2897   if (!isa<StringRecTy>(TypedName->getType()))
2898     PrintFatalError(getLoc(), Twine("Record name '") + Name->getAsString() +
2899                                   "' is not a string!");
2900 }
2901 
getType() const2902 const RecordRecTy *Record::getType() const {
2903   SmallVector<const Record *> DirectSCs(
2904       make_first_range(getDirectSuperClasses()));
2905   return RecordRecTy::get(TrackedRecords, DirectSCs);
2906 }
2907 
getDefInit() const2908 DefInit *Record::getDefInit() const {
2909   if (!CorrespondingDefInit) {
2910     CorrespondingDefInit =
2911         new (TrackedRecords.getImpl().Allocator) DefInit(this);
2912   }
2913   return CorrespondingDefInit;
2914 }
2915 
getNewUID(RecordKeeper & RK)2916 unsigned Record::getNewUID(RecordKeeper &RK) {
2917   return RK.getImpl().LastRecordID++;
2918 }
2919 
setName(const Init * NewName)2920 void Record::setName(const Init *NewName) {
2921   Name = NewName;
2922   checkName();
2923   // DO NOT resolve record values to the name at this point because
2924   // there might be default values for arguments of this def. Those
2925   // arguments might not have been resolved yet so we don't want to
2926   // prematurely assume values for those arguments were not passed to
2927   // this def.
2928   //
2929   // Nonetheless, it may be that some of this Record's values
2930   // reference the record name. Indeed, the reason for having the
2931   // record name be an Init is to provide this flexibility. The extra
2932   // resolve steps after completely instantiating defs takes care of
2933   // this. See TGParser::ParseDef and TGParser::ParseDefm.
2934 }
2935 
resolveReferences(Resolver & R,const RecordVal * SkipVal)2936 void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
2937   const Init *OldName = getNameInit();
2938   const Init *NewName = Name->resolveReferences(R);
2939   if (NewName != OldName) {
2940     // Re-register with RecordKeeper.
2941     setName(NewName);
2942   }
2943 
2944   // Resolve the field values.
2945   for (RecordVal &Value : Values) {
2946     if (SkipVal == &Value) // Skip resolve the same field as the given one
2947       continue;
2948     if (const Init *V = Value.getValue()) {
2949       const Init *VR = V->resolveReferences(R);
2950       if (Value.setValue(VR)) {
2951         std::string Type;
2952         if (const auto *VRT = dyn_cast<TypedInit>(VR))
2953           Type =
2954               (Twine("of type '") + VRT->getType()->getAsString() + "' ").str();
2955         PrintFatalError(
2956             getLoc(),
2957             Twine("Invalid value ") + Type + "found when setting field '" +
2958                 Value.getNameInitAsString() + "' of type '" +
2959                 Value.getType()->getAsString() +
2960                 "' after resolving references: " + VR->getAsUnquotedString() +
2961                 "\n");
2962       }
2963     }
2964   }
2965 
2966   // Resolve the assertion expressions.
2967   for (AssertionInfo &Assertion : Assertions) {
2968     const Init *Value = Assertion.Condition->resolveReferences(R);
2969     Assertion.Condition = Value;
2970     Value = Assertion.Message->resolveReferences(R);
2971     Assertion.Message = Value;
2972   }
2973   // Resolve the dump expressions.
2974   for (DumpInfo &Dump : Dumps) {
2975     const Init *Value = Dump.Message->resolveReferences(R);
2976     Dump.Message = Value;
2977   }
2978 }
2979 
resolveReferences(const Init * NewName)2980 void Record::resolveReferences(const Init *NewName) {
2981   RecordResolver R(*this);
2982   R.setName(NewName);
2983   R.setFinal(true);
2984   resolveReferences(R);
2985 }
2986 
2987 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2988 LLVM_DUMP_METHOD void Record::dump() const { errs() << *this; }
2989 #endif
2990 
operator <<(raw_ostream & OS,const Record & R)2991 raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
2992   OS << R.getNameInitAsString();
2993 
2994   ArrayRef<const Init *> TArgs = R.getTemplateArgs();
2995   if (!TArgs.empty()) {
2996     OS << "<";
2997     ListSeparator LS;
2998     for (const Init *TA : TArgs) {
2999       const RecordVal *RV = R.getValue(TA);
3000       assert(RV && "Template argument record not found??");
3001       OS << LS;
3002       RV->print(OS, false);
3003     }
3004     OS << ">";
3005   }
3006 
3007   OS << " {";
3008   std::vector<const Record *> SCs = R.getSuperClasses();
3009   if (!SCs.empty()) {
3010     OS << "\t//";
3011     for (const Record *SC : SCs)
3012       OS << " " << SC->getNameInitAsString();
3013   }
3014   OS << "\n";
3015 
3016   for (const RecordVal &Val : R.getValues())
3017     if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3018       OS << Val;
3019   for (const RecordVal &Val : R.getValues())
3020     if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3021       OS << Val;
3022 
3023   return OS << "}\n";
3024 }
3025 
getFieldLoc(StringRef FieldName) const3026 SMLoc Record::getFieldLoc(StringRef FieldName) const {
3027   const RecordVal *R = getValue(FieldName);
3028   if (!R)
3029     PrintFatalError(getLoc(), "Record `" + getName() +
3030       "' does not have a field named `" + FieldName + "'!\n");
3031   return R->getLoc();
3032 }
3033 
getValueInit(StringRef FieldName) const3034 const Init *Record::getValueInit(StringRef FieldName) const {
3035   const RecordVal *R = getValue(FieldName);
3036   if (!R || !R->getValue())
3037     PrintFatalError(getLoc(), "Record `" + getName() +
3038       "' does not have a field named `" + FieldName + "'!\n");
3039   return R->getValue();
3040 }
3041 
getValueAsString(StringRef FieldName) const3042 StringRef Record::getValueAsString(StringRef FieldName) const {
3043   std::optional<StringRef> S = getValueAsOptionalString(FieldName);
3044   if (!S)
3045     PrintFatalError(getLoc(), "Record `" + getName() +
3046       "' does not have a field named `" + FieldName + "'!\n");
3047   return *S;
3048 }
3049 
3050 std::optional<StringRef>
getValueAsOptionalString(StringRef FieldName) const3051 Record::getValueAsOptionalString(StringRef FieldName) const {
3052   const RecordVal *R = getValue(FieldName);
3053   if (!R || !R->getValue())
3054     return std::nullopt;
3055   if (isa<UnsetInit>(R->getValue()))
3056     return std::nullopt;
3057 
3058   if (const auto *SI = dyn_cast<StringInit>(R->getValue()))
3059     return SI->getValue();
3060 
3061   PrintFatalError(getLoc(),
3062                   "Record `" + getName() + "', ` field `" + FieldName +
3063                       "' exists but does not have a string initializer!");
3064 }
3065 
getValueAsBitsInit(StringRef FieldName) const3066 const BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
3067   const RecordVal *R = getValue(FieldName);
3068   if (!R || !R->getValue())
3069     PrintFatalError(getLoc(), "Record `" + getName() +
3070       "' does not have a field named `" + FieldName + "'!\n");
3071 
3072   if (const auto *BI = dyn_cast<BitsInit>(R->getValue()))
3073     return BI;
3074   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
3075                                 "' exists but does not have a bits value");
3076 }
3077 
getValueAsListInit(StringRef FieldName) const3078 const ListInit *Record::getValueAsListInit(StringRef FieldName) const {
3079   const RecordVal *R = getValue(FieldName);
3080   if (!R || !R->getValue())
3081     PrintFatalError(getLoc(), "Record `" + getName() +
3082       "' does not have a field named `" + FieldName + "'!\n");
3083 
3084   if (const auto *LI = dyn_cast<ListInit>(R->getValue()))
3085     return LI;
3086   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
3087                                 "' exists but does not have a list value");
3088 }
3089 
3090 std::vector<const Record *>
getValueAsListOfDefs(StringRef FieldName) const3091 Record::getValueAsListOfDefs(StringRef FieldName) const {
3092   const ListInit *List = getValueAsListInit(FieldName);
3093   std::vector<const Record *> Defs;
3094   for (const Init *I : List->getElements()) {
3095     if (const auto *DI = dyn_cast<DefInit>(I))
3096       Defs.push_back(DI->getDef());
3097     else
3098       PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3099                                     FieldName +
3100                                     "' list is not entirely DefInit!");
3101   }
3102   return Defs;
3103 }
3104 
getValueAsInt(StringRef FieldName) const3105 int64_t Record::getValueAsInt(StringRef FieldName) const {
3106   const RecordVal *R = getValue(FieldName);
3107   if (!R || !R->getValue())
3108     PrintFatalError(getLoc(), "Record `" + getName() +
3109       "' does not have a field named `" + FieldName + "'!\n");
3110 
3111   if (const auto *II = dyn_cast<IntInit>(R->getValue()))
3112     return II->getValue();
3113   PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" +
3114                                 FieldName +
3115                                 "' exists but does not have an int value: " +
3116                                 R->getValue()->getAsString());
3117 }
3118 
3119 std::vector<int64_t>
getValueAsListOfInts(StringRef FieldName) const3120 Record::getValueAsListOfInts(StringRef FieldName) const {
3121   const ListInit *List = getValueAsListInit(FieldName);
3122   std::vector<int64_t> Ints;
3123   for (const Init *I : List->getElements()) {
3124     if (const auto *II = dyn_cast<IntInit>(I))
3125       Ints.push_back(II->getValue());
3126     else
3127       PrintFatalError(getLoc(),
3128                       Twine("Record `") + getName() + "', field `" + FieldName +
3129                           "' exists but does not have a list of ints value: " +
3130                           I->getAsString());
3131   }
3132   return Ints;
3133 }
3134 
3135 std::vector<StringRef>
getValueAsListOfStrings(StringRef FieldName) const3136 Record::getValueAsListOfStrings(StringRef FieldName) const {
3137   const ListInit *List = getValueAsListInit(FieldName);
3138   std::vector<StringRef> Strings;
3139   for (const Init *I : List->getElements()) {
3140     if (const auto *SI = dyn_cast<StringInit>(I))
3141       Strings.push_back(SI->getValue());
3142     else
3143       PrintFatalError(getLoc(),
3144                       Twine("Record `") + getName() + "', field `" + FieldName +
3145                           "' exists but does not have a list of strings value: " +
3146                           I->getAsString());
3147   }
3148   return Strings;
3149 }
3150 
getValueAsDef(StringRef FieldName) const3151 const Record *Record::getValueAsDef(StringRef FieldName) const {
3152   const RecordVal *R = getValue(FieldName);
3153   if (!R || !R->getValue())
3154     PrintFatalError(getLoc(), "Record `" + getName() +
3155       "' does not have a field named `" + FieldName + "'!\n");
3156 
3157   if (const auto *DI = dyn_cast<DefInit>(R->getValue()))
3158     return DI->getDef();
3159   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3160     FieldName + "' does not have a def initializer!");
3161 }
3162 
getValueAsOptionalDef(StringRef FieldName) const3163 const Record *Record::getValueAsOptionalDef(StringRef FieldName) const {
3164   const RecordVal *R = getValue(FieldName);
3165   if (!R || !R->getValue())
3166     PrintFatalError(getLoc(), "Record `" + getName() +
3167       "' does not have a field named `" + FieldName + "'!\n");
3168 
3169   if (const auto *DI = dyn_cast<DefInit>(R->getValue()))
3170     return DI->getDef();
3171   if (isa<UnsetInit>(R->getValue()))
3172     return nullptr;
3173   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3174     FieldName + "' does not have either a def initializer or '?'!");
3175 }
3176 
getValueAsBit(StringRef FieldName) const3177 bool Record::getValueAsBit(StringRef FieldName) const {
3178   const RecordVal *R = getValue(FieldName);
3179   if (!R || !R->getValue())
3180     PrintFatalError(getLoc(), "Record `" + getName() +
3181       "' does not have a field named `" + FieldName + "'!\n");
3182 
3183   if (const auto *BI = dyn_cast<BitInit>(R->getValue()))
3184     return BI->getValue();
3185   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3186     FieldName + "' does not have a bit initializer!");
3187 }
3188 
getValueAsBitOrUnset(StringRef FieldName,bool & Unset) const3189 bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
3190   const RecordVal *R = getValue(FieldName);
3191   if (!R || !R->getValue())
3192     PrintFatalError(getLoc(), "Record `" + getName() +
3193       "' does not have a field named `" + FieldName.str() + "'!\n");
3194 
3195   if (isa<UnsetInit>(R->getValue())) {
3196     Unset = true;
3197     return false;
3198   }
3199   Unset = false;
3200   if (const auto *BI = dyn_cast<BitInit>(R->getValue()))
3201     return BI->getValue();
3202   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3203     FieldName + "' does not have a bit initializer!");
3204 }
3205 
getValueAsDag(StringRef FieldName) const3206 const DagInit *Record::getValueAsDag(StringRef FieldName) const {
3207   const RecordVal *R = getValue(FieldName);
3208   if (!R || !R->getValue())
3209     PrintFatalError(getLoc(), "Record `" + getName() +
3210       "' does not have a field named `" + FieldName + "'!\n");
3211 
3212   if (const auto *DI = dyn_cast<DagInit>(R->getValue()))
3213     return DI;
3214   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
3215     FieldName + "' does not have a dag initializer!");
3216 }
3217 
3218 // Check all record assertions: For each one, resolve the condition
3219 // and message, then call CheckAssert().
3220 // Note: The condition and message are probably already resolved,
3221 //       but resolving again allows calls before records are resolved.
checkRecordAssertions()3222 void Record::checkRecordAssertions() {
3223   RecordResolver R(*this);
3224   R.setFinal(true);
3225 
3226   bool AnyFailed = false;
3227   for (const auto &Assertion : getAssertions()) {
3228     const Init *Condition = Assertion.Condition->resolveReferences(R);
3229     const Init *Message = Assertion.Message->resolveReferences(R);
3230     AnyFailed |= CheckAssert(Assertion.Loc, Condition, Message);
3231   }
3232 
3233   if (!AnyFailed)
3234     return;
3235 
3236   // If any of the record assertions failed, print some context that will
3237   // help see where the record that caused these assert failures is defined.
3238   PrintError(this, "assertion failed in this record");
3239 }
3240 
emitRecordDumps()3241 void Record::emitRecordDumps() {
3242   RecordResolver R(*this);
3243   R.setFinal(true);
3244 
3245   for (const DumpInfo &Dump : getDumps()) {
3246     const Init *Message = Dump.Message->resolveReferences(R);
3247     dumpMessage(Dump.Loc, Message);
3248   }
3249 }
3250 
3251 // Report a warning if the record has unused template arguments.
checkUnusedTemplateArgs()3252 void Record::checkUnusedTemplateArgs() {
3253   for (const Init *TA : getTemplateArgs()) {
3254     const RecordVal *Arg = getValue(TA);
3255     if (!Arg->isUsed())
3256       PrintWarning(Arg->getLoc(),
3257                    "unused template argument: " + Twine(Arg->getName()));
3258   }
3259 }
3260 
RecordKeeper()3261 RecordKeeper::RecordKeeper()
3262     : Impl(std::make_unique<detail::RecordKeeperImpl>(*this)),
3263       Timer(std::make_unique<TGTimer>()) {}
3264 
3265 RecordKeeper::~RecordKeeper() = default;
3266 
3267 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3268 LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
3269 #endif
3270 
operator <<(raw_ostream & OS,const RecordKeeper & RK)3271 raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
3272   OS << "------------- Classes -----------------\n";
3273   for (const auto &[_, C] : RK.getClasses())
3274     OS << "class " << *C;
3275 
3276   OS << "------------- Defs -----------------\n";
3277   for (const auto &[_, D] : RK.getDefs())
3278     OS << "def " << *D;
3279   return OS;
3280 }
3281 
3282 /// GetNewAnonymousName - Generate a unique anonymous name that can be used as
3283 /// an identifier.
getNewAnonymousName()3284 const Init *RecordKeeper::getNewAnonymousName() {
3285   return AnonymousNameInit::get(*this, getImpl().AnonCounter++);
3286 }
3287 
3288 ArrayRef<const Record *>
getAllDerivedDefinitions(StringRef ClassName) const3289 RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
3290   // We cache the record vectors for single classes. Many backends request
3291   // the same vectors multiple times.
3292   auto [Iter, Inserted] = Cache.try_emplace(ClassName.str());
3293   if (Inserted)
3294     Iter->second = getAllDerivedDefinitions(ArrayRef(ClassName));
3295   return Iter->second;
3296 }
3297 
3298 std::vector<const Record *>
getAllDerivedDefinitions(ArrayRef<StringRef> ClassNames) const3299 RecordKeeper::getAllDerivedDefinitions(ArrayRef<StringRef> ClassNames) const {
3300   SmallVector<const Record *, 2> ClassRecs;
3301   std::vector<const Record *> Defs;
3302 
3303   assert(ClassNames.size() > 0 && "At least one class must be passed.");
3304   for (StringRef ClassName : ClassNames) {
3305     const Record *Class = getClass(ClassName);
3306     if (!Class)
3307       PrintFatalError("The class '" + ClassName + "' is not defined\n");
3308     ClassRecs.push_back(Class);
3309   }
3310 
3311   for (const auto &OneDef : getDefs()) {
3312     if (all_of(ClassRecs, [&OneDef](const Record *Class) {
3313           return OneDef.second->isSubClassOf(Class);
3314         }))
3315       Defs.push_back(OneDef.second.get());
3316   }
3317   llvm::sort(Defs, LessRecord());
3318   return Defs;
3319 }
3320 
3321 ArrayRef<const Record *>
getAllDerivedDefinitionsIfDefined(StringRef ClassName) const3322 RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const {
3323   if (getClass(ClassName))
3324     return getAllDerivedDefinitions(ClassName);
3325   return Cache[""];
3326 }
3327 
dumpAllocationStats(raw_ostream & OS) const3328 void RecordKeeper::dumpAllocationStats(raw_ostream &OS) const {
3329   Impl->dumpAllocationStats(OS);
3330 }
3331 
resolve(const Init * VarName)3332 const Init *MapResolver::resolve(const Init *VarName) {
3333   auto It = Map.find(VarName);
3334   if (It == Map.end())
3335     return nullptr;
3336 
3337   const Init *I = It->second.V;
3338 
3339   if (!It->second.Resolved && Map.size() > 1) {
3340     // Resolve mutual references among the mapped variables, but prevent
3341     // infinite recursion.
3342     Map.erase(It);
3343     I = I->resolveReferences(*this);
3344     Map[VarName] = {I, true};
3345   }
3346 
3347   return I;
3348 }
3349 
resolve(const Init * VarName)3350 const Init *RecordResolver::resolve(const Init *VarName) {
3351   const Init *Val = Cache.lookup(VarName);
3352   if (Val)
3353     return Val;
3354 
3355   if (llvm::is_contained(Stack, VarName))
3356     return nullptr; // prevent infinite recursion
3357 
3358   if (const RecordVal *RV = getCurrentRecord()->getValue(VarName)) {
3359     if (!isa<UnsetInit>(RV->getValue())) {
3360       Val = RV->getValue();
3361       Stack.push_back(VarName);
3362       Val = Val->resolveReferences(*this);
3363       Stack.pop_back();
3364     }
3365   } else if (Name && VarName == getCurrentRecord()->getNameInit()) {
3366     Stack.push_back(VarName);
3367     Val = Name->resolveReferences(*this);
3368     Stack.pop_back();
3369   }
3370 
3371   Cache[VarName] = Val;
3372   return Val;
3373 }
3374 
resolve(const Init * VarName)3375 const Init *TrackUnresolvedResolver::resolve(const Init *VarName) {
3376   const Init *I = nullptr;
3377 
3378   if (R) {
3379     I = R->resolve(VarName);
3380     if (I && !FoundUnresolved) {
3381       // Do not recurse into the resolved initializer, as that would change
3382       // the behavior of the resolver we're delegating, but do check to see
3383       // if there are unresolved variables remaining.
3384       TrackUnresolvedResolver Sub;
3385       I->resolveReferences(Sub);
3386       FoundUnresolved |= Sub.FoundUnresolved;
3387     }
3388   }
3389 
3390   if (!I)
3391     FoundUnresolved = true;
3392   return I;
3393 }
3394 
resolve(const Init * VarName)3395 const Init *HasReferenceResolver::resolve(const Init *VarName) {
3396   if (VarName == VarNameToTrack)
3397     Found = true;
3398   return nullptr;
3399 }
3400