Bug Summary

File:llvm/lib/TableGen/Record.cpp
Warning:line 2307, column 8
Dereference of null pointer (loaded from variable '__begin1')

Annotated Source Code

Press '?' to see keyboard shortcuts

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