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