File: | llvm/lib/TableGen/Record.cpp |
Warning: | line 875, column 26 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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/ADT/ArrayRef.h" | ||||
14 | #include "llvm/ADT/DenseMap.h" | ||||
15 | #include "llvm/ADT/FoldingSet.h" | ||||
16 | #include "llvm/ADT/SmallString.h" | ||||
17 | #include "llvm/ADT/SmallVector.h" | ||||
18 | #include "llvm/ADT/Statistic.h" | ||||
19 | #include "llvm/ADT/StringExtras.h" | ||||
20 | #include "llvm/ADT/StringMap.h" | ||||
21 | #include "llvm/ADT/StringRef.h" | ||||
22 | #include "llvm/ADT/StringSet.h" | ||||
23 | #include "llvm/Config/llvm-config.h" | ||||
24 | #include "llvm/Support/Allocator.h" | ||||
25 | #include "llvm/Support/Casting.h" | ||||
26 | #include "llvm/Support/Compiler.h" | ||||
27 | #include "llvm/Support/ErrorHandling.h" | ||||
28 | #include "llvm/Support/SMLoc.h" | ||||
29 | #include "llvm/Support/raw_ostream.h" | ||||
30 | #include "llvm/TableGen/Error.h" | ||||
31 | #include "llvm/TableGen/Record.h" | ||||
32 | #include <cassert> | ||||
33 | #include <cstdint> | ||||
34 | #include <memory> | ||||
35 | #include <map> | ||||
36 | #include <string> | ||||
37 | #include <utility> | ||||
38 | #include <vector> | ||||
39 | |||||
40 | using namespace llvm; | ||||
41 | |||||
42 | #define DEBUG_TYPE"tblgen-records" "tblgen-records" | ||||
43 | |||||
44 | static BumpPtrAllocator Allocator; | ||||
45 | |||||
46 | //===----------------------------------------------------------------------===// | ||||
47 | // Type implementations | ||||
48 | //===----------------------------------------------------------------------===// | ||||
49 | |||||
50 | BitRecTy BitRecTy::Shared; | ||||
51 | IntRecTy IntRecTy::Shared; | ||||
52 | StringRecTy StringRecTy::Shared; | ||||
53 | DagRecTy DagRecTy::Shared; | ||||
54 | |||||
55 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
56 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void RecTy::dump() const { print(errs()); } | ||||
57 | #endif | ||||
58 | |||||
59 | ListRecTy *RecTy::getListTy() { | ||||
60 | if (!ListTy) | ||||
61 | ListTy = new(Allocator) ListRecTy(this); | ||||
62 | return ListTy; | ||||
63 | } | ||||
64 | |||||
65 | bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
66 | assert(RHS && "NULL pointer")((RHS && "NULL pointer") ? static_cast<void> (0 ) : __assert_fail ("RHS && \"NULL pointer\"", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 66, __PRETTY_FUNCTION__)); | ||||
67 | return Kind == RHS->getRecTyKind(); | ||||
68 | } | ||||
69 | |||||
70 | bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; } | ||||
71 | |||||
72 | bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{ | ||||
73 | if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind) | ||||
74 | return true; | ||||
75 | if (const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS)) | ||||
76 | return BitsTy->getNumBits() == 1; | ||||
77 | return false; | ||||
78 | } | ||||
79 | |||||
80 | BitsRecTy *BitsRecTy::get(unsigned Sz) { | ||||
81 | static std::vector<BitsRecTy*> Shared; | ||||
82 | if (Sz >= Shared.size()) | ||||
83 | Shared.resize(Sz + 1); | ||||
84 | BitsRecTy *&Ty = Shared[Sz]; | ||||
85 | if (!Ty) | ||||
86 | Ty = new(Allocator) BitsRecTy(Sz); | ||||
87 | return Ty; | ||||
88 | } | ||||
89 | |||||
90 | std::string BitsRecTy::getAsString() const { | ||||
91 | return "bits<" + utostr(Size) + ">"; | ||||
92 | } | ||||
93 | |||||
94 | bool BitsRecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
95 | if (RecTy::typeIsConvertibleTo(RHS)) //argument and the sender are same type | ||||
96 | return cast<BitsRecTy>(RHS)->Size == Size; | ||||
97 | RecTyKind kind = RHS->getRecTyKind(); | ||||
98 | return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind); | ||||
99 | } | ||||
100 | |||||
101 | bool BitsRecTy::typeIsA(const RecTy *RHS) const { | ||||
102 | if (const BitsRecTy *RHSb = dyn_cast<BitsRecTy>(RHS)) | ||||
103 | return RHSb->Size == Size; | ||||
104 | return false; | ||||
105 | } | ||||
106 | |||||
107 | bool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
108 | RecTyKind kind = RHS->getRecTyKind(); | ||||
109 | return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind; | ||||
110 | } | ||||
111 | |||||
112 | std::string StringRecTy::getAsString() const { | ||||
113 | return "string"; | ||||
114 | } | ||||
115 | |||||
116 | bool StringRecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
117 | RecTyKind Kind = RHS->getRecTyKind(); | ||||
118 | return Kind == StringRecTyKind; | ||||
119 | } | ||||
120 | |||||
121 | std::string ListRecTy::getAsString() const { | ||||
122 | return "list<" + ElementTy->getAsString() + ">"; | ||||
123 | } | ||||
124 | |||||
125 | bool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
126 | if (const auto *ListTy = dyn_cast<ListRecTy>(RHS)) | ||||
127 | return ElementTy->typeIsConvertibleTo(ListTy->getElementType()); | ||||
128 | return false; | ||||
129 | } | ||||
130 | |||||
131 | bool ListRecTy::typeIsA(const RecTy *RHS) const { | ||||
132 | if (const ListRecTy *RHSl = dyn_cast<ListRecTy>(RHS)) | ||||
133 | return getElementType()->typeIsA(RHSl->getElementType()); | ||||
134 | return false; | ||||
135 | } | ||||
136 | |||||
137 | std::string DagRecTy::getAsString() const { | ||||
138 | return "dag"; | ||||
139 | } | ||||
140 | |||||
141 | static void ProfileRecordRecTy(FoldingSetNodeID &ID, | ||||
142 | ArrayRef<Record *> Classes) { | ||||
143 | ID.AddInteger(Classes.size()); | ||||
144 | for (Record *R : Classes) | ||||
145 | ID.AddPointer(R); | ||||
146 | } | ||||
147 | |||||
148 | RecordRecTy *RecordRecTy::get(ArrayRef<Record *> UnsortedClasses) { | ||||
149 | if (UnsortedClasses.empty()) { | ||||
150 | static RecordRecTy AnyRecord(0); | ||||
151 | return &AnyRecord; | ||||
152 | } | ||||
153 | |||||
154 | FoldingSet<RecordRecTy> &ThePool = | ||||
155 | UnsortedClasses[0]->getRecords().RecordTypePool; | ||||
156 | |||||
157 | SmallVector<Record *, 4> Classes(UnsortedClasses.begin(), | ||||
158 | UnsortedClasses.end()); | ||||
159 | llvm::sort(Classes, [](Record *LHS, Record *RHS) { | ||||
160 | return LHS->getNameInitAsString() < RHS->getNameInitAsString(); | ||||
161 | }); | ||||
162 | |||||
163 | FoldingSetNodeID ID; | ||||
164 | ProfileRecordRecTy(ID, Classes); | ||||
165 | |||||
166 | void *IP = nullptr; | ||||
167 | if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
168 | return Ty; | ||||
169 | |||||
170 | #ifndef NDEBUG | ||||
171 | // Check for redundancy. | ||||
172 | for (unsigned i = 0; i < Classes.size(); ++i) { | ||||
173 | for (unsigned j = 0; j < Classes.size(); ++j) { | ||||
174 | assert(i == j || !Classes[i]->isSubClassOf(Classes[j]))((i == j || !Classes[i]->isSubClassOf(Classes[j])) ? static_cast <void> (0) : __assert_fail ("i == j || !Classes[i]->isSubClassOf(Classes[j])" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 174, __PRETTY_FUNCTION__)); | ||||
175 | } | ||||
176 | assert(&Classes[0]->getRecords() == &Classes[i]->getRecords())((&Classes[0]->getRecords() == &Classes[i]->getRecords ()) ? static_cast<void> (0) : __assert_fail ("&Classes[0]->getRecords() == &Classes[i]->getRecords()" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 176, __PRETTY_FUNCTION__)); | ||||
177 | } | ||||
178 | #endif | ||||
179 | |||||
180 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Record *>(Classes.size()), | ||||
181 | alignof(RecordRecTy)); | ||||
182 | RecordRecTy *Ty = new(Mem) RecordRecTy(Classes.size()); | ||||
183 | std::uninitialized_copy(Classes.begin(), Classes.end(), | ||||
184 | Ty->getTrailingObjects<Record *>()); | ||||
185 | ThePool.InsertNode(Ty, IP); | ||||
186 | return Ty; | ||||
187 | } | ||||
188 | |||||
189 | void RecordRecTy::Profile(FoldingSetNodeID &ID) const { | ||||
190 | ProfileRecordRecTy(ID, getClasses()); | ||||
191 | } | ||||
192 | |||||
193 | std::string RecordRecTy::getAsString() const { | ||||
194 | if (NumClasses == 1) | ||||
195 | return getClasses()[0]->getNameInitAsString(); | ||||
196 | |||||
197 | std::string Str = "{"; | ||||
198 | bool First = true; | ||||
199 | for (Record *R : getClasses()) { | ||||
200 | if (!First) | ||||
201 | Str += ", "; | ||||
202 | First = false; | ||||
203 | Str += R->getNameInitAsString(); | ||||
204 | } | ||||
205 | Str += "}"; | ||||
206 | return Str; | ||||
207 | } | ||||
208 | |||||
209 | bool RecordRecTy::isSubClassOf(Record *Class) const { | ||||
210 | return llvm::any_of(getClasses(), [Class](Record *MySuperClass) { | ||||
211 | return MySuperClass == Class || | ||||
212 | MySuperClass->isSubClassOf(Class); | ||||
213 | }); | ||||
214 | } | ||||
215 | |||||
216 | bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const { | ||||
217 | if (this == RHS) | ||||
218 | return true; | ||||
219 | |||||
220 | const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS); | ||||
221 | if (!RTy) | ||||
222 | return false; | ||||
223 | |||||
224 | return llvm::all_of(RTy->getClasses(), [this](Record *TargetClass) { | ||||
225 | return isSubClassOf(TargetClass); | ||||
226 | }); | ||||
227 | } | ||||
228 | |||||
229 | bool RecordRecTy::typeIsA(const RecTy *RHS) const { | ||||
230 | return typeIsConvertibleTo(RHS); | ||||
231 | } | ||||
232 | |||||
233 | static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) { | ||||
234 | SmallVector<Record *, 4> CommonSuperClasses; | ||||
235 | SmallVector<Record *, 4> Stack; | ||||
236 | |||||
237 | Stack.insert(Stack.end(), T1->classes_begin(), T1->classes_end()); | ||||
238 | |||||
239 | while (!Stack.empty()) { | ||||
240 | Record *R = Stack.back(); | ||||
241 | Stack.pop_back(); | ||||
242 | |||||
243 | if (T2->isSubClassOf(R)) { | ||||
244 | CommonSuperClasses.push_back(R); | ||||
245 | } else { | ||||
246 | R->getDirectSuperClasses(Stack); | ||||
247 | } | ||||
248 | } | ||||
249 | |||||
250 | return RecordRecTy::get(CommonSuperClasses); | ||||
251 | } | ||||
252 | |||||
253 | RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { | ||||
254 | if (T1 == T2) | ||||
255 | return T1; | ||||
256 | |||||
257 | if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) { | ||||
258 | if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) | ||||
259 | return resolveRecordTypes(RecTy1, RecTy2); | ||||
260 | } | ||||
261 | |||||
262 | if (T1->typeIsConvertibleTo(T2)) | ||||
263 | return T2; | ||||
264 | if (T2->typeIsConvertibleTo(T1)) | ||||
265 | return T1; | ||||
266 | |||||
267 | if (ListRecTy *ListTy1 = dyn_cast<ListRecTy>(T1)) { | ||||
268 | if (ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) { | ||||
269 | RecTy* NewType = resolveTypes(ListTy1->getElementType(), | ||||
270 | ListTy2->getElementType()); | ||||
271 | if (NewType) | ||||
272 | return NewType->getListTy(); | ||||
273 | } | ||||
274 | } | ||||
275 | |||||
276 | return nullptr; | ||||
277 | } | ||||
278 | |||||
279 | //===----------------------------------------------------------------------===// | ||||
280 | // Initializer implementations | ||||
281 | //===----------------------------------------------------------------------===// | ||||
282 | |||||
283 | void Init::anchor() {} | ||||
284 | |||||
285 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
286 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void Init::dump() const { return print(errs()); } | ||||
287 | #endif | ||||
288 | |||||
289 | UnsetInit *UnsetInit::get() { | ||||
290 | static UnsetInit TheInit; | ||||
291 | return &TheInit; | ||||
292 | } | ||||
293 | |||||
294 | Init *UnsetInit::getCastTo(RecTy *Ty) const { | ||||
295 | return const_cast<UnsetInit *>(this); | ||||
296 | } | ||||
297 | |||||
298 | Init *UnsetInit::convertInitializerTo(RecTy *Ty) const { | ||||
299 | return const_cast<UnsetInit *>(this); | ||||
300 | } | ||||
301 | |||||
302 | BitInit *BitInit::get(bool V) { | ||||
303 | static BitInit True(true); | ||||
304 | static BitInit False(false); | ||||
305 | |||||
306 | return V ? &True : &False; | ||||
307 | } | ||||
308 | |||||
309 | Init *BitInit::convertInitializerTo(RecTy *Ty) const { | ||||
310 | if (isa<BitRecTy>(Ty)) | ||||
311 | return const_cast<BitInit *>(this); | ||||
312 | |||||
313 | if (isa<IntRecTy>(Ty)) | ||||
314 | return IntInit::get(getValue()); | ||||
315 | |||||
316 | if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { | ||||
317 | // Can only convert single bit. | ||||
318 | if (BRT->getNumBits() == 1) | ||||
319 | return BitsInit::get(const_cast<BitInit *>(this)); | ||||
320 | } | ||||
321 | |||||
322 | return nullptr; | ||||
323 | } | ||||
324 | |||||
325 | static void | ||||
326 | ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) { | ||||
327 | ID.AddInteger(Range.size()); | ||||
328 | |||||
329 | for (Init *I : Range) | ||||
330 | ID.AddPointer(I); | ||||
331 | } | ||||
332 | |||||
333 | BitsInit *BitsInit::get(ArrayRef<Init *> Range) { | ||||
334 | static FoldingSet<BitsInit> ThePool; | ||||
335 | |||||
336 | FoldingSetNodeID ID; | ||||
337 | ProfileBitsInit(ID, Range); | ||||
338 | |||||
339 | void *IP = nullptr; | ||||
340 | if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
341 | return I; | ||||
342 | |||||
343 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), | ||||
344 | alignof(BitsInit)); | ||||
345 | BitsInit *I = new(Mem) BitsInit(Range.size()); | ||||
346 | std::uninitialized_copy(Range.begin(), Range.end(), | ||||
347 | I->getTrailingObjects<Init *>()); | ||||
348 | ThePool.InsertNode(I, IP); | ||||
349 | return I; | ||||
350 | } | ||||
351 | |||||
352 | void BitsInit::Profile(FoldingSetNodeID &ID) const { | ||||
353 | ProfileBitsInit(ID, makeArrayRef(getTrailingObjects<Init *>(), NumBits)); | ||||
354 | } | ||||
355 | |||||
356 | Init *BitsInit::convertInitializerTo(RecTy *Ty) const { | ||||
357 | if (isa<BitRecTy>(Ty)) { | ||||
358 | if (getNumBits() != 1) return nullptr; // Only accept if just one bit! | ||||
359 | return getBit(0); | ||||
360 | } | ||||
361 | |||||
362 | if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { | ||||
363 | // If the number of bits is right, return it. Otherwise we need to expand | ||||
364 | // or truncate. | ||||
365 | if (getNumBits() != BRT->getNumBits()) return nullptr; | ||||
366 | return const_cast<BitsInit *>(this); | ||||
367 | } | ||||
368 | |||||
369 | if (isa<IntRecTy>(Ty)) { | ||||
370 | int64_t Result = 0; | ||||
371 | for (unsigned i = 0, e = getNumBits(); i != e; ++i) | ||||
372 | if (auto *Bit = dyn_cast<BitInit>(getBit(i))) | ||||
373 | Result |= static_cast<int64_t>(Bit->getValue()) << i; | ||||
374 | else | ||||
375 | return nullptr; | ||||
376 | return IntInit::get(Result); | ||||
377 | } | ||||
378 | |||||
379 | return nullptr; | ||||
380 | } | ||||
381 | |||||
382 | Init * | ||||
383 | BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { | ||||
384 | SmallVector<Init *, 16> NewBits(Bits.size()); | ||||
385 | |||||
386 | for (unsigned i = 0, e = Bits.size(); i != e; ++i) { | ||||
387 | if (Bits[i] >= getNumBits()) | ||||
388 | return nullptr; | ||||
389 | NewBits[i] = getBit(Bits[i]); | ||||
390 | } | ||||
391 | return BitsInit::get(NewBits); | ||||
392 | } | ||||
393 | |||||
394 | bool BitsInit::isConcrete() const { | ||||
395 | for (unsigned i = 0, e = getNumBits(); i != e; ++i) { | ||||
396 | if (!getBit(i)->isConcrete()) | ||||
397 | return false; | ||||
398 | } | ||||
399 | return true; | ||||
400 | } | ||||
401 | |||||
402 | std::string BitsInit::getAsString() const { | ||||
403 | std::string Result = "{ "; | ||||
404 | for (unsigned i = 0, e = getNumBits(); i != e; ++i) { | ||||
405 | if (i) Result += ", "; | ||||
406 | if (Init *Bit = getBit(e-i-1)) | ||||
407 | Result += Bit->getAsString(); | ||||
408 | else | ||||
409 | Result += "*"; | ||||
410 | } | ||||
411 | return Result + " }"; | ||||
412 | } | ||||
413 | |||||
414 | // resolveReferences - If there are any field references that refer to fields | ||||
415 | // that have been filled in, we can propagate the values now. | ||||
416 | Init *BitsInit::resolveReferences(Resolver &R) const { | ||||
417 | bool Changed = false; | ||||
418 | SmallVector<Init *, 16> NewBits(getNumBits()); | ||||
419 | |||||
420 | Init *CachedBitVarRef = nullptr; | ||||
421 | Init *CachedBitVarResolved = nullptr; | ||||
422 | |||||
423 | for (unsigned i = 0, e = getNumBits(); i != e; ++i) { | ||||
424 | Init *CurBit = getBit(i); | ||||
425 | Init *NewBit = CurBit; | ||||
426 | |||||
427 | if (VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) { | ||||
428 | if (CurBitVar->getBitVar() != CachedBitVarRef) { | ||||
429 | CachedBitVarRef = CurBitVar->getBitVar(); | ||||
430 | CachedBitVarResolved = CachedBitVarRef->resolveReferences(R); | ||||
431 | } | ||||
432 | assert(CachedBitVarResolved && "Unresolved bitvar reference")((CachedBitVarResolved && "Unresolved bitvar reference" ) ? static_cast<void> (0) : __assert_fail ("CachedBitVarResolved && \"Unresolved bitvar reference\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 432, __PRETTY_FUNCTION__)); | ||||
433 | NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum()); | ||||
434 | } else { | ||||
435 | // getBit(0) implicitly converts int and bits<1> values to bit. | ||||
436 | NewBit = CurBit->resolveReferences(R)->getBit(0); | ||||
437 | } | ||||
438 | |||||
439 | if (isa<UnsetInit>(NewBit) && R.keepUnsetBits()) | ||||
440 | NewBit = CurBit; | ||||
441 | NewBits[i] = NewBit; | ||||
442 | Changed |= CurBit != NewBit; | ||||
443 | } | ||||
444 | |||||
445 | if (Changed) | ||||
446 | return BitsInit::get(NewBits); | ||||
447 | |||||
448 | return const_cast<BitsInit *>(this); | ||||
449 | } | ||||
450 | |||||
451 | IntInit *IntInit::get(int64_t V) { | ||||
452 | static std::map<int64_t, IntInit*> ThePool; | ||||
453 | |||||
454 | IntInit *&I = ThePool[V]; | ||||
455 | if (!I) I = new(Allocator) IntInit(V); | ||||
456 | return I; | ||||
457 | } | ||||
458 | |||||
459 | std::string IntInit::getAsString() const { | ||||
460 | return itostr(Value); | ||||
461 | } | ||||
462 | |||||
463 | static bool canFitInBitfield(int64_t Value, unsigned NumBits) { | ||||
464 | // For example, with NumBits == 4, we permit Values from [-7 .. 15]. | ||||
465 | return (NumBits >= sizeof(Value) * 8) || | ||||
466 | (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1); | ||||
467 | } | ||||
468 | |||||
469 | Init *IntInit::convertInitializerTo(RecTy *Ty) const { | ||||
470 | if (isa<IntRecTy>(Ty)) | ||||
471 | return const_cast<IntInit *>(this); | ||||
472 | |||||
473 | if (isa<BitRecTy>(Ty)) { | ||||
474 | int64_t Val = getValue(); | ||||
475 | if (Val != 0 && Val != 1) return nullptr; // Only accept 0 or 1 for a bit! | ||||
476 | return BitInit::get(Val != 0); | ||||
477 | } | ||||
478 | |||||
479 | if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) { | ||||
480 | int64_t Value = getValue(); | ||||
481 | // Make sure this bitfield is large enough to hold the integer value. | ||||
482 | if (!canFitInBitfield(Value, BRT->getNumBits())) | ||||
483 | return nullptr; | ||||
484 | |||||
485 | SmallVector<Init *, 16> NewBits(BRT->getNumBits()); | ||||
486 | for (unsigned i = 0; i != BRT->getNumBits(); ++i) | ||||
487 | NewBits[i] = BitInit::get(Value & ((i < 64) ? (1LL << i) : 0)); | ||||
488 | |||||
489 | return BitsInit::get(NewBits); | ||||
490 | } | ||||
491 | |||||
492 | return nullptr; | ||||
493 | } | ||||
494 | |||||
495 | Init * | ||||
496 | IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { | ||||
497 | SmallVector<Init *, 16> NewBits(Bits.size()); | ||||
498 | |||||
499 | for (unsigned i = 0, e = Bits.size(); i != e; ++i) { | ||||
500 | if (Bits[i] >= 64) | ||||
501 | return nullptr; | ||||
502 | |||||
503 | NewBits[i] = BitInit::get(Value & (INT64_C(1)1L << Bits[i])); | ||||
504 | } | ||||
505 | return BitsInit::get(NewBits); | ||||
506 | } | ||||
507 | |||||
508 | StringInit *StringInit::get(StringRef V, StringFormat Fmt) { | ||||
509 | static StringMap<StringInit*, BumpPtrAllocator &> StringPool(Allocator); | ||||
510 | static StringMap<StringInit*, BumpPtrAllocator &> CodePool(Allocator); | ||||
511 | |||||
512 | if (Fmt == SF_String) { | ||||
513 | auto &Entry = *StringPool.insert(std::make_pair(V, nullptr)).first; | ||||
514 | if (!Entry.second) | ||||
515 | Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt); | ||||
516 | return Entry.second; | ||||
517 | } else { | ||||
518 | auto &Entry = *CodePool.insert(std::make_pair(V, nullptr)).first; | ||||
519 | if (!Entry.second) | ||||
520 | Entry.second = new (Allocator) StringInit(Entry.getKey(), Fmt); | ||||
521 | return Entry.second; | ||||
522 | } | ||||
523 | } | ||||
524 | |||||
525 | Init *StringInit::convertInitializerTo(RecTy *Ty) const { | ||||
526 | if (isa<StringRecTy>(Ty)) | ||||
527 | return const_cast<StringInit *>(this); | ||||
528 | |||||
529 | return nullptr; | ||||
530 | } | ||||
531 | |||||
532 | static void ProfileListInit(FoldingSetNodeID &ID, | ||||
533 | ArrayRef<Init *> Range, | ||||
534 | RecTy *EltTy) { | ||||
535 | ID.AddInteger(Range.size()); | ||||
536 | ID.AddPointer(EltTy); | ||||
537 | |||||
538 | for (Init *I : Range) | ||||
539 | ID.AddPointer(I); | ||||
540 | } | ||||
541 | |||||
542 | ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { | ||||
543 | static FoldingSet<ListInit> ThePool; | ||||
544 | |||||
545 | FoldingSetNodeID ID; | ||||
546 | ProfileListInit(ID, Range, EltTy); | ||||
547 | |||||
548 | void *IP = nullptr; | ||||
549 | if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
550 | return I; | ||||
551 | |||||
552 | assert(Range.empty() || !isa<TypedInit>(Range[0]) ||((Range.empty() || !isa<TypedInit>(Range[0]) || cast< TypedInit>(Range[0])->getType()->typeIsConvertibleTo (EltTy)) ? static_cast<void> (0) : __assert_fail ("Range.empty() || !isa<TypedInit>(Range[0]) || cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy)" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 553, __PRETTY_FUNCTION__)) | ||||
553 | cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy))((Range.empty() || !isa<TypedInit>(Range[0]) || cast< TypedInit>(Range[0])->getType()->typeIsConvertibleTo (EltTy)) ? static_cast<void> (0) : __assert_fail ("Range.empty() || !isa<TypedInit>(Range[0]) || cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy)" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 553, __PRETTY_FUNCTION__)); | ||||
554 | |||||
555 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), | ||||
556 | alignof(ListInit)); | ||||
557 | ListInit *I = new(Mem) ListInit(Range.size(), EltTy); | ||||
558 | std::uninitialized_copy(Range.begin(), Range.end(), | ||||
559 | I->getTrailingObjects<Init *>()); | ||||
560 | ThePool.InsertNode(I, IP); | ||||
561 | return I; | ||||
562 | } | ||||
563 | |||||
564 | void ListInit::Profile(FoldingSetNodeID &ID) const { | ||||
565 | RecTy *EltTy = cast<ListRecTy>(getType())->getElementType(); | ||||
566 | |||||
567 | ProfileListInit(ID, getValues(), EltTy); | ||||
568 | } | ||||
569 | |||||
570 | Init *ListInit::convertInitializerTo(RecTy *Ty) const { | ||||
571 | if (getType() == Ty) | ||||
572 | return const_cast<ListInit*>(this); | ||||
573 | |||||
574 | if (auto *LRT = dyn_cast<ListRecTy>(Ty)) { | ||||
575 | SmallVector<Init*, 8> Elements; | ||||
576 | Elements.reserve(getValues().size()); | ||||
577 | |||||
578 | // Verify that all of the elements of the list are subclasses of the | ||||
579 | // appropriate class! | ||||
580 | bool Changed = false; | ||||
581 | RecTy *ElementType = LRT->getElementType(); | ||||
582 | for (Init *I : getValues()) | ||||
583 | if (Init *CI = I->convertInitializerTo(ElementType)) { | ||||
584 | Elements.push_back(CI); | ||||
585 | if (CI != I) | ||||
586 | Changed = true; | ||||
587 | } else | ||||
588 | return nullptr; | ||||
589 | |||||
590 | if (!Changed) | ||||
591 | return const_cast<ListInit*>(this); | ||||
592 | return ListInit::get(Elements, ElementType); | ||||
593 | } | ||||
594 | |||||
595 | return nullptr; | ||||
596 | } | ||||
597 | |||||
598 | Init *ListInit::convertInitListSlice(ArrayRef<unsigned> Elements) const { | ||||
599 | SmallVector<Init*, 8> Vals; | ||||
600 | Vals.reserve(Elements.size()); | ||||
601 | for (unsigned Element : Elements) { | ||||
602 | if (Element >= size()) | ||||
603 | return nullptr; | ||||
604 | Vals.push_back(getElement(Element)); | ||||
605 | } | ||||
606 | return ListInit::get(Vals, getElementType()); | ||||
607 | } | ||||
608 | |||||
609 | Record *ListInit::getElementAsRecord(unsigned i) const { | ||||
610 | assert(i < NumValues && "List element index out of range!")((i < NumValues && "List element index out of range!" ) ? static_cast<void> (0) : __assert_fail ("i < NumValues && \"List element index out of range!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 610, __PRETTY_FUNCTION__)); | ||||
611 | DefInit *DI = dyn_cast<DefInit>(getElement(i)); | ||||
612 | if (!DI) | ||||
613 | PrintFatalError("Expected record in list!"); | ||||
614 | return DI->getDef(); | ||||
615 | } | ||||
616 | |||||
617 | Init *ListInit::resolveReferences(Resolver &R) const { | ||||
618 | SmallVector<Init*, 8> Resolved; | ||||
619 | Resolved.reserve(size()); | ||||
620 | bool Changed = false; | ||||
621 | |||||
622 | for (Init *CurElt : getValues()) { | ||||
623 | Init *E = CurElt->resolveReferences(R); | ||||
624 | Changed |= E != CurElt; | ||||
625 | Resolved.push_back(E); | ||||
626 | } | ||||
627 | |||||
628 | if (Changed) | ||||
629 | return ListInit::get(Resolved, getElementType()); | ||||
630 | return const_cast<ListInit *>(this); | ||||
631 | } | ||||
632 | |||||
633 | bool ListInit::isConcrete() const { | ||||
634 | for (Init *Element : *this) { | ||||
635 | if (!Element->isConcrete()) | ||||
636 | return false; | ||||
637 | } | ||||
638 | return true; | ||||
639 | } | ||||
640 | |||||
641 | std::string ListInit::getAsString() const { | ||||
642 | std::string Result = "["; | ||||
643 | const char *sep = ""; | ||||
644 | for (Init *Element : *this) { | ||||
645 | Result += sep; | ||||
646 | sep = ", "; | ||||
647 | Result += Element->getAsString(); | ||||
648 | } | ||||
649 | return Result + "]"; | ||||
650 | } | ||||
651 | |||||
652 | Init *OpInit::getBit(unsigned Bit) const { | ||||
653 | if (getType() == BitRecTy::get()) | ||||
654 | return const_cast<OpInit*>(this); | ||||
655 | return VarBitInit::get(const_cast<OpInit*>(this), Bit); | ||||
656 | } | ||||
657 | |||||
658 | static void | ||||
659 | ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) { | ||||
660 | ID.AddInteger(Opcode); | ||||
661 | ID.AddPointer(Op); | ||||
662 | ID.AddPointer(Type); | ||||
663 | } | ||||
664 | |||||
665 | UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) { | ||||
666 | static FoldingSet<UnOpInit> ThePool; | ||||
667 | |||||
668 | FoldingSetNodeID ID; | ||||
669 | ProfileUnOpInit(ID, Opc, LHS, Type); | ||||
670 | |||||
671 | void *IP = nullptr; | ||||
672 | if (UnOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
673 | return I; | ||||
674 | |||||
675 | UnOpInit *I = new(Allocator) UnOpInit(Opc, LHS, Type); | ||||
676 | ThePool.InsertNode(I, IP); | ||||
677 | return I; | ||||
678 | } | ||||
679 | |||||
680 | void UnOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
681 | ProfileUnOpInit(ID, getOpcode(), getOperand(), getType()); | ||||
682 | } | ||||
683 | |||||
684 | Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { | ||||
685 | switch (getOpcode()) { | ||||
686 | case CAST: | ||||
687 | if (isa<StringRecTy>(getType())) { | ||||
688 | if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) | ||||
689 | return LHSs; | ||||
690 | |||||
691 | if (DefInit *LHSd = dyn_cast<DefInit>(LHS)) | ||||
692 | return StringInit::get(LHSd->getAsString()); | ||||
693 | |||||
694 | if (IntInit *LHSi = dyn_cast<IntInit>(LHS)) | ||||
695 | return StringInit::get(LHSi->getAsString()); | ||||
696 | } else if (isa<RecordRecTy>(getType())) { | ||||
697 | if (StringInit *Name = dyn_cast<StringInit>(LHS)) { | ||||
698 | if (!CurRec && !IsFinal) | ||||
699 | break; | ||||
700 | assert(CurRec && "NULL pointer")((CurRec && "NULL pointer") ? static_cast<void> (0) : __assert_fail ("CurRec && \"NULL pointer\"", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 700, __PRETTY_FUNCTION__)); | ||||
701 | Record *D; | ||||
702 | |||||
703 | // Self-references are allowed, but their resolution is delayed until | ||||
704 | // the final resolve to ensure that we get the correct type for them. | ||||
705 | if (Name == CurRec->getNameInit()) { | ||||
706 | if (!IsFinal) | ||||
707 | break; | ||||
708 | D = CurRec; | ||||
709 | } else { | ||||
710 | D = CurRec->getRecords().getDef(Name->getValue()); | ||||
711 | if (!D) { | ||||
712 | if (IsFinal) | ||||
713 | PrintFatalError(CurRec->getLoc(), | ||||
714 | Twine("Undefined reference to record: '") + | ||||
715 | Name->getValue() + "'\n"); | ||||
716 | break; | ||||
717 | } | ||||
718 | } | ||||
719 | |||||
720 | DefInit *DI = DefInit::get(D); | ||||
721 | if (!DI->getType()->typeIsA(getType())) { | ||||
722 | PrintFatalError(CurRec->getLoc(), | ||||
723 | Twine("Expected type '") + | ||||
724 | getType()->getAsString() + "', got '" + | ||||
725 | DI->getType()->getAsString() + "' in: " + | ||||
726 | getAsString() + "\n"); | ||||
727 | } | ||||
728 | return DI; | ||||
729 | } | ||||
730 | } | ||||
731 | |||||
732 | if (Init *NewInit = LHS->convertInitializerTo(getType())) | ||||
733 | return NewInit; | ||||
734 | break; | ||||
735 | |||||
736 | case NOT: | ||||
737 | if (IntInit *LHSi = | ||||
738 | dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()))) | ||||
739 | return IntInit::get(LHSi->getValue() ? 0 : 1); | ||||
740 | break; | ||||
741 | |||||
742 | case HEAD: | ||||
743 | if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { | ||||
744 | assert(!LHSl->empty() && "Empty list in head")((!LHSl->empty() && "Empty list in head") ? static_cast <void> (0) : __assert_fail ("!LHSl->empty() && \"Empty list in head\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 744, __PRETTY_FUNCTION__)); | ||||
745 | return LHSl->getElement(0); | ||||
746 | } | ||||
747 | break; | ||||
748 | |||||
749 | case TAIL: | ||||
750 | if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { | ||||
751 | assert(!LHSl->empty() && "Empty list in tail")((!LHSl->empty() && "Empty list in tail") ? static_cast <void> (0) : __assert_fail ("!LHSl->empty() && \"Empty list in tail\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 751, __PRETTY_FUNCTION__)); | ||||
752 | // Note the +1. We can't just pass the result of getValues() | ||||
753 | // directly. | ||||
754 | return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType()); | ||||
755 | } | ||||
756 | break; | ||||
757 | |||||
758 | case SIZE: | ||||
759 | if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) | ||||
760 | return IntInit::get(LHSl->size()); | ||||
761 | if (DagInit *LHSd = dyn_cast<DagInit>(LHS)) | ||||
762 | return IntInit::get(LHSd->arg_size()); | ||||
763 | if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) | ||||
764 | return IntInit::get(LHSs->getValue().size()); | ||||
765 | break; | ||||
766 | |||||
767 | case EMPTY: | ||||
768 | if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) | ||||
769 | return IntInit::get(LHSl->empty()); | ||||
770 | if (DagInit *LHSd = dyn_cast<DagInit>(LHS)) | ||||
771 | return IntInit::get(LHSd->arg_empty()); | ||||
772 | if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) | ||||
773 | return IntInit::get(LHSs->getValue().empty()); | ||||
774 | break; | ||||
775 | |||||
776 | case GETDAGOP: | ||||
777 | if (DagInit *Dag = dyn_cast<DagInit>(LHS)) { | ||||
778 | DefInit *DI = DefInit::get(Dag->getOperatorAsDef({})); | ||||
779 | if (!DI->getType()->typeIsA(getType())) { | ||||
780 | PrintFatalError(CurRec->getLoc(), | ||||
781 | Twine("Expected type '") + | ||||
782 | getType()->getAsString() + "', got '" + | ||||
783 | DI->getType()->getAsString() + "' in: " + | ||||
784 | getAsString() + "\n"); | ||||
785 | } else { | ||||
786 | return DI; | ||||
787 | } | ||||
788 | } | ||||
789 | break; | ||||
790 | } | ||||
791 | return const_cast<UnOpInit *>(this); | ||||
792 | } | ||||
793 | |||||
794 | Init *UnOpInit::resolveReferences(Resolver &R) const { | ||||
795 | Init *lhs = LHS->resolveReferences(R); | ||||
796 | |||||
797 | if (LHS != lhs || (R.isFinal() && getOpcode() == CAST)) | ||||
798 | return (UnOpInit::get(getOpcode(), lhs, getType())) | ||||
799 | ->Fold(R.getCurrentRecord(), R.isFinal()); | ||||
800 | return const_cast<UnOpInit *>(this); | ||||
801 | } | ||||
802 | |||||
803 | std::string UnOpInit::getAsString() const { | ||||
804 | std::string Result; | ||||
805 | switch (getOpcode()) { | ||||
806 | case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break; | ||||
807 | case NOT: Result = "!not"; break; | ||||
808 | case HEAD: Result = "!head"; break; | ||||
809 | case TAIL: Result = "!tail"; break; | ||||
810 | case SIZE: Result = "!size"; break; | ||||
811 | case EMPTY: Result = "!empty"; break; | ||||
812 | case GETDAGOP: Result = "!getdagop"; break; | ||||
813 | } | ||||
814 | return Result + "(" + LHS->getAsString() + ")"; | ||||
815 | } | ||||
816 | |||||
817 | static void | ||||
818 | ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS, | ||||
819 | RecTy *Type) { | ||||
820 | ID.AddInteger(Opcode); | ||||
821 | ID.AddPointer(LHS); | ||||
822 | ID.AddPointer(RHS); | ||||
823 | ID.AddPointer(Type); | ||||
824 | } | ||||
825 | |||||
826 | BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, | ||||
827 | Init *RHS, RecTy *Type) { | ||||
828 | static FoldingSet<BinOpInit> ThePool; | ||||
829 | |||||
830 | FoldingSetNodeID ID; | ||||
831 | ProfileBinOpInit(ID, Opc, LHS, RHS, Type); | ||||
832 | |||||
833 | void *IP = nullptr; | ||||
834 | if (BinOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
835 | return I; | ||||
836 | |||||
837 | BinOpInit *I = new(Allocator) BinOpInit(Opc, LHS, RHS, Type); | ||||
838 | ThePool.InsertNode(I, IP); | ||||
839 | return I; | ||||
840 | } | ||||
841 | |||||
842 | void BinOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
843 | ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType()); | ||||
844 | } | ||||
845 | |||||
846 | static StringInit *ConcatStringInits(const StringInit *I0, | ||||
847 | const StringInit *I1) { | ||||
848 | SmallString<80> Concat(I0->getValue()); | ||||
849 | Concat.append(I1->getValue()); | ||||
850 | return StringInit::get(Concat, | ||||
851 | StringInit::determineFormat(I0->getFormat(), | ||||
852 | I1->getFormat())); | ||||
853 | } | ||||
854 | |||||
855 | static StringInit *interleaveStringList(const ListInit *List, | ||||
856 | const StringInit *Delim) { | ||||
857 | if (List->size() == 0) | ||||
858 | return StringInit::get(""); | ||||
859 | SmallString<80> Result(dyn_cast<StringInit>(List->getElement(0))->getValue()); | ||||
860 | StringInit::StringFormat Fmt = StringInit::SF_String; | ||||
861 | |||||
862 | for (unsigned I = 1, E = List->size(); I < E; ++I) { | ||||
863 | Result.append(Delim->getValue()); | ||||
864 | auto *StrInit = dyn_cast<StringInit>(List->getElement(I)); | ||||
865 | Result.append(StrInit->getValue()); | ||||
866 | Fmt = StringInit::determineFormat(Fmt, StrInit->getFormat()); | ||||
867 | } | ||||
868 | return StringInit::get(Result, Fmt); | ||||
869 | } | ||||
870 | |||||
871 | static StringInit *interleaveIntList(const ListInit *List, | ||||
872 | const StringInit *Delim) { | ||||
873 | if (List->size() == 0) | ||||
874 | return StringInit::get(""); | ||||
875 | SmallString<80> Result(dyn_cast<IntInit>(List->getElement(0)-> | ||||
| |||||
876 | getCastTo(IntRecTy::get()))->getAsString()); | ||||
877 | |||||
878 | for (unsigned I = 1, E = List->size(); I < E; ++I) { | ||||
879 | Result.append(Delim->getValue()); | ||||
880 | Result.append(dyn_cast<IntInit>(List->getElement(I)-> | ||||
881 | getCastTo(IntRecTy::get()))->getAsString()); | ||||
882 | } | ||||
883 | return StringInit::get(Result); | ||||
884 | } | ||||
885 | |||||
886 | Init *BinOpInit::getStrConcat(Init *I0, Init *I1) { | ||||
887 | // Shortcut for the common case of concatenating two strings. | ||||
888 | if (const StringInit *I0s = dyn_cast<StringInit>(I0)) | ||||
889 | if (const StringInit *I1s = dyn_cast<StringInit>(I1)) | ||||
890 | return ConcatStringInits(I0s, I1s); | ||||
891 | return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get()); | ||||
892 | } | ||||
893 | |||||
894 | static ListInit *ConcatListInits(const ListInit *LHS, | ||||
895 | const ListInit *RHS) { | ||||
896 | SmallVector<Init *, 8> Args; | ||||
897 | Args.insert(Args.end(), LHS->begin(), LHS->end()); | ||||
898 | Args.insert(Args.end(), RHS->begin(), RHS->end()); | ||||
899 | return ListInit::get(Args, LHS->getElementType()); | ||||
900 | } | ||||
901 | |||||
902 | Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) { | ||||
903 | assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list")((isa<ListRecTy>(LHS->getType()) && "First arg must be a list" ) ? static_cast<void> (0) : __assert_fail ("isa<ListRecTy>(LHS->getType()) && \"First arg must be a list\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 903, __PRETTY_FUNCTION__)); | ||||
904 | |||||
905 | // Shortcut for the common case of concatenating two lists. | ||||
906 | if (const ListInit *LHSList = dyn_cast<ListInit>(LHS)) | ||||
907 | if (const ListInit *RHSList = dyn_cast<ListInit>(RHS)) | ||||
908 | return ConcatListInits(LHSList, RHSList); | ||||
909 | return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType()); | ||||
910 | } | ||||
911 | |||||
912 | Init *BinOpInit::Fold(Record *CurRec) const { | ||||
913 | switch (getOpcode()) { | ||||
| |||||
914 | case CONCAT: { | ||||
915 | DagInit *LHSs = dyn_cast<DagInit>(LHS); | ||||
916 | DagInit *RHSs = dyn_cast<DagInit>(RHS); | ||||
917 | if (LHSs && RHSs) { | ||||
918 | DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator()); | ||||
919 | DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator()); | ||||
920 | if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) || | ||||
921 | (!ROp && !isa<UnsetInit>(RHSs->getOperator()))) | ||||
922 | break; | ||||
923 | if (LOp && ROp && LOp->getDef() != ROp->getDef()) { | ||||
924 | PrintFatalError(Twine("Concatenated Dag operators do not match: '") + | ||||
925 | LHSs->getAsString() + "' vs. '" + RHSs->getAsString() + | ||||
926 | "'"); | ||||
927 | } | ||||
928 | Init *Op = LOp ? LOp : ROp; | ||||
929 | if (!Op) | ||||
930 | Op = UnsetInit::get(); | ||||
931 | |||||
932 | SmallVector<Init*, 8> Args; | ||||
933 | SmallVector<StringInit*, 8> ArgNames; | ||||
934 | for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) { | ||||
935 | Args.push_back(LHSs->getArg(i)); | ||||
936 | ArgNames.push_back(LHSs->getArgName(i)); | ||||
937 | } | ||||
938 | for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) { | ||||
939 | Args.push_back(RHSs->getArg(i)); | ||||
940 | ArgNames.push_back(RHSs->getArgName(i)); | ||||
941 | } | ||||
942 | return DagInit::get(Op, nullptr, Args, ArgNames); | ||||
943 | } | ||||
944 | break; | ||||
945 | } | ||||
946 | case LISTCONCAT: { | ||||
947 | ListInit *LHSs = dyn_cast<ListInit>(LHS); | ||||
948 | ListInit *RHSs = dyn_cast<ListInit>(RHS); | ||||
949 | if (LHSs && RHSs) { | ||||
950 | SmallVector<Init *, 8> Args; | ||||
951 | Args.insert(Args.end(), LHSs->begin(), LHSs->end()); | ||||
952 | Args.insert(Args.end(), RHSs->begin(), RHSs->end()); | ||||
953 | return ListInit::get(Args, LHSs->getElementType()); | ||||
954 | } | ||||
955 | break; | ||||
956 | } | ||||
957 | case LISTSPLAT: { | ||||
958 | TypedInit *Value = dyn_cast<TypedInit>(LHS); | ||||
959 | IntInit *Size = dyn_cast<IntInit>(RHS); | ||||
960 | if (Value && Size) { | ||||
961 | SmallVector<Init *, 8> Args(Size->getValue(), Value); | ||||
962 | return ListInit::get(Args, Value->getType()); | ||||
963 | } | ||||
964 | break; | ||||
965 | } | ||||
966 | case STRCONCAT: { | ||||
967 | StringInit *LHSs = dyn_cast<StringInit>(LHS); | ||||
968 | StringInit *RHSs = dyn_cast<StringInit>(RHS); | ||||
969 | if (LHSs && RHSs) | ||||
970 | return ConcatStringInits(LHSs, RHSs); | ||||
971 | break; | ||||
972 | } | ||||
973 | case INTERLEAVE: { | ||||
974 | ListInit *List = dyn_cast<ListInit>(LHS); | ||||
975 | StringInit *Delim = dyn_cast<StringInit>(RHS); | ||||
976 | if (List
| ||||
977 | if (isa<StringRecTy>(List->getElementType())) | ||||
978 | return interleaveStringList(List, Delim); | ||||
979 | else | ||||
980 | return interleaveIntList(List, Delim); | ||||
981 | } | ||||
982 | break; | ||||
983 | } | ||||
984 | case EQ: | ||||
985 | case NE: | ||||
986 | case LE: | ||||
987 | case LT: | ||||
988 | case GE: | ||||
989 | case GT: { | ||||
990 | // First see if we have two bit, bits, or int. | ||||
991 | IntInit *LHSi = | ||||
992 | dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); | ||||
993 | IntInit *RHSi = | ||||
994 | dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); | ||||
995 | |||||
996 | if (LHSi && RHSi) { | ||||
997 | bool Result; | ||||
998 | switch (getOpcode()) { | ||||
999 | case EQ: Result = LHSi->getValue() == RHSi->getValue(); break; | ||||
1000 | case NE: Result = LHSi->getValue() != RHSi->getValue(); break; | ||||
1001 | case LE: Result = LHSi->getValue() <= RHSi->getValue(); break; | ||||
1002 | case LT: Result = LHSi->getValue() < RHSi->getValue(); break; | ||||
1003 | case GE: Result = LHSi->getValue() >= RHSi->getValue(); break; | ||||
1004 | case GT: Result = LHSi->getValue() > RHSi->getValue(); break; | ||||
1005 | default: llvm_unreachable("unhandled comparison")::llvm::llvm_unreachable_internal("unhandled comparison", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1005); | ||||
1006 | } | ||||
1007 | return BitInit::get(Result); | ||||
1008 | } | ||||
1009 | |||||
1010 | // Next try strings. | ||||
1011 | StringInit *LHSs = dyn_cast<StringInit>(LHS); | ||||
1012 | StringInit *RHSs = dyn_cast<StringInit>(RHS); | ||||
1013 | |||||
1014 | if (LHSs && RHSs) { | ||||
1015 | bool Result; | ||||
1016 | switch (getOpcode()) { | ||||
1017 | case EQ: Result = LHSs->getValue() == RHSs->getValue(); break; | ||||
1018 | case NE: Result = LHSs->getValue() != RHSs->getValue(); break; | ||||
1019 | case LE: Result = LHSs->getValue() <= RHSs->getValue(); break; | ||||
1020 | case LT: Result = LHSs->getValue() < RHSs->getValue(); break; | ||||
1021 | case GE: Result = LHSs->getValue() >= RHSs->getValue(); break; | ||||
1022 | case GT: Result = LHSs->getValue() > RHSs->getValue(); break; | ||||
1023 | default: llvm_unreachable("unhandled comparison")::llvm::llvm_unreachable_internal("unhandled comparison", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1023); | ||||
1024 | } | ||||
1025 | return BitInit::get(Result); | ||||
1026 | } | ||||
1027 | |||||
1028 | // Finally, !eq and !ne can be used with records. | ||||
1029 | if (getOpcode() == EQ || getOpcode() == NE) { | ||||
1030 | DefInit *LHSd = dyn_cast<DefInit>(LHS); | ||||
1031 | DefInit *RHSd = dyn_cast<DefInit>(RHS); | ||||
1032 | if (LHSd && RHSd) | ||||
1033 | return BitInit::get((getOpcode() == EQ) ? LHSd == RHSd | ||||
1034 | : LHSd != RHSd); | ||||
1035 | } | ||||
1036 | |||||
1037 | break; | ||||
1038 | } | ||||
1039 | case SETDAGOP: { | ||||
1040 | DagInit *Dag = dyn_cast<DagInit>(LHS); | ||||
1041 | DefInit *Op = dyn_cast<DefInit>(RHS); | ||||
1042 | if (Dag && Op) { | ||||
1043 | SmallVector<Init*, 8> Args; | ||||
1044 | SmallVector<StringInit*, 8> ArgNames; | ||||
1045 | for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { | ||||
1046 | Args.push_back(Dag->getArg(i)); | ||||
1047 | ArgNames.push_back(Dag->getArgName(i)); | ||||
1048 | } | ||||
1049 | return DagInit::get(Op, nullptr, Args, ArgNames); | ||||
1050 | } | ||||
1051 | break; | ||||
1052 | } | ||||
1053 | case ADD: | ||||
1054 | case SUB: | ||||
1055 | case MUL: | ||||
1056 | case AND: | ||||
1057 | case OR: | ||||
1058 | case XOR: | ||||
1059 | case SHL: | ||||
1060 | case SRA: | ||||
1061 | case SRL: { | ||||
1062 | IntInit *LHSi = | ||||
1063 | dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); | ||||
1064 | IntInit *RHSi = | ||||
1065 | dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); | ||||
1066 | if (LHSi && RHSi) { | ||||
1067 | int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); | ||||
1068 | int64_t Result; | ||||
1069 | switch (getOpcode()) { | ||||
1070 | default: llvm_unreachable("Bad opcode!")::llvm::llvm_unreachable_internal("Bad opcode!", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1070); | ||||
1071 | case ADD: Result = LHSv + RHSv; break; | ||||
1072 | case SUB: Result = LHSv - RHSv; break; | ||||
1073 | case MUL: Result = LHSv * RHSv; break; | ||||
1074 | case AND: Result = LHSv & RHSv; break; | ||||
1075 | case OR: Result = LHSv | RHSv; break; | ||||
1076 | case XOR: Result = LHSv ^ RHSv; break; | ||||
1077 | case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break; | ||||
1078 | case SRA: Result = LHSv >> RHSv; break; | ||||
1079 | case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; | ||||
1080 | } | ||||
1081 | return IntInit::get(Result); | ||||
1082 | } | ||||
1083 | break; | ||||
1084 | } | ||||
1085 | } | ||||
1086 | return const_cast<BinOpInit *>(this); | ||||
1087 | } | ||||
1088 | |||||
1089 | Init *BinOpInit::resolveReferences(Resolver &R) const { | ||||
1090 | Init *lhs = LHS->resolveReferences(R); | ||||
1091 | Init *rhs = RHS->resolveReferences(R); | ||||
1092 | |||||
1093 | if (LHS != lhs || RHS != rhs) | ||||
1094 | return (BinOpInit::get(getOpcode(), lhs, rhs, getType())) | ||||
1095 | ->Fold(R.getCurrentRecord()); | ||||
1096 | return const_cast<BinOpInit *>(this); | ||||
1097 | } | ||||
1098 | |||||
1099 | std::string BinOpInit::getAsString() const { | ||||
1100 | std::string Result; | ||||
1101 | switch (getOpcode()) { | ||||
1102 | case CONCAT: Result = "!con"; break; | ||||
1103 | case ADD: Result = "!add"; break; | ||||
1104 | case SUB: Result = "!sub"; break; | ||||
1105 | case MUL: Result = "!mul"; break; | ||||
1106 | case AND: Result = "!and"; break; | ||||
1107 | case OR: Result = "!or"; break; | ||||
1108 | case XOR: Result = "!xor"; break; | ||||
1109 | case SHL: Result = "!shl"; break; | ||||
1110 | case SRA: Result = "!sra"; break; | ||||
1111 | case SRL: Result = "!srl"; break; | ||||
1112 | case EQ: Result = "!eq"; break; | ||||
1113 | case NE: Result = "!ne"; break; | ||||
1114 | case LE: Result = "!le"; break; | ||||
1115 | case LT: Result = "!lt"; break; | ||||
1116 | case GE: Result = "!ge"; break; | ||||
1117 | case GT: Result = "!gt"; break; | ||||
1118 | case LISTCONCAT: Result = "!listconcat"; break; | ||||
1119 | case LISTSPLAT: Result = "!listsplat"; break; | ||||
1120 | case STRCONCAT: Result = "!strconcat"; break; | ||||
1121 | case INTERLEAVE: Result = "!interleave"; break; | ||||
1122 | case SETDAGOP: Result = "!setdagop"; break; | ||||
1123 | } | ||||
1124 | return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; | ||||
1125 | } | ||||
1126 | |||||
1127 | static void | ||||
1128 | ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS, | ||||
1129 | Init *RHS, RecTy *Type) { | ||||
1130 | ID.AddInteger(Opcode); | ||||
1131 | ID.AddPointer(LHS); | ||||
1132 | ID.AddPointer(MHS); | ||||
1133 | ID.AddPointer(RHS); | ||||
1134 | ID.AddPointer(Type); | ||||
1135 | } | ||||
1136 | |||||
1137 | TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS, | ||||
1138 | RecTy *Type) { | ||||
1139 | static FoldingSet<TernOpInit> ThePool; | ||||
1140 | |||||
1141 | FoldingSetNodeID ID; | ||||
1142 | ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type); | ||||
1143 | |||||
1144 | void *IP = nullptr; | ||||
1145 | if (TernOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
1146 | return I; | ||||
1147 | |||||
1148 | TernOpInit *I = new(Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type); | ||||
1149 | ThePool.InsertNode(I, IP); | ||||
1150 | return I; | ||||
1151 | } | ||||
1152 | |||||
1153 | void TernOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
1154 | ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType()); | ||||
1155 | } | ||||
1156 | |||||
1157 | static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) { | ||||
1158 | MapResolver R(CurRec); | ||||
1159 | R.set(LHS, MHSe); | ||||
1160 | return RHS->resolveReferences(R); | ||||
1161 | } | ||||
1162 | |||||
1163 | static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS, | ||||
1164 | Record *CurRec) { | ||||
1165 | bool Change = false; | ||||
1166 | Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec); | ||||
1167 | if (Val != MHSd->getOperator()) | ||||
1168 | Change = true; | ||||
1169 | |||||
1170 | SmallVector<std::pair<Init *, StringInit *>, 8> NewArgs; | ||||
1171 | for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) { | ||||
1172 | Init *Arg = MHSd->getArg(i); | ||||
1173 | Init *NewArg; | ||||
1174 | StringInit *ArgName = MHSd->getArgName(i); | ||||
1175 | |||||
1176 | if (DagInit *Argd = dyn_cast<DagInit>(Arg)) | ||||
1177 | NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec); | ||||
1178 | else | ||||
1179 | NewArg = ItemApply(LHS, Arg, RHS, CurRec); | ||||
1180 | |||||
1181 | NewArgs.push_back(std::make_pair(NewArg, ArgName)); | ||||
1182 | if (Arg != NewArg) | ||||
1183 | Change = true; | ||||
1184 | } | ||||
1185 | |||||
1186 | if (Change) | ||||
1187 | return DagInit::get(Val, nullptr, NewArgs); | ||||
1188 | return MHSd; | ||||
1189 | } | ||||
1190 | |||||
1191 | // Applies RHS to all elements of MHS, using LHS as a temp variable. | ||||
1192 | static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, | ||||
1193 | Record *CurRec) { | ||||
1194 | if (DagInit *MHSd = dyn_cast<DagInit>(MHS)) | ||||
1195 | return ForeachDagApply(LHS, MHSd, RHS, CurRec); | ||||
1196 | |||||
1197 | if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) { | ||||
1198 | SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end()); | ||||
1199 | |||||
1200 | for (Init *&Item : NewList) { | ||||
1201 | Init *NewItem = ItemApply(LHS, Item, RHS, CurRec); | ||||
1202 | if (NewItem != Item) | ||||
1203 | Item = NewItem; | ||||
1204 | } | ||||
1205 | return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType()); | ||||
1206 | } | ||||
1207 | |||||
1208 | return nullptr; | ||||
1209 | } | ||||
1210 | |||||
1211 | // Evaluates RHS for all elements of MHS, using LHS as a temp variable. | ||||
1212 | // Creates a new list with the elements that evaluated to true. | ||||
1213 | static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, | ||||
1214 | Record *CurRec) { | ||||
1215 | if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) { | ||||
1216 | SmallVector<Init *, 8> NewList; | ||||
1217 | |||||
1218 | for (Init *Item : MHSl->getValues()) { | ||||
1219 | Init *Include = ItemApply(LHS, Item, RHS, CurRec); | ||||
1220 | if (!Include) | ||||
1221 | return nullptr; | ||||
1222 | if (IntInit *IncludeInt = dyn_cast_or_null<IntInit>( | ||||
1223 | Include->convertInitializerTo(IntRecTy::get()))) { | ||||
1224 | if (IncludeInt->getValue()) | ||||
1225 | NewList.push_back(Item); | ||||
1226 | } else { | ||||
1227 | return nullptr; | ||||
1228 | } | ||||
1229 | } | ||||
1230 | return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType()); | ||||
1231 | } | ||||
1232 | |||||
1233 | return nullptr; | ||||
1234 | } | ||||
1235 | |||||
1236 | Init *TernOpInit::Fold(Record *CurRec) const { | ||||
1237 | switch (getOpcode()) { | ||||
1238 | case SUBST: { | ||||
1239 | DefInit *LHSd = dyn_cast<DefInit>(LHS); | ||||
1240 | VarInit *LHSv = dyn_cast<VarInit>(LHS); | ||||
1241 | StringInit *LHSs = dyn_cast<StringInit>(LHS); | ||||
1242 | |||||
1243 | DefInit *MHSd = dyn_cast<DefInit>(MHS); | ||||
1244 | VarInit *MHSv = dyn_cast<VarInit>(MHS); | ||||
1245 | StringInit *MHSs = dyn_cast<StringInit>(MHS); | ||||
1246 | |||||
1247 | DefInit *RHSd = dyn_cast<DefInit>(RHS); | ||||
1248 | VarInit *RHSv = dyn_cast<VarInit>(RHS); | ||||
1249 | StringInit *RHSs = dyn_cast<StringInit>(RHS); | ||||
1250 | |||||
1251 | if (LHSd && MHSd && RHSd) { | ||||
1252 | Record *Val = RHSd->getDef(); | ||||
1253 | if (LHSd->getAsString() == RHSd->getAsString()) | ||||
1254 | Val = MHSd->getDef(); | ||||
1255 | return DefInit::get(Val); | ||||
1256 | } | ||||
1257 | if (LHSv && MHSv && RHSv) { | ||||
1258 | std::string Val = std::string(RHSv->getName()); | ||||
1259 | if (LHSv->getAsString() == RHSv->getAsString()) | ||||
1260 | Val = std::string(MHSv->getName()); | ||||
1261 | return VarInit::get(Val, getType()); | ||||
1262 | } | ||||
1263 | if (LHSs && MHSs && RHSs) { | ||||
1264 | std::string Val = std::string(RHSs->getValue()); | ||||
1265 | |||||
1266 | std::string::size_type found; | ||||
1267 | std::string::size_type idx = 0; | ||||
1268 | while (true) { | ||||
1269 | found = Val.find(std::string(LHSs->getValue()), idx); | ||||
1270 | if (found == std::string::npos) | ||||
1271 | break; | ||||
1272 | Val.replace(found, LHSs->getValue().size(), | ||||
1273 | std::string(MHSs->getValue())); | ||||
1274 | idx = found + MHSs->getValue().size(); | ||||
1275 | } | ||||
1276 | |||||
1277 | return StringInit::get(Val); | ||||
1278 | } | ||||
1279 | break; | ||||
1280 | } | ||||
1281 | |||||
1282 | case FOREACH: { | ||||
1283 | if (Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec)) | ||||
1284 | return Result; | ||||
1285 | break; | ||||
1286 | } | ||||
1287 | |||||
1288 | case FILTER: { | ||||
1289 | if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec)) | ||||
1290 | return Result; | ||||
1291 | break; | ||||
1292 | } | ||||
1293 | |||||
1294 | case IF: { | ||||
1295 | if (IntInit *LHSi = dyn_cast_or_null<IntInit>( | ||||
1296 | LHS->convertInitializerTo(IntRecTy::get()))) { | ||||
1297 | if (LHSi->getValue()) | ||||
1298 | return MHS; | ||||
1299 | return RHS; | ||||
1300 | } | ||||
1301 | break; | ||||
1302 | } | ||||
1303 | |||||
1304 | case DAG: { | ||||
1305 | ListInit *MHSl = dyn_cast<ListInit>(MHS); | ||||
1306 | ListInit *RHSl = dyn_cast<ListInit>(RHS); | ||||
1307 | bool MHSok = MHSl || isa<UnsetInit>(MHS); | ||||
1308 | bool RHSok = RHSl || isa<UnsetInit>(RHS); | ||||
1309 | |||||
1310 | if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS)) | ||||
1311 | break; // Typically prevented by the parser, but might happen with template args | ||||
1312 | |||||
1313 | if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) { | ||||
1314 | SmallVector<std::pair<Init *, StringInit *>, 8> Children; | ||||
1315 | unsigned Size = MHSl ? MHSl->size() : RHSl->size(); | ||||
1316 | for (unsigned i = 0; i != Size; ++i) { | ||||
1317 | Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(); | ||||
1318 | Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(); | ||||
1319 | if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name)) | ||||
1320 | return const_cast<TernOpInit *>(this); | ||||
1321 | Children.emplace_back(Node, dyn_cast<StringInit>(Name)); | ||||
1322 | } | ||||
1323 | return DagInit::get(LHS, nullptr, Children); | ||||
1324 | } | ||||
1325 | break; | ||||
1326 | } | ||||
1327 | } | ||||
1328 | |||||
1329 | return const_cast<TernOpInit *>(this); | ||||
1330 | } | ||||
1331 | |||||
1332 | Init *TernOpInit::resolveReferences(Resolver &R) const { | ||||
1333 | Init *lhs = LHS->resolveReferences(R); | ||||
1334 | |||||
1335 | if (getOpcode() == IF && lhs != LHS) { | ||||
1336 | if (IntInit *Value = dyn_cast_or_null<IntInit>( | ||||
1337 | lhs->convertInitializerTo(IntRecTy::get()))) { | ||||
1338 | // Short-circuit | ||||
1339 | if (Value->getValue()) | ||||
1340 | return MHS->resolveReferences(R); | ||||
1341 | return RHS->resolveReferences(R); | ||||
1342 | } | ||||
1343 | } | ||||
1344 | |||||
1345 | Init *mhs = MHS->resolveReferences(R); | ||||
1346 | Init *rhs; | ||||
1347 | |||||
1348 | if (getOpcode() == FOREACH || getOpcode() == FILTER) { | ||||
1349 | ShadowResolver SR(R); | ||||
1350 | SR.addShadow(lhs); | ||||
1351 | rhs = RHS->resolveReferences(SR); | ||||
1352 | } else { | ||||
1353 | rhs = RHS->resolveReferences(R); | ||||
1354 | } | ||||
1355 | |||||
1356 | if (LHS != lhs || MHS != mhs || RHS != rhs) | ||||
1357 | return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType())) | ||||
1358 | ->Fold(R.getCurrentRecord()); | ||||
1359 | return const_cast<TernOpInit *>(this); | ||||
1360 | } | ||||
1361 | |||||
1362 | std::string TernOpInit::getAsString() const { | ||||
1363 | std::string Result; | ||||
1364 | bool UnquotedLHS = false; | ||||
1365 | switch (getOpcode()) { | ||||
1366 | case SUBST: Result = "!subst"; break; | ||||
1367 | case FOREACH: Result = "!foreach"; UnquotedLHS = true; break; | ||||
1368 | case FILTER: Result = "!filter"; UnquotedLHS = true; break; | ||||
1369 | case IF: Result = "!if"; break; | ||||
1370 | case DAG: Result = "!dag"; break; | ||||
1371 | } | ||||
1372 | return (Result + "(" + | ||||
1373 | (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) + | ||||
1374 | ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")"); | ||||
1375 | } | ||||
1376 | |||||
1377 | static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *A, Init *B, | ||||
1378 | Init *Start, Init *List, Init *Expr, | ||||
1379 | RecTy *Type) { | ||||
1380 | ID.AddPointer(Start); | ||||
1381 | ID.AddPointer(List); | ||||
1382 | ID.AddPointer(A); | ||||
1383 | ID.AddPointer(B); | ||||
1384 | ID.AddPointer(Expr); | ||||
1385 | ID.AddPointer(Type); | ||||
1386 | } | ||||
1387 | |||||
1388 | FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B, | ||||
1389 | Init *Expr, RecTy *Type) { | ||||
1390 | static FoldingSet<FoldOpInit> ThePool; | ||||
1391 | |||||
1392 | FoldingSetNodeID ID; | ||||
1393 | ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type); | ||||
1394 | |||||
1395 | void *IP = nullptr; | ||||
1396 | if (FoldOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
1397 | return I; | ||||
1398 | |||||
1399 | FoldOpInit *I = new (Allocator) FoldOpInit(Start, List, A, B, Expr, Type); | ||||
1400 | ThePool.InsertNode(I, IP); | ||||
1401 | return I; | ||||
1402 | } | ||||
1403 | |||||
1404 | void FoldOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
1405 | ProfileFoldOpInit(ID, Start, List, A, B, Expr, getType()); | ||||
1406 | } | ||||
1407 | |||||
1408 | Init *FoldOpInit::Fold(Record *CurRec) const { | ||||
1409 | if (ListInit *LI = dyn_cast<ListInit>(List)) { | ||||
1410 | Init *Accum = Start; | ||||
1411 | for (Init *Elt : *LI) { | ||||
1412 | MapResolver R(CurRec); | ||||
1413 | R.set(A, Accum); | ||||
1414 | R.set(B, Elt); | ||||
1415 | Accum = Expr->resolveReferences(R); | ||||
1416 | } | ||||
1417 | return Accum; | ||||
1418 | } | ||||
1419 | return const_cast<FoldOpInit *>(this); | ||||
1420 | } | ||||
1421 | |||||
1422 | Init *FoldOpInit::resolveReferences(Resolver &R) const { | ||||
1423 | Init *NewStart = Start->resolveReferences(R); | ||||
1424 | Init *NewList = List->resolveReferences(R); | ||||
1425 | ShadowResolver SR(R); | ||||
1426 | SR.addShadow(A); | ||||
1427 | SR.addShadow(B); | ||||
1428 | Init *NewExpr = Expr->resolveReferences(SR); | ||||
1429 | |||||
1430 | if (Start == NewStart && List == NewList && Expr == NewExpr) | ||||
1431 | return const_cast<FoldOpInit *>(this); | ||||
1432 | |||||
1433 | return get(NewStart, NewList, A, B, NewExpr, getType()) | ||||
1434 | ->Fold(R.getCurrentRecord()); | ||||
1435 | } | ||||
1436 | |||||
1437 | Init *FoldOpInit::getBit(unsigned Bit) const { | ||||
1438 | return VarBitInit::get(const_cast<FoldOpInit *>(this), Bit); | ||||
1439 | } | ||||
1440 | |||||
1441 | std::string FoldOpInit::getAsString() const { | ||||
1442 | return (Twine("!foldl(") + Start->getAsString() + ", " + List->getAsString() + | ||||
1443 | ", " + A->getAsUnquotedString() + ", " + B->getAsUnquotedString() + | ||||
1444 | ", " + Expr->getAsString() + ")") | ||||
1445 | .str(); | ||||
1446 | } | ||||
1447 | |||||
1448 | static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType, | ||||
1449 | Init *Expr) { | ||||
1450 | ID.AddPointer(CheckType); | ||||
1451 | ID.AddPointer(Expr); | ||||
1452 | } | ||||
1453 | |||||
1454 | IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) { | ||||
1455 | static FoldingSet<IsAOpInit> ThePool; | ||||
1456 | |||||
1457 | FoldingSetNodeID ID; | ||||
1458 | ProfileIsAOpInit(ID, CheckType, Expr); | ||||
1459 | |||||
1460 | void *IP = nullptr; | ||||
1461 | if (IsAOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
1462 | return I; | ||||
1463 | |||||
1464 | IsAOpInit *I = new (Allocator) IsAOpInit(CheckType, Expr); | ||||
1465 | ThePool.InsertNode(I, IP); | ||||
1466 | return I; | ||||
1467 | } | ||||
1468 | |||||
1469 | void IsAOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
1470 | ProfileIsAOpInit(ID, CheckType, Expr); | ||||
1471 | } | ||||
1472 | |||||
1473 | Init *IsAOpInit::Fold() const { | ||||
1474 | if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) { | ||||
1475 | // Is the expression type known to be (a subclass of) the desired type? | ||||
1476 | if (TI->getType()->typeIsConvertibleTo(CheckType)) | ||||
1477 | return IntInit::get(1); | ||||
1478 | |||||
1479 | if (isa<RecordRecTy>(CheckType)) { | ||||
1480 | // If the target type is not a subclass of the expression type, or if | ||||
1481 | // the expression has fully resolved to a record, we know that it can't | ||||
1482 | // be of the required type. | ||||
1483 | if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr)) | ||||
1484 | return IntInit::get(0); | ||||
1485 | } else { | ||||
1486 | // We treat non-record types as not castable. | ||||
1487 | return IntInit::get(0); | ||||
1488 | } | ||||
1489 | } | ||||
1490 | return const_cast<IsAOpInit *>(this); | ||||
1491 | } | ||||
1492 | |||||
1493 | Init *IsAOpInit::resolveReferences(Resolver &R) const { | ||||
1494 | Init *NewExpr = Expr->resolveReferences(R); | ||||
1495 | if (Expr != NewExpr) | ||||
1496 | return get(CheckType, NewExpr)->Fold(); | ||||
1497 | return const_cast<IsAOpInit *>(this); | ||||
1498 | } | ||||
1499 | |||||
1500 | Init *IsAOpInit::getBit(unsigned Bit) const { | ||||
1501 | return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit); | ||||
1502 | } | ||||
1503 | |||||
1504 | std::string IsAOpInit::getAsString() const { | ||||
1505 | return (Twine("!isa<") + CheckType->getAsString() + ">(" + | ||||
1506 | Expr->getAsString() + ")") | ||||
1507 | .str(); | ||||
1508 | } | ||||
1509 | |||||
1510 | RecTy *TypedInit::getFieldType(StringInit *FieldName) const { | ||||
1511 | if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) { | ||||
1512 | for (Record *Rec : RecordType->getClasses()) { | ||||
1513 | if (RecordVal *Field = Rec->getValue(FieldName)) | ||||
1514 | return Field->getType(); | ||||
1515 | } | ||||
1516 | } | ||||
1517 | return nullptr; | ||||
1518 | } | ||||
1519 | |||||
1520 | Init * | ||||
1521 | TypedInit::convertInitializerTo(RecTy *Ty) const { | ||||
1522 | if (getType() == Ty || getType()->typeIsA(Ty)) | ||||
1523 | return const_cast<TypedInit *>(this); | ||||
1524 | |||||
1525 | if (isa<BitRecTy>(getType()) && isa<BitsRecTy>(Ty) && | ||||
1526 | cast<BitsRecTy>(Ty)->getNumBits() == 1) | ||||
1527 | return BitsInit::get({const_cast<TypedInit *>(this)}); | ||||
1528 | |||||
1529 | return nullptr; | ||||
1530 | } | ||||
1531 | |||||
1532 | Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { | ||||
1533 | BitsRecTy *T = dyn_cast<BitsRecTy>(getType()); | ||||
1534 | if (!T) return nullptr; // Cannot subscript a non-bits variable. | ||||
1535 | unsigned NumBits = T->getNumBits(); | ||||
1536 | |||||
1537 | SmallVector<Init *, 16> NewBits; | ||||
1538 | NewBits.reserve(Bits.size()); | ||||
1539 | for (unsigned Bit : Bits) { | ||||
1540 | if (Bit >= NumBits) | ||||
1541 | return nullptr; | ||||
1542 | |||||
1543 | NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit)); | ||||
1544 | } | ||||
1545 | return BitsInit::get(NewBits); | ||||
1546 | } | ||||
1547 | |||||
1548 | Init *TypedInit::getCastTo(RecTy *Ty) const { | ||||
1549 | // Handle the common case quickly | ||||
1550 | if (getType() == Ty || getType()->typeIsA(Ty)) | ||||
1551 | return const_cast<TypedInit *>(this); | ||||
1552 | |||||
1553 | if (Init *Converted = convertInitializerTo(Ty)) { | ||||
1554 | assert(!isa<TypedInit>(Converted) ||((!isa<TypedInit>(Converted) || cast<TypedInit>(Converted )->getType()->typeIsA(Ty)) ? static_cast<void> (0 ) : __assert_fail ("!isa<TypedInit>(Converted) || cast<TypedInit>(Converted)->getType()->typeIsA(Ty)" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1555, __PRETTY_FUNCTION__)) | ||||
1555 | cast<TypedInit>(Converted)->getType()->typeIsA(Ty))((!isa<TypedInit>(Converted) || cast<TypedInit>(Converted )->getType()->typeIsA(Ty)) ? static_cast<void> (0 ) : __assert_fail ("!isa<TypedInit>(Converted) || cast<TypedInit>(Converted)->getType()->typeIsA(Ty)" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1555, __PRETTY_FUNCTION__)); | ||||
1556 | return Converted; | ||||
1557 | } | ||||
1558 | |||||
1559 | if (!getType()->typeIsConvertibleTo(Ty)) | ||||
1560 | return nullptr; | ||||
1561 | |||||
1562 | return UnOpInit::get(UnOpInit::CAST, const_cast<TypedInit *>(this), Ty) | ||||
1563 | ->Fold(nullptr); | ||||
1564 | } | ||||
1565 | |||||
1566 | Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const { | ||||
1567 | ListRecTy *T = dyn_cast<ListRecTy>(getType()); | ||||
1568 | if (!T) return nullptr; // Cannot subscript a non-list variable. | ||||
1569 | |||||
1570 | if (Elements.size() == 1) | ||||
1571 | return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]); | ||||
1572 | |||||
1573 | SmallVector<Init*, 8> ListInits; | ||||
1574 | ListInits.reserve(Elements.size()); | ||||
1575 | for (unsigned Element : Elements) | ||||
1576 | ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this), | ||||
1577 | Element)); | ||||
1578 | return ListInit::get(ListInits, T->getElementType()); | ||||
1579 | } | ||||
1580 | |||||
1581 | |||||
1582 | VarInit *VarInit::get(StringRef VN, RecTy *T) { | ||||
1583 | Init *Value = StringInit::get(VN); | ||||
1584 | return VarInit::get(Value, T); | ||||
1585 | } | ||||
1586 | |||||
1587 | VarInit *VarInit::get(Init *VN, RecTy *T) { | ||||
1588 | using Key = std::pair<RecTy *, Init *>; | ||||
1589 | static DenseMap<Key, VarInit*> ThePool; | ||||
1590 | |||||
1591 | Key TheKey(std::make_pair(T, VN)); | ||||
1592 | |||||
1593 | VarInit *&I = ThePool[TheKey]; | ||||
1594 | if (!I) | ||||
1595 | I = new(Allocator) VarInit(VN, T); | ||||
1596 | return I; | ||||
1597 | } | ||||
1598 | |||||
1599 | StringRef VarInit::getName() const { | ||||
1600 | StringInit *NameString = cast<StringInit>(getNameInit()); | ||||
1601 | return NameString->getValue(); | ||||
1602 | } | ||||
1603 | |||||
1604 | Init *VarInit::getBit(unsigned Bit) const { | ||||
1605 | if (getType() == BitRecTy::get()) | ||||
1606 | return const_cast<VarInit*>(this); | ||||
1607 | return VarBitInit::get(const_cast<VarInit*>(this), Bit); | ||||
1608 | } | ||||
1609 | |||||
1610 | Init *VarInit::resolveReferences(Resolver &R) const { | ||||
1611 | if (Init *Val = R.resolve(VarName)) | ||||
1612 | return Val; | ||||
1613 | return const_cast<VarInit *>(this); | ||||
1614 | } | ||||
1615 | |||||
1616 | VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { | ||||
1617 | using Key = std::pair<TypedInit *, unsigned>; | ||||
1618 | static DenseMap<Key, VarBitInit*> ThePool; | ||||
1619 | |||||
1620 | Key TheKey(std::make_pair(T, B)); | ||||
1621 | |||||
1622 | VarBitInit *&I = ThePool[TheKey]; | ||||
1623 | if (!I) | ||||
1624 | I = new(Allocator) VarBitInit(T, B); | ||||
1625 | return I; | ||||
1626 | } | ||||
1627 | |||||
1628 | std::string VarBitInit::getAsString() const { | ||||
1629 | return TI->getAsString() + "{" + utostr(Bit) + "}"; | ||||
1630 | } | ||||
1631 | |||||
1632 | Init *VarBitInit::resolveReferences(Resolver &R) const { | ||||
1633 | Init *I = TI->resolveReferences(R); | ||||
1634 | if (TI != I) | ||||
1635 | return I->getBit(getBitNum()); | ||||
1636 | |||||
1637 | return const_cast<VarBitInit*>(this); | ||||
1638 | } | ||||
1639 | |||||
1640 | VarListElementInit *VarListElementInit::get(TypedInit *T, | ||||
1641 | unsigned E) { | ||||
1642 | using Key = std::pair<TypedInit *, unsigned>; | ||||
1643 | static DenseMap<Key, VarListElementInit*> ThePool; | ||||
1644 | |||||
1645 | Key TheKey(std::make_pair(T, E)); | ||||
1646 | |||||
1647 | VarListElementInit *&I = ThePool[TheKey]; | ||||
1648 | if (!I) I = new(Allocator) VarListElementInit(T, E); | ||||
1649 | return I; | ||||
1650 | } | ||||
1651 | |||||
1652 | std::string VarListElementInit::getAsString() const { | ||||
1653 | return TI->getAsString() + "[" + utostr(Element) + "]"; | ||||
1654 | } | ||||
1655 | |||||
1656 | Init *VarListElementInit::resolveReferences(Resolver &R) const { | ||||
1657 | Init *NewTI = TI->resolveReferences(R); | ||||
1658 | if (ListInit *List = dyn_cast<ListInit>(NewTI)) { | ||||
1659 | // Leave out-of-bounds array references as-is. This can happen without | ||||
1660 | // being an error, e.g. in the untaken "branch" of an !if expression. | ||||
1661 | if (getElementNum() < List->size()) | ||||
1662 | return List->getElement(getElementNum()); | ||||
1663 | } | ||||
1664 | if (NewTI != TI && isa<TypedInit>(NewTI)) | ||||
1665 | return VarListElementInit::get(cast<TypedInit>(NewTI), getElementNum()); | ||||
1666 | return const_cast<VarListElementInit *>(this); | ||||
1667 | } | ||||
1668 | |||||
1669 | Init *VarListElementInit::getBit(unsigned Bit) const { | ||||
1670 | if (getType() == BitRecTy::get()) | ||||
1671 | return const_cast<VarListElementInit*>(this); | ||||
1672 | return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit); | ||||
1673 | } | ||||
1674 | |||||
1675 | DefInit::DefInit(Record *D) | ||||
1676 | : TypedInit(IK_DefInit, D->getType()), Def(D) {} | ||||
1677 | |||||
1678 | DefInit *DefInit::get(Record *R) { | ||||
1679 | return R->getDefInit(); | ||||
1680 | } | ||||
1681 | |||||
1682 | Init *DefInit::convertInitializerTo(RecTy *Ty) const { | ||||
1683 | if (auto *RRT = dyn_cast<RecordRecTy>(Ty)) | ||||
1684 | if (getType()->typeIsConvertibleTo(RRT)) | ||||
1685 | return const_cast<DefInit *>(this); | ||||
1686 | return nullptr; | ||||
1687 | } | ||||
1688 | |||||
1689 | RecTy *DefInit::getFieldType(StringInit *FieldName) const { | ||||
1690 | if (const RecordVal *RV = Def->getValue(FieldName)) | ||||
1691 | return RV->getType(); | ||||
1692 | return nullptr; | ||||
1693 | } | ||||
1694 | |||||
1695 | std::string DefInit::getAsString() const { return std::string(Def->getName()); } | ||||
1696 | |||||
1697 | static void ProfileVarDefInit(FoldingSetNodeID &ID, | ||||
1698 | Record *Class, | ||||
1699 | ArrayRef<Init *> Args) { | ||||
1700 | ID.AddInteger(Args.size()); | ||||
1701 | ID.AddPointer(Class); | ||||
1702 | |||||
1703 | for (Init *I : Args) | ||||
1704 | ID.AddPointer(I); | ||||
1705 | } | ||||
1706 | |||||
1707 | VarDefInit *VarDefInit::get(Record *Class, ArrayRef<Init *> Args) { | ||||
1708 | static FoldingSet<VarDefInit> ThePool; | ||||
1709 | |||||
1710 | FoldingSetNodeID ID; | ||||
1711 | ProfileVarDefInit(ID, Class, Args); | ||||
1712 | |||||
1713 | void *IP = nullptr; | ||||
1714 | if (VarDefInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
1715 | return I; | ||||
1716 | |||||
1717 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Args.size()), | ||||
1718 | alignof(VarDefInit)); | ||||
1719 | VarDefInit *I = new(Mem) VarDefInit(Class, Args.size()); | ||||
1720 | std::uninitialized_copy(Args.begin(), Args.end(), | ||||
1721 | I->getTrailingObjects<Init *>()); | ||||
1722 | ThePool.InsertNode(I, IP); | ||||
1723 | return I; | ||||
1724 | } | ||||
1725 | |||||
1726 | void VarDefInit::Profile(FoldingSetNodeID &ID) const { | ||||
1727 | ProfileVarDefInit(ID, Class, args()); | ||||
1728 | } | ||||
1729 | |||||
1730 | DefInit *VarDefInit::instantiate() { | ||||
1731 | if (!Def) { | ||||
1732 | RecordKeeper &Records = Class->getRecords(); | ||||
1733 | auto NewRecOwner = std::make_unique<Record>(Records.getNewAnonymousName(), | ||||
1734 | Class->getLoc(), Records, | ||||
1735 | /*IsAnonymous=*/true); | ||||
1736 | Record *NewRec = NewRecOwner.get(); | ||||
1737 | |||||
1738 | // Copy values from class to instance | ||||
1739 | for (const RecordVal &Val : Class->getValues()) | ||||
1740 | NewRec->addValue(Val); | ||||
1741 | |||||
1742 | // Substitute and resolve template arguments | ||||
1743 | ArrayRef<Init *> TArgs = Class->getTemplateArgs(); | ||||
1744 | MapResolver R(NewRec); | ||||
1745 | |||||
1746 | for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { | ||||
1747 | if (i < args_size()) | ||||
1748 | R.set(TArgs[i], getArg(i)); | ||||
1749 | else | ||||
1750 | R.set(TArgs[i], NewRec->getValue(TArgs[i])->getValue()); | ||||
1751 | |||||
1752 | NewRec->removeValue(TArgs[i]); | ||||
1753 | } | ||||
1754 | |||||
1755 | NewRec->resolveReferences(R); | ||||
1756 | |||||
1757 | // Add superclasses. | ||||
1758 | ArrayRef<std::pair<Record *, SMRange>> SCs = Class->getSuperClasses(); | ||||
1759 | for (const auto &SCPair : SCs) | ||||
1760 | NewRec->addSuperClass(SCPair.first, SCPair.second); | ||||
1761 | |||||
1762 | NewRec->addSuperClass(Class, | ||||
1763 | SMRange(Class->getLoc().back(), | ||||
1764 | Class->getLoc().back())); | ||||
1765 | |||||
1766 | // Resolve internal references and store in record keeper | ||||
1767 | NewRec->resolveReferences(); | ||||
1768 | Records.addDef(std::move(NewRecOwner)); | ||||
1769 | |||||
1770 | Def = DefInit::get(NewRec); | ||||
1771 | } | ||||
1772 | |||||
1773 | return Def; | ||||
1774 | } | ||||
1775 | |||||
1776 | Init *VarDefInit::resolveReferences(Resolver &R) const { | ||||
1777 | TrackUnresolvedResolver UR(&R); | ||||
1778 | bool Changed = false; | ||||
1779 | SmallVector<Init *, 8> NewArgs; | ||||
1780 | NewArgs.reserve(args_size()); | ||||
1781 | |||||
1782 | for (Init *Arg : args()) { | ||||
1783 | Init *NewArg = Arg->resolveReferences(UR); | ||||
1784 | NewArgs.push_back(NewArg); | ||||
1785 | Changed |= NewArg != Arg; | ||||
1786 | } | ||||
1787 | |||||
1788 | if (Changed) { | ||||
1789 | auto New = VarDefInit::get(Class, NewArgs); | ||||
1790 | if (!UR.foundUnresolved()) | ||||
1791 | return New->instantiate(); | ||||
1792 | return New; | ||||
1793 | } | ||||
1794 | return const_cast<VarDefInit *>(this); | ||||
1795 | } | ||||
1796 | |||||
1797 | Init *VarDefInit::Fold() const { | ||||
1798 | if (Def) | ||||
1799 | return Def; | ||||
1800 | |||||
1801 | TrackUnresolvedResolver R; | ||||
1802 | for (Init *Arg : args()) | ||||
1803 | Arg->resolveReferences(R); | ||||
1804 | |||||
1805 | if (!R.foundUnresolved()) | ||||
1806 | return const_cast<VarDefInit *>(this)->instantiate(); | ||||
1807 | return const_cast<VarDefInit *>(this); | ||||
1808 | } | ||||
1809 | |||||
1810 | std::string VarDefInit::getAsString() const { | ||||
1811 | std::string Result = Class->getNameInitAsString() + "<"; | ||||
1812 | const char *sep = ""; | ||||
1813 | for (Init *Arg : args()) { | ||||
1814 | Result += sep; | ||||
1815 | sep = ", "; | ||||
1816 | Result += Arg->getAsString(); | ||||
1817 | } | ||||
1818 | return Result + ">"; | ||||
1819 | } | ||||
1820 | |||||
1821 | FieldInit *FieldInit::get(Init *R, StringInit *FN) { | ||||
1822 | using Key = std::pair<Init *, StringInit *>; | ||||
1823 | static DenseMap<Key, FieldInit*> ThePool; | ||||
1824 | |||||
1825 | Key TheKey(std::make_pair(R, FN)); | ||||
1826 | |||||
1827 | FieldInit *&I = ThePool[TheKey]; | ||||
1828 | if (!I) I = new(Allocator) FieldInit(R, FN); | ||||
1829 | return I; | ||||
1830 | } | ||||
1831 | |||||
1832 | Init *FieldInit::getBit(unsigned Bit) const { | ||||
1833 | if (getType() == BitRecTy::get()) | ||||
1834 | return const_cast<FieldInit*>(this); | ||||
1835 | return VarBitInit::get(const_cast<FieldInit*>(this), Bit); | ||||
1836 | } | ||||
1837 | |||||
1838 | Init *FieldInit::resolveReferences(Resolver &R) const { | ||||
1839 | Init *NewRec = Rec->resolveReferences(R); | ||||
1840 | if (NewRec != Rec) | ||||
1841 | return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord()); | ||||
1842 | return const_cast<FieldInit *>(this); | ||||
1843 | } | ||||
1844 | |||||
1845 | Init *FieldInit::Fold(Record *CurRec) const { | ||||
1846 | if (DefInit *DI = dyn_cast<DefInit>(Rec)) { | ||||
1847 | Record *Def = DI->getDef(); | ||||
1848 | if (Def == CurRec) | ||||
1849 | PrintFatalError(CurRec->getLoc(), | ||||
1850 | Twine("Attempting to access field '") + | ||||
1851 | FieldName->getAsUnquotedString() + "' of '" + | ||||
1852 | Rec->getAsString() + "' is a forbidden self-reference"); | ||||
1853 | Init *FieldVal = Def->getValue(FieldName)->getValue(); | ||||
1854 | if (FieldVal->isComplete()) | ||||
1855 | return FieldVal; | ||||
1856 | } | ||||
1857 | return const_cast<FieldInit *>(this); | ||||
1858 | } | ||||
1859 | |||||
1860 | bool FieldInit::isConcrete() const { | ||||
1861 | if (DefInit *DI = dyn_cast<DefInit>(Rec)) { | ||||
1862 | Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue(); | ||||
1863 | return FieldVal->isConcrete(); | ||||
1864 | } | ||||
1865 | return false; | ||||
1866 | } | ||||
1867 | |||||
1868 | static void ProfileCondOpInit(FoldingSetNodeID &ID, | ||||
1869 | ArrayRef<Init *> CondRange, | ||||
1870 | ArrayRef<Init *> ValRange, | ||||
1871 | const RecTy *ValType) { | ||||
1872 | assert(CondRange.size() == ValRange.size() &&((CondRange.size() == ValRange.size() && "Number of conditions and values must match!" ) ? static_cast<void> (0) : __assert_fail ("CondRange.size() == ValRange.size() && \"Number of conditions and values must match!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1873, __PRETTY_FUNCTION__)) | ||||
1873 | "Number of conditions and values must match!")((CondRange.size() == ValRange.size() && "Number of conditions and values must match!" ) ? static_cast<void> (0) : __assert_fail ("CondRange.size() == ValRange.size() && \"Number of conditions and values must match!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1873, __PRETTY_FUNCTION__)); | ||||
1874 | ID.AddPointer(ValType); | ||||
1875 | ArrayRef<Init *>::iterator Case = CondRange.begin(); | ||||
1876 | ArrayRef<Init *>::iterator Val = ValRange.begin(); | ||||
1877 | |||||
1878 | while (Case != CondRange.end()) { | ||||
1879 | ID.AddPointer(*Case++); | ||||
1880 | ID.AddPointer(*Val++); | ||||
1881 | } | ||||
1882 | } | ||||
1883 | |||||
1884 | void CondOpInit::Profile(FoldingSetNodeID &ID) const { | ||||
1885 | ProfileCondOpInit(ID, | ||||
1886 | makeArrayRef(getTrailingObjects<Init *>(), NumConds), | ||||
1887 | makeArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds), | ||||
1888 | ValType); | ||||
1889 | } | ||||
1890 | |||||
1891 | CondOpInit * | ||||
1892 | CondOpInit::get(ArrayRef<Init *> CondRange, | ||||
1893 | ArrayRef<Init *> ValRange, RecTy *Ty) { | ||||
1894 | assert(CondRange.size() == ValRange.size() &&((CondRange.size() == ValRange.size() && "Number of conditions and values must match!" ) ? static_cast<void> (0) : __assert_fail ("CondRange.size() == ValRange.size() && \"Number of conditions and values must match!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1895, __PRETTY_FUNCTION__)) | ||||
1895 | "Number of conditions and values must match!")((CondRange.size() == ValRange.size() && "Number of conditions and values must match!" ) ? static_cast<void> (0) : __assert_fail ("CondRange.size() == ValRange.size() && \"Number of conditions and values must match!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 1895, __PRETTY_FUNCTION__)); | ||||
1896 | |||||
1897 | static FoldingSet<CondOpInit> ThePool; | ||||
1898 | FoldingSetNodeID ID; | ||||
1899 | ProfileCondOpInit(ID, CondRange, ValRange, Ty); | ||||
1900 | |||||
1901 | void *IP = nullptr; | ||||
1902 | if (CondOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
1903 | return I; | ||||
1904 | |||||
1905 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(2*CondRange.size()), | ||||
1906 | alignof(BitsInit)); | ||||
1907 | CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty); | ||||
1908 | |||||
1909 | std::uninitialized_copy(CondRange.begin(), CondRange.end(), | ||||
1910 | I->getTrailingObjects<Init *>()); | ||||
1911 | std::uninitialized_copy(ValRange.begin(), ValRange.end(), | ||||
1912 | I->getTrailingObjects<Init *>()+CondRange.size()); | ||||
1913 | ThePool.InsertNode(I, IP); | ||||
1914 | return I; | ||||
1915 | } | ||||
1916 | |||||
1917 | Init *CondOpInit::resolveReferences(Resolver &R) const { | ||||
1918 | SmallVector<Init*, 4> NewConds; | ||||
1919 | bool Changed = false; | ||||
1920 | for (const Init *Case : getConds()) { | ||||
1921 | Init *NewCase = Case->resolveReferences(R); | ||||
1922 | NewConds.push_back(NewCase); | ||||
1923 | Changed |= NewCase != Case; | ||||
1924 | } | ||||
1925 | |||||
1926 | SmallVector<Init*, 4> NewVals; | ||||
1927 | for (const Init *Val : getVals()) { | ||||
1928 | Init *NewVal = Val->resolveReferences(R); | ||||
1929 | NewVals.push_back(NewVal); | ||||
1930 | Changed |= NewVal != Val; | ||||
1931 | } | ||||
1932 | |||||
1933 | if (Changed) | ||||
1934 | return (CondOpInit::get(NewConds, NewVals, | ||||
1935 | getValType()))->Fold(R.getCurrentRecord()); | ||||
1936 | |||||
1937 | return const_cast<CondOpInit *>(this); | ||||
1938 | } | ||||
1939 | |||||
1940 | Init *CondOpInit::Fold(Record *CurRec) const { | ||||
1941 | for ( unsigned i = 0; i < NumConds; ++i) { | ||||
1942 | Init *Cond = getCond(i); | ||||
1943 | Init *Val = getVal(i); | ||||
1944 | |||||
1945 | if (IntInit *CondI = dyn_cast_or_null<IntInit>( | ||||
1946 | Cond->convertInitializerTo(IntRecTy::get()))) { | ||||
1947 | if (CondI->getValue()) | ||||
1948 | return Val->convertInitializerTo(getValType()); | ||||
1949 | } else | ||||
1950 | return const_cast<CondOpInit *>(this); | ||||
1951 | } | ||||
1952 | |||||
1953 | PrintFatalError(CurRec->getLoc(), | ||||
1954 | CurRec->getName() + | ||||
1955 | " does not have any true condition in:" + | ||||
1956 | this->getAsString()); | ||||
1957 | return nullptr; | ||||
1958 | } | ||||
1959 | |||||
1960 | bool CondOpInit::isConcrete() const { | ||||
1961 | for (const Init *Case : getConds()) | ||||
1962 | if (!Case->isConcrete()) | ||||
1963 | return false; | ||||
1964 | |||||
1965 | for (const Init *Val : getVals()) | ||||
1966 | if (!Val->isConcrete()) | ||||
1967 | return false; | ||||
1968 | |||||
1969 | return true; | ||||
1970 | } | ||||
1971 | |||||
1972 | bool CondOpInit::isComplete() const { | ||||
1973 | for (const Init *Case : getConds()) | ||||
1974 | if (!Case->isComplete()) | ||||
1975 | return false; | ||||
1976 | |||||
1977 | for (const Init *Val : getVals()) | ||||
1978 | if (!Val->isConcrete()) | ||||
1979 | return false; | ||||
1980 | |||||
1981 | return true; | ||||
1982 | } | ||||
1983 | |||||
1984 | std::string CondOpInit::getAsString() const { | ||||
1985 | std::string Result = "!cond("; | ||||
1986 | for (unsigned i = 0; i < getNumConds(); i++) { | ||||
1987 | Result += getCond(i)->getAsString() + ": "; | ||||
1988 | Result += getVal(i)->getAsString(); | ||||
1989 | if (i != getNumConds()-1) | ||||
1990 | Result += ", "; | ||||
1991 | } | ||||
1992 | return Result + ")"; | ||||
1993 | } | ||||
1994 | |||||
1995 | Init *CondOpInit::getBit(unsigned Bit) const { | ||||
1996 | return VarBitInit::get(const_cast<CondOpInit *>(this), Bit); | ||||
1997 | } | ||||
1998 | |||||
1999 | static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN, | ||||
2000 | ArrayRef<Init *> ArgRange, | ||||
2001 | ArrayRef<StringInit *> NameRange) { | ||||
2002 | ID.AddPointer(V); | ||||
2003 | ID.AddPointer(VN); | ||||
2004 | |||||
2005 | ArrayRef<Init *>::iterator Arg = ArgRange.begin(); | ||||
2006 | ArrayRef<StringInit *>::iterator Name = NameRange.begin(); | ||||
2007 | while (Arg != ArgRange.end()) { | ||||
2008 | assert(Name != NameRange.end() && "Arg name underflow!")((Name != NameRange.end() && "Arg name underflow!") ? static_cast<void> (0) : __assert_fail ("Name != NameRange.end() && \"Arg name underflow!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2008, __PRETTY_FUNCTION__)); | ||||
2009 | ID.AddPointer(*Arg++); | ||||
2010 | ID.AddPointer(*Name++); | ||||
2011 | } | ||||
2012 | assert(Name == NameRange.end() && "Arg name overflow!")((Name == NameRange.end() && "Arg name overflow!") ? static_cast <void> (0) : __assert_fail ("Name == NameRange.end() && \"Arg name overflow!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2012, __PRETTY_FUNCTION__)); | ||||
2013 | } | ||||
2014 | |||||
2015 | DagInit * | ||||
2016 | DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, | ||||
2017 | ArrayRef<StringInit *> NameRange) { | ||||
2018 | static FoldingSet<DagInit> ThePool; | ||||
2019 | |||||
2020 | FoldingSetNodeID ID; | ||||
2021 | ProfileDagInit(ID, V, VN, ArgRange, NameRange); | ||||
2022 | |||||
2023 | void *IP = nullptr; | ||||
2024 | if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) | ||||
2025 | return I; | ||||
2026 | |||||
2027 | void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()), alignof(BitsInit)); | ||||
2028 | DagInit *I = new(Mem) DagInit(V, VN, ArgRange.size(), NameRange.size()); | ||||
2029 | std::uninitialized_copy(ArgRange.begin(), ArgRange.end(), | ||||
2030 | I->getTrailingObjects<Init *>()); | ||||
2031 | std::uninitialized_copy(NameRange.begin(), NameRange.end(), | ||||
2032 | I->getTrailingObjects<StringInit *>()); | ||||
2033 | ThePool.InsertNode(I, IP); | ||||
2034 | return I; | ||||
2035 | } | ||||
2036 | |||||
2037 | DagInit * | ||||
2038 | DagInit::get(Init *V, StringInit *VN, | ||||
2039 | ArrayRef<std::pair<Init*, StringInit*>> args) { | ||||
2040 | SmallVector<Init *, 8> Args; | ||||
2041 | SmallVector<StringInit *, 8> Names; | ||||
2042 | |||||
2043 | for (const auto &Arg : args) { | ||||
2044 | Args.push_back(Arg.first); | ||||
2045 | Names.push_back(Arg.second); | ||||
2046 | } | ||||
2047 | |||||
2048 | return DagInit::get(V, VN, Args, Names); | ||||
2049 | } | ||||
2050 | |||||
2051 | void DagInit::Profile(FoldingSetNodeID &ID) const { | ||||
2052 | ProfileDagInit(ID, Val, ValName, makeArrayRef(getTrailingObjects<Init *>(), NumArgs), makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames)); | ||||
2053 | } | ||||
2054 | |||||
2055 | Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const { | ||||
2056 | if (DefInit *DefI = dyn_cast<DefInit>(Val)) | ||||
2057 | return DefI->getDef(); | ||||
2058 | PrintFatalError(Loc, "Expected record as operator"); | ||||
2059 | return nullptr; | ||||
2060 | } | ||||
2061 | |||||
2062 | Init *DagInit::resolveReferences(Resolver &R) const { | ||||
2063 | SmallVector<Init*, 8> NewArgs; | ||||
2064 | NewArgs.reserve(arg_size()); | ||||
2065 | bool ArgsChanged = false; | ||||
2066 | for (const Init *Arg : getArgs()) { | ||||
2067 | Init *NewArg = Arg->resolveReferences(R); | ||||
2068 | NewArgs.push_back(NewArg); | ||||
2069 | ArgsChanged |= NewArg != Arg; | ||||
2070 | } | ||||
2071 | |||||
2072 | Init *Op = Val->resolveReferences(R); | ||||
2073 | if (Op != Val || ArgsChanged) | ||||
2074 | return DagInit::get(Op, ValName, NewArgs, getArgNames()); | ||||
2075 | |||||
2076 | return const_cast<DagInit *>(this); | ||||
2077 | } | ||||
2078 | |||||
2079 | bool DagInit::isConcrete() const { | ||||
2080 | if (!Val->isConcrete()) | ||||
2081 | return false; | ||||
2082 | for (const Init *Elt : getArgs()) { | ||||
2083 | if (!Elt->isConcrete()) | ||||
2084 | return false; | ||||
2085 | } | ||||
2086 | return true; | ||||
2087 | } | ||||
2088 | |||||
2089 | std::string DagInit::getAsString() const { | ||||
2090 | std::string Result = "(" + Val->getAsString(); | ||||
2091 | if (ValName) | ||||
2092 | Result += ":" + ValName->getAsUnquotedString(); | ||||
2093 | if (!arg_empty()) { | ||||
2094 | Result += " " + getArg(0)->getAsString(); | ||||
2095 | if (getArgName(0)) Result += ":$" + getArgName(0)->getAsUnquotedString(); | ||||
2096 | for (unsigned i = 1, e = getNumArgs(); i != e; ++i) { | ||||
2097 | Result += ", " + getArg(i)->getAsString(); | ||||
2098 | if (getArgName(i)) Result += ":$" + getArgName(i)->getAsUnquotedString(); | ||||
2099 | } | ||||
2100 | } | ||||
2101 | return Result + ")"; | ||||
2102 | } | ||||
2103 | |||||
2104 | //===----------------------------------------------------------------------===// | ||||
2105 | // Other implementations | ||||
2106 | //===----------------------------------------------------------------------===// | ||||
2107 | |||||
2108 | RecordVal::RecordVal(Init *N, RecTy *T, bool P) | ||||
2109 | : Name(N), TyAndPrefix(T, P) { | ||||
2110 | setValue(UnsetInit::get()); | ||||
2111 | assert(Value && "Cannot create unset value for current type!")((Value && "Cannot create unset value for current type!" ) ? static_cast<void> (0) : __assert_fail ("Value && \"Cannot create unset value for current type!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2111, __PRETTY_FUNCTION__)); | ||||
2112 | } | ||||
2113 | |||||
2114 | // This constructor accepts the same arguments as the above, but also | ||||
2115 | // a source location. | ||||
2116 | RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P) | ||||
2117 | : Name(N), Loc(Loc), TyAndPrefix(T, P) { | ||||
2118 | setValue(UnsetInit::get()); | ||||
2119 | assert(Value && "Cannot create unset value for current type!")((Value && "Cannot create unset value for current type!" ) ? static_cast<void> (0) : __assert_fail ("Value && \"Cannot create unset value for current type!\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2119, __PRETTY_FUNCTION__)); | ||||
2120 | } | ||||
2121 | |||||
2122 | StringRef RecordVal::getName() const { | ||||
2123 | return cast<StringInit>(getNameInit())->getValue(); | ||||
2124 | } | ||||
2125 | |||||
2126 | std::string RecordVal::getPrintType() const { | ||||
2127 | if (getType() == StringRecTy::get()) { | ||||
2128 | if (auto *StrInit = dyn_cast<StringInit>(Value)) { | ||||
2129 | if (StrInit->hasCodeFormat()) | ||||
2130 | return "code"; | ||||
2131 | else | ||||
2132 | return "string"; | ||||
2133 | } else { | ||||
2134 | return "string"; | ||||
2135 | } | ||||
2136 | } else { | ||||
2137 | return TyAndPrefix.getPointer()->getAsString(); | ||||
2138 | } | ||||
2139 | } | ||||
2140 | |||||
2141 | bool RecordVal::setValue(Init *V) { | ||||
2142 | if (V) { | ||||
2143 | Value = V->getCastTo(getType()); | ||||
2144 | if (Value) { | ||||
2145 | assert(!isa<TypedInit>(Value) ||((!isa<TypedInit>(Value) || cast<TypedInit>(Value )->getType()->typeIsA(getType())) ? static_cast<void > (0) : __assert_fail ("!isa<TypedInit>(Value) || cast<TypedInit>(Value)->getType()->typeIsA(getType())" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2146, __PRETTY_FUNCTION__)) | ||||
2146 | cast<TypedInit>(Value)->getType()->typeIsA(getType()))((!isa<TypedInit>(Value) || cast<TypedInit>(Value )->getType()->typeIsA(getType())) ? static_cast<void > (0) : __assert_fail ("!isa<TypedInit>(Value) || cast<TypedInit>(Value)->getType()->typeIsA(getType())" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2146, __PRETTY_FUNCTION__)); | ||||
2147 | if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) { | ||||
2148 | if (!isa<BitsInit>(Value)) { | ||||
2149 | SmallVector<Init *, 64> Bits; | ||||
2150 | Bits.reserve(BTy->getNumBits()); | ||||
2151 | for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I) | ||||
2152 | Bits.push_back(Value->getBit(I)); | ||||
2153 | Value = BitsInit::get(Bits); | ||||
2154 | } | ||||
2155 | } | ||||
2156 | } | ||||
2157 | return Value == nullptr; | ||||
2158 | } | ||||
2159 | Value = nullptr; | ||||
2160 | return false; | ||||
2161 | } | ||||
2162 | |||||
2163 | // This version of setValue takes a source location and resets the | ||||
2164 | // location in the RecordVal. | ||||
2165 | bool RecordVal::setValue(Init *V, SMLoc NewLoc) { | ||||
2166 | Loc = NewLoc; | ||||
2167 | if (V) { | ||||
2168 | Value = V->getCastTo(getType()); | ||||
2169 | if (Value) { | ||||
2170 | assert(!isa<TypedInit>(Value) ||((!isa<TypedInit>(Value) || cast<TypedInit>(Value )->getType()->typeIsA(getType())) ? static_cast<void > (0) : __assert_fail ("!isa<TypedInit>(Value) || cast<TypedInit>(Value)->getType()->typeIsA(getType())" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2171, __PRETTY_FUNCTION__)) | ||||
2171 | cast<TypedInit>(Value)->getType()->typeIsA(getType()))((!isa<TypedInit>(Value) || cast<TypedInit>(Value )->getType()->typeIsA(getType())) ? static_cast<void > (0) : __assert_fail ("!isa<TypedInit>(Value) || cast<TypedInit>(Value)->getType()->typeIsA(getType())" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2171, __PRETTY_FUNCTION__)); | ||||
2172 | if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) { | ||||
2173 | if (!isa<BitsInit>(Value)) { | ||||
2174 | SmallVector<Init *, 64> Bits; | ||||
2175 | Bits.reserve(BTy->getNumBits()); | ||||
2176 | for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I) | ||||
2177 | Bits.push_back(Value->getBit(I)); | ||||
2178 | Value = BitsInit::get(Bits); | ||||
2179 | } | ||||
2180 | } | ||||
2181 | } | ||||
2182 | return Value == nullptr; | ||||
2183 | } | ||||
2184 | Value = nullptr; | ||||
2185 | return false; | ||||
2186 | } | ||||
2187 | |||||
2188 | #include "llvm/TableGen/Record.h" | ||||
2189 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
2190 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void RecordVal::dump() const { errs() << *this; } | ||||
2191 | #endif | ||||
2192 | |||||
2193 | void RecordVal::print(raw_ostream &OS, bool PrintSem) const { | ||||
2194 | if (getPrefix()) OS << "field "; | ||||
2195 | OS << getPrintType() << " " << getNameInitAsString(); | ||||
2196 | |||||
2197 | if (getValue()) | ||||
2198 | OS << " = " << *getValue(); | ||||
2199 | |||||
2200 | if (PrintSem) OS << ";\n"; | ||||
2201 | } | ||||
2202 | |||||
2203 | unsigned Record::LastID = 0; | ||||
2204 | |||||
2205 | void Record::checkName() { | ||||
2206 | // Ensure the record name has string type. | ||||
2207 | const TypedInit *TypedName = cast<const TypedInit>(Name); | ||||
2208 | if (!isa<StringRecTy>(TypedName->getType())) | ||||
2209 | PrintFatalError(getLoc(), Twine("Record name '") + Name->getAsString() + | ||||
2210 | "' is not a string!"); | ||||
2211 | } | ||||
2212 | |||||
2213 | RecordRecTy *Record::getType() { | ||||
2214 | SmallVector<Record *, 4> DirectSCs; | ||||
2215 | getDirectSuperClasses(DirectSCs); | ||||
2216 | return RecordRecTy::get(DirectSCs); | ||||
2217 | } | ||||
2218 | |||||
2219 | DefInit *Record::getDefInit() { | ||||
2220 | if (!CorrespondingDefInit) | ||||
2221 | CorrespondingDefInit = new (Allocator) DefInit(this); | ||||
2222 | return CorrespondingDefInit; | ||||
2223 | } | ||||
2224 | |||||
2225 | void Record::setName(Init *NewName) { | ||||
2226 | Name = NewName; | ||||
2227 | checkName(); | ||||
2228 | // DO NOT resolve record values to the name at this point because | ||||
2229 | // there might be default values for arguments of this def. Those | ||||
2230 | // arguments might not have been resolved yet so we don't want to | ||||
2231 | // prematurely assume values for those arguments were not passed to | ||||
2232 | // this def. | ||||
2233 | // | ||||
2234 | // Nonetheless, it may be that some of this Record's values | ||||
2235 | // reference the record name. Indeed, the reason for having the | ||||
2236 | // record name be an Init is to provide this flexibility. The extra | ||||
2237 | // resolve steps after completely instantiating defs takes care of | ||||
2238 | // this. See TGParser::ParseDef and TGParser::ParseDefm. | ||||
2239 | } | ||||
2240 | |||||
2241 | // NOTE for the next two functions: | ||||
2242 | // Superclasses are in post-order, so the final one is a direct | ||||
2243 | // superclass. All of its transitive superclases immediately precede it, | ||||
2244 | // so we can step through the direct superclasses in reverse order. | ||||
2245 | |||||
2246 | bool Record::hasDirectSuperClass(const Record *Superclass) const { | ||||
2247 | ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses(); | ||||
2248 | |||||
2249 | for (int I = SCs.size() - 1; I >= 0; --I) { | ||||
2250 | const Record *SC = SCs[I].first; | ||||
2251 | if (SC == Superclass) | ||||
2252 | return true; | ||||
2253 | I -= SC->getSuperClasses().size(); | ||||
2254 | } | ||||
2255 | |||||
2256 | return false; | ||||
2257 | } | ||||
2258 | |||||
2259 | void Record::getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const { | ||||
2260 | ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses(); | ||||
2261 | |||||
2262 | while (!SCs.empty()) { | ||||
2263 | Record *SC = SCs.back().first; | ||||
2264 | SCs = SCs.drop_back(1 + SC->getSuperClasses().size()); | ||||
2265 | Classes.push_back(SC); | ||||
2266 | } | ||||
2267 | } | ||||
2268 | |||||
2269 | void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) { | ||||
2270 | for (RecordVal &Value : Values) { | ||||
2271 | if (SkipVal == &Value) // Skip resolve the same field as the given one | ||||
2272 | continue; | ||||
2273 | if (Init *V = Value.getValue()) { | ||||
2274 | Init *VR = V->resolveReferences(R); | ||||
2275 | if (Value.setValue(VR)) { | ||||
2276 | std::string Type; | ||||
2277 | if (TypedInit *VRT = dyn_cast<TypedInit>(VR)) | ||||
2278 | Type = | ||||
2279 | (Twine("of type '") + VRT->getType()->getAsString() + "' ").str(); | ||||
2280 | PrintFatalError(getLoc(), Twine("Invalid value ") + Type + | ||||
2281 | "is found when setting '" + | ||||
2282 | Value.getNameInitAsString() + | ||||
2283 | "' of type '" + | ||||
2284 | Value.getType()->getAsString() + | ||||
2285 | "' after resolving references: " + | ||||
2286 | VR->getAsUnquotedString() + "\n"); | ||||
2287 | } | ||||
2288 | } | ||||
2289 | } | ||||
2290 | Init *OldName = getNameInit(); | ||||
2291 | Init *NewName = Name->resolveReferences(R); | ||||
2292 | if (NewName != OldName) { | ||||
2293 | // Re-register with RecordKeeper. | ||||
2294 | setName(NewName); | ||||
2295 | } | ||||
2296 | } | ||||
2297 | |||||
2298 | void Record::resolveReferences() { | ||||
2299 | RecordResolver R(*this); | ||||
2300 | R.setFinal(true); | ||||
2301 | resolveReferences(R); | ||||
2302 | } | ||||
2303 | |||||
2304 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
2305 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void Record::dump() const { errs() << *this; } | ||||
2306 | #endif | ||||
2307 | |||||
2308 | raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) { | ||||
2309 | OS << R.getNameInitAsString(); | ||||
2310 | |||||
2311 | ArrayRef<Init *> TArgs = R.getTemplateArgs(); | ||||
2312 | if (!TArgs.empty()) { | ||||
2313 | OS << "<"; | ||||
2314 | bool NeedComma = false; | ||||
2315 | for (const Init *TA : TArgs) { | ||||
2316 | if (NeedComma) OS << ", "; | ||||
2317 | NeedComma = true; | ||||
2318 | const RecordVal *RV = R.getValue(TA); | ||||
2319 | assert(RV && "Template argument record not found??")((RV && "Template argument record not found??") ? static_cast <void> (0) : __assert_fail ("RV && \"Template argument record not found??\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2319, __PRETTY_FUNCTION__)); | ||||
2320 | RV->print(OS, false); | ||||
2321 | } | ||||
2322 | OS << ">"; | ||||
2323 | } | ||||
2324 | |||||
2325 | OS << " {"; | ||||
2326 | ArrayRef<std::pair<Record *, SMRange>> SC = R.getSuperClasses(); | ||||
2327 | if (!SC.empty()) { | ||||
2328 | OS << "\t//"; | ||||
2329 | for (const auto &SuperPair : SC) | ||||
2330 | OS << " " << SuperPair.first->getNameInitAsString(); | ||||
2331 | } | ||||
2332 | OS << "\n"; | ||||
2333 | |||||
2334 | for (const RecordVal &Val : R.getValues()) | ||||
2335 | if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) | ||||
2336 | OS << Val; | ||||
2337 | for (const RecordVal &Val : R.getValues()) | ||||
2338 | if (!Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) | ||||
2339 | OS << Val; | ||||
2340 | |||||
2341 | return OS << "}\n"; | ||||
2342 | } | ||||
2343 | |||||
2344 | SMLoc Record::getFieldLoc(StringRef FieldName) const { | ||||
2345 | const RecordVal *R = getValue(FieldName); | ||||
2346 | if (!R) | ||||
2347 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2348 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2349 | return R->getLoc(); | ||||
2350 | } | ||||
2351 | |||||
2352 | Init *Record::getValueInit(StringRef FieldName) const { | ||||
2353 | const RecordVal *R = getValue(FieldName); | ||||
2354 | if (!R || !R->getValue()) | ||||
2355 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2356 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2357 | return R->getValue(); | ||||
2358 | } | ||||
2359 | |||||
2360 | StringRef Record::getValueAsString(StringRef FieldName) const { | ||||
2361 | llvm::Optional<StringRef> S = getValueAsOptionalString(FieldName); | ||||
2362 | if (!S.hasValue()) | ||||
2363 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2364 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2365 | return S.getValue(); | ||||
2366 | } | ||||
2367 | |||||
2368 | llvm::Optional<StringRef> | ||||
2369 | Record::getValueAsOptionalString(StringRef FieldName) const { | ||||
2370 | const RecordVal *R = getValue(FieldName); | ||||
2371 | if (!R || !R->getValue()) | ||||
2372 | return llvm::Optional<StringRef>(); | ||||
2373 | if (isa<UnsetInit>(R->getValue())) | ||||
2374 | return llvm::Optional<StringRef>(); | ||||
2375 | |||||
2376 | if (StringInit *SI = dyn_cast<StringInit>(R->getValue())) | ||||
2377 | return SI->getValue(); | ||||
2378 | |||||
2379 | PrintFatalError(getLoc(), | ||||
2380 | "Record `" + getName() + "', ` field `" + FieldName + | ||||
2381 | "' exists but does not have a string initializer!"); | ||||
2382 | } | ||||
2383 | |||||
2384 | BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const { | ||||
2385 | const RecordVal *R = getValue(FieldName); | ||||
2386 | if (!R || !R->getValue()) | ||||
2387 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2388 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2389 | |||||
2390 | if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue())) | ||||
2391 | return BI; | ||||
2392 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName + | ||||
2393 | "' exists but does not have a bits value"); | ||||
2394 | } | ||||
2395 | |||||
2396 | ListInit *Record::getValueAsListInit(StringRef FieldName) const { | ||||
2397 | const RecordVal *R = getValue(FieldName); | ||||
2398 | if (!R || !R->getValue()) | ||||
2399 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2400 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2401 | |||||
2402 | if (ListInit *LI = dyn_cast<ListInit>(R->getValue())) | ||||
2403 | return LI; | ||||
2404 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName + | ||||
2405 | "' exists but does not have a list value"); | ||||
2406 | } | ||||
2407 | |||||
2408 | std::vector<Record*> | ||||
2409 | Record::getValueAsListOfDefs(StringRef FieldName) const { | ||||
2410 | ListInit *List = getValueAsListInit(FieldName); | ||||
2411 | std::vector<Record*> Defs; | ||||
2412 | for (Init *I : List->getValues()) { | ||||
2413 | if (DefInit *DI = dyn_cast<DefInit>(I)) | ||||
2414 | Defs.push_back(DI->getDef()); | ||||
2415 | else | ||||
2416 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2417 | FieldName + "' list is not entirely DefInit!"); | ||||
2418 | } | ||||
2419 | return Defs; | ||||
2420 | } | ||||
2421 | |||||
2422 | int64_t Record::getValueAsInt(StringRef FieldName) const { | ||||
2423 | const RecordVal *R = getValue(FieldName); | ||||
2424 | if (!R || !R->getValue()) | ||||
2425 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2426 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2427 | |||||
2428 | if (IntInit *II = dyn_cast<IntInit>(R->getValue())) | ||||
2429 | return II->getValue(); | ||||
2430 | PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" + | ||||
2431 | FieldName + | ||||
2432 | "' exists but does not have an int value: " + | ||||
2433 | R->getValue()->getAsString()); | ||||
2434 | } | ||||
2435 | |||||
2436 | std::vector<int64_t> | ||||
2437 | Record::getValueAsListOfInts(StringRef FieldName) const { | ||||
2438 | ListInit *List = getValueAsListInit(FieldName); | ||||
2439 | std::vector<int64_t> Ints; | ||||
2440 | for (Init *I : List->getValues()) { | ||||
2441 | if (IntInit *II = dyn_cast<IntInit>(I)) | ||||
2442 | Ints.push_back(II->getValue()); | ||||
2443 | else | ||||
2444 | PrintFatalError(getLoc(), | ||||
2445 | Twine("Record `") + getName() + "', field `" + FieldName + | ||||
2446 | "' exists but does not have a list of ints value: " + | ||||
2447 | I->getAsString()); | ||||
2448 | } | ||||
2449 | return Ints; | ||||
2450 | } | ||||
2451 | |||||
2452 | std::vector<StringRef> | ||||
2453 | Record::getValueAsListOfStrings(StringRef FieldName) const { | ||||
2454 | ListInit *List = getValueAsListInit(FieldName); | ||||
2455 | std::vector<StringRef> Strings; | ||||
2456 | for (Init *I : List->getValues()) { | ||||
2457 | if (StringInit *SI = dyn_cast<StringInit>(I)) | ||||
2458 | Strings.push_back(SI->getValue()); | ||||
2459 | else | ||||
2460 | PrintFatalError(getLoc(), | ||||
2461 | Twine("Record `") + getName() + "', field `" + FieldName + | ||||
2462 | "' exists but does not have a list of strings value: " + | ||||
2463 | I->getAsString()); | ||||
2464 | } | ||||
2465 | return Strings; | ||||
2466 | } | ||||
2467 | |||||
2468 | Record *Record::getValueAsDef(StringRef FieldName) const { | ||||
2469 | const RecordVal *R = getValue(FieldName); | ||||
2470 | if (!R || !R->getValue()) | ||||
2471 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2472 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2473 | |||||
2474 | if (DefInit *DI = dyn_cast<DefInit>(R->getValue())) | ||||
2475 | return DI->getDef(); | ||||
2476 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2477 | FieldName + "' does not have a def initializer!"); | ||||
2478 | } | ||||
2479 | |||||
2480 | Record *Record::getValueAsOptionalDef(StringRef FieldName) const { | ||||
2481 | const RecordVal *R = getValue(FieldName); | ||||
2482 | if (!R || !R->getValue()) | ||||
2483 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2484 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2485 | |||||
2486 | if (DefInit *DI = dyn_cast<DefInit>(R->getValue())) | ||||
2487 | return DI->getDef(); | ||||
2488 | if (isa<UnsetInit>(R->getValue())) | ||||
2489 | return nullptr; | ||||
2490 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2491 | FieldName + "' does not have either a def initializer or '?'!"); | ||||
2492 | } | ||||
2493 | |||||
2494 | |||||
2495 | bool Record::getValueAsBit(StringRef FieldName) const { | ||||
2496 | const RecordVal *R = getValue(FieldName); | ||||
2497 | if (!R || !R->getValue()) | ||||
2498 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2499 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2500 | |||||
2501 | if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) | ||||
2502 | return BI->getValue(); | ||||
2503 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2504 | FieldName + "' does not have a bit initializer!"); | ||||
2505 | } | ||||
2506 | |||||
2507 | bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const { | ||||
2508 | const RecordVal *R = getValue(FieldName); | ||||
2509 | if (!R || !R->getValue()) | ||||
2510 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2511 | "' does not have a field named `" + FieldName.str() + "'!\n"); | ||||
2512 | |||||
2513 | if (isa<UnsetInit>(R->getValue())) { | ||||
2514 | Unset = true; | ||||
2515 | return false; | ||||
2516 | } | ||||
2517 | Unset = false; | ||||
2518 | if (BitInit *BI = dyn_cast<BitInit>(R->getValue())) | ||||
2519 | return BI->getValue(); | ||||
2520 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2521 | FieldName + "' does not have a bit initializer!"); | ||||
2522 | } | ||||
2523 | |||||
2524 | DagInit *Record::getValueAsDag(StringRef FieldName) const { | ||||
2525 | const RecordVal *R = getValue(FieldName); | ||||
2526 | if (!R || !R->getValue()) | ||||
2527 | PrintFatalError(getLoc(), "Record `" + getName() + | ||||
2528 | "' does not have a field named `" + FieldName + "'!\n"); | ||||
2529 | |||||
2530 | if (DagInit *DI = dyn_cast<DagInit>(R->getValue())) | ||||
2531 | return DI; | ||||
2532 | PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + | ||||
2533 | FieldName + "' does not have a dag initializer!"); | ||||
2534 | } | ||||
2535 | |||||
2536 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
2537 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void RecordKeeper::dump() const { errs() << *this; } | ||||
2538 | #endif | ||||
2539 | |||||
2540 | raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { | ||||
2541 | OS << "------------- Classes -----------------\n"; | ||||
2542 | for (const auto &C : RK.getClasses()) | ||||
2543 | OS << "class " << *C.second; | ||||
2544 | |||||
2545 | OS << "------------- Defs -----------------\n"; | ||||
2546 | for (const auto &D : RK.getDefs()) | ||||
2547 | OS << "def " << *D.second; | ||||
2548 | return OS; | ||||
2549 | } | ||||
2550 | |||||
2551 | /// GetNewAnonymousName - Generate a unique anonymous name that can be used as | ||||
2552 | /// an identifier. | ||||
2553 | Init *RecordKeeper::getNewAnonymousName() { | ||||
2554 | return StringInit::get("anonymous_" + utostr(AnonCounter++)); | ||||
2555 | } | ||||
2556 | |||||
2557 | // These functions implement the phase timing facility. Starting a timer | ||||
2558 | // when one is already running stops the running one. | ||||
2559 | |||||
2560 | void RecordKeeper::startTimer(StringRef Name) { | ||||
2561 | if (TimingGroup) { | ||||
2562 | if (LastTimer && LastTimer->isRunning()) { | ||||
2563 | LastTimer->stopTimer(); | ||||
2564 | if (BackendTimer) { | ||||
2565 | LastTimer->clear(); | ||||
2566 | BackendTimer = false; | ||||
2567 | } | ||||
2568 | } | ||||
2569 | |||||
2570 | LastTimer = new Timer("", Name, *TimingGroup); | ||||
2571 | LastTimer->startTimer(); | ||||
2572 | } | ||||
2573 | } | ||||
2574 | |||||
2575 | void RecordKeeper::stopTimer() { | ||||
2576 | if (TimingGroup) { | ||||
2577 | assert(LastTimer && "No phase timer was started")((LastTimer && "No phase timer was started") ? static_cast <void> (0) : __assert_fail ("LastTimer && \"No phase timer was started\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2577, __PRETTY_FUNCTION__)); | ||||
2578 | LastTimer->stopTimer(); | ||||
2579 | } | ||||
2580 | } | ||||
2581 | |||||
2582 | void RecordKeeper::startBackendTimer(StringRef Name) { | ||||
2583 | if (TimingGroup) { | ||||
2584 | startTimer(Name); | ||||
2585 | BackendTimer = true; | ||||
2586 | } | ||||
2587 | } | ||||
2588 | |||||
2589 | void RecordKeeper::stopBackendTimer() { | ||||
2590 | if (TimingGroup) { | ||||
2591 | if (BackendTimer) { | ||||
2592 | stopTimer(); | ||||
2593 | BackendTimer = false; | ||||
2594 | } | ||||
2595 | } | ||||
2596 | } | ||||
2597 | |||||
2598 | // We cache the record vectors for single classes. Many backends request | ||||
2599 | // the same vectors multiple times. | ||||
2600 | std::vector<Record *> RecordKeeper::getAllDerivedDefinitions( | ||||
2601 | StringRef ClassName) const { | ||||
2602 | |||||
2603 | auto Pair = ClassRecordsMap.try_emplace(ClassName); | ||||
2604 | if (Pair.second) | ||||
2605 | Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName)); | ||||
2606 | |||||
2607 | return Pair.first->second; | ||||
2608 | } | ||||
2609 | |||||
2610 | std::vector<Record *> RecordKeeper::getAllDerivedDefinitions( | ||||
2611 | ArrayRef<StringRef> ClassNames) const { | ||||
2612 | SmallVector<Record *, 2> ClassRecs; | ||||
2613 | std::vector<Record *> Defs; | ||||
2614 | |||||
2615 | assert(ClassNames.size() > 0 && "At least one class must be passed.")((ClassNames.size() > 0 && "At least one class must be passed." ) ? static_cast<void> (0) : __assert_fail ("ClassNames.size() > 0 && \"At least one class must be passed.\"" , "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/TableGen/Record.cpp" , 2615, __PRETTY_FUNCTION__)); | ||||
2616 | for (const auto &ClassName : ClassNames) { | ||||
2617 | Record *Class = getClass(ClassName); | ||||
2618 | if (!Class) | ||||
2619 | PrintFatalError("The class '" + ClassName + "' is not defined\n"); | ||||
2620 | ClassRecs.push_back(Class); | ||||
2621 | } | ||||
2622 | |||||
2623 | for (const auto &OneDef : getDefs()) { | ||||
2624 | if (all_of(ClassRecs, [&OneDef](const Record *Class) { | ||||
2625 | return OneDef.second->isSubClassOf(Class); | ||||
2626 | })) | ||||
2627 | Defs.push_back(OneDef.second.get()); | ||||
2628 | } | ||||
2629 | |||||
2630 | return Defs; | ||||
2631 | } | ||||
2632 | |||||
2633 | Init *MapResolver::resolve(Init *VarName) { | ||||
2634 | auto It = Map.find(VarName); | ||||
2635 | if (It == Map.end()) | ||||
2636 | return nullptr; | ||||
2637 | |||||
2638 | Init *I = It->second.V; | ||||
2639 | |||||
2640 | if (!It->second.Resolved && Map.size() > 1) { | ||||
2641 | // Resolve mutual references among the mapped variables, but prevent | ||||
2642 | // infinite recursion. | ||||
2643 | Map.erase(It); | ||||
2644 | I = I->resolveReferences(*this); | ||||
2645 | Map[VarName] = {I, true}; | ||||
2646 | } | ||||
2647 | |||||
2648 | return I; | ||||
2649 | } | ||||
2650 | |||||
2651 | Init *RecordResolver::resolve(Init *VarName) { | ||||
2652 | Init *Val = Cache.lookup(VarName); | ||||
2653 | if (Val) | ||||
2654 | return Val; | ||||
2655 | |||||
2656 | for (Init *S : Stack) { | ||||
2657 | if (S == VarName) | ||||
2658 | return nullptr; // prevent infinite recursion | ||||
2659 | } | ||||
2660 | |||||
2661 | if (RecordVal *RV = getCurrentRecord()->getValue(VarName)) { | ||||
2662 | if (!isa<UnsetInit>(RV->getValue())) { | ||||
2663 | Val = RV->getValue(); | ||||
2664 | Stack.push_back(VarName); | ||||
2665 | Val = Val->resolveReferences(*this); | ||||
2666 | Stack.pop_back(); | ||||
2667 | } | ||||
2668 | } | ||||
2669 | |||||
2670 | Cache[VarName] = Val; | ||||
2671 | return Val; | ||||
2672 | } | ||||
2673 | |||||
2674 | Init *TrackUnresolvedResolver::resolve(Init *VarName) { | ||||
2675 | Init *I = nullptr; | ||||
2676 | |||||
2677 | if (R) { | ||||
2678 | I = R->resolve(VarName); | ||||
2679 | if (I && !FoundUnresolved) { | ||||
2680 | // Do not recurse into the resolved initializer, as that would change | ||||
2681 | // the behavior of the resolver we're delegating, but do check to see | ||||
2682 | // if there are unresolved variables remaining. | ||||
2683 | TrackUnresolvedResolver Sub; | ||||
2684 | I->resolveReferences(Sub); | ||||
2685 | FoundUnresolved |= Sub.FoundUnresolved; | ||||
2686 | } | ||||
2687 | } | ||||
2688 | |||||
2689 | if (!I) | ||||
2690 | FoundUnresolved = true; | ||||
2691 | return I; | ||||
2692 | } | ||||
2693 | |||||
2694 | Init *HasReferenceResolver::resolve(Init *VarName) | ||||
2695 | { | ||||
2696 | if (VarName == VarNameToTrack) | ||||
2697 | Found = true; | ||||
2698 | return nullptr; | ||||
2699 | } |