22#include "llvm/Config/llvm-config.h"
42#define DEBUG_TYPE "tblgen-records"
106 OS <<
"TheArgumentInitPool size = " << TheArgumentInitPool.size() <<
'\n';
107 OS <<
"TheBitsInitPool size = " << TheBitsInitPool.size() <<
'\n';
108 OS <<
"TheIntInitPool size = " << TheIntInitPool.size() <<
'\n';
109 OS <<
"StringInitStringPool size = " << StringInitStringPool.size() <<
'\n';
110 OS <<
"StringInitCodePool size = " << StringInitCodePool.size() <<
'\n';
111 OS <<
"TheListInitPool size = " << TheListInitPool.size() <<
'\n';
112 OS <<
"TheUnOpInitPool size = " << TheUnOpInitPool.size() <<
'\n';
113 OS <<
"TheBinOpInitPool size = " << TheBinOpInitPool.size() <<
'\n';
114 OS <<
"TheTernOpInitPool size = " << TheTernOpInitPool.size() <<
'\n';
115 OS <<
"TheFoldOpInitPool size = " << TheFoldOpInitPool.size() <<
'\n';
116 OS <<
"TheIsAOpInitPool size = " << TheIsAOpInitPool.size() <<
'\n';
117 OS <<
"TheExistsOpInitPool size = " << TheExistsOpInitPool.size() <<
'\n';
118 OS <<
"TheCondOpInitPool size = " << TheCondOpInitPool.size() <<
'\n';
119 OS <<
"TheDagInitPool size = " << TheDagInitPool.size() <<
'\n';
120 OS <<
"RecordTypePool size = " << RecordTypePool.size() <<
'\n';
121 OS <<
"TheVarInitPool size = " << TheVarInitPool.size() <<
'\n';
122 OS <<
"TheVarBitInitPool size = " << TheVarBitInitPool.size() <<
'\n';
123 OS <<
"TheVarDefInitPool size = " << TheVarDefInitPool.size() <<
'\n';
124 OS <<
"TheFieldInitPool size = " << TheFieldInitPool.size() <<
'\n';
125 OS <<
"Bytes allocated = " <<
Allocator.getBytesAllocated() <<
'\n';
126 OS <<
"Total allocator memory = " <<
Allocator.getTotalMemory() <<
"\n\n";
128 OS <<
"Number of records instantiated = " << LastRecordID <<
'\n';
129 OS <<
"Number of anonymous records = " << AnonCounter <<
'\n';
136#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
148 return Kind ==
RHS->getRecTyKind();
160 if (
const auto *BitsTy = dyn_cast<BitsRecTy>(
RHS))
161 return BitsTy->getNumBits() == 1;
176 return "bits<" + utostr(Size) +
">";
181 return cast<BitsRecTy>(
RHS)->Size == Size;
213 if (
const auto *ListTy = dyn_cast<ListRecTy>(
RHS))
219 if (
const auto *RHSl = dyn_cast<ListRecTy>(
RHS))
234 ID.AddInteger(Classes.
size());
235 for (
const Record *R : Classes)
242 if (UnsortedClasses.
empty())
249 return LHS->getNameInitAsString() <
RHS->getNameInitAsString();
261 for (
unsigned i = 0; i < Classes.
size(); ++i) {
262 for (
unsigned j = 0; j < Classes.
size(); ++j) {
265 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
270 totalSizeToAlloc<const Record *>(Classes.
size()),
alignof(
RecordRecTy));
272 std::uninitialized_copy(Classes.
begin(), Classes.
end(),
279 assert(Class &&
"unexpected null class");
280 return get(Class->getRecords(), {Class});
289 return getClasses()[0]->getNameInitAsString();
291 std::string Str =
"{";
297 Str += R->getNameInitAsString();
305 return MySuperClass == Class || MySuperClass->
isSubClassOf(Class);
313 const auto *RTy = dyn_cast<RecordRecTy>(
RHS);
318 return isSubClassOf(TargetClass);
331 while (!Stack.empty()) {
332 const Record *R = Stack.pop_back_val();
337 R->getDirectSuperClasses(Stack);
348 if (
const auto *RecTy1 = dyn_cast<RecordRecTy>(
T1)) {
349 if (
const auto *RecTy2 = dyn_cast<RecordRecTy>(T2))
353 assert(
T1 !=
nullptr &&
"Invalid record type");
354 if (
T1->typeIsConvertibleTo(T2))
357 assert(T2 !=
nullptr &&
"Invalid record type");
361 if (
const auto *ListTy1 = dyn_cast<ListRecTy>(
T1)) {
362 if (
const auto *ListTy2 = dyn_cast<ListRecTy>(T2)) {
363 const RecTy *NewType =
364 resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());
377void Init::anchor() {}
379#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
384 if (
auto *TyInit = dyn_cast<TypedInit>(
this))
385 return TyInit->getType()->getRecordKeeper();
386 if (
auto *ArgInit = dyn_cast<ArgumentInit>(
this))
387 return ArgInit->getRecordKeeper();
388 return cast<UnsetInit>(
this)->getRecordKeeper();
403 auto I = Aux.index();
406 ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
408 ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
433 const Init *NewValue =
Value->resolveReferences(R);
434 if (NewValue !=
Value)
445 if (isa<BitRecTy>(Ty))
448 if (isa<IntRecTy>(Ty))
451 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
453 if (BRT->getNumBits() == 1)
478 totalSizeToAlloc<const Init *>(
Range.size()),
alignof(
BitsInit));
480 std::uninitialized_copy(
Range.begin(),
Range.end(),
481 I->getTrailingObjects<
const Init *>());
491 if (isa<BitRecTy>(Ty)) {
496 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
499 if (
getNumBits() != BRT->getNumBits())
return nullptr;
503 if (isa<IntRecTy>(Ty)) {
514 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i)
515 if (
auto *Bit = dyn_cast<BitInit>(
getBit(i)))
516 Result |=
static_cast<int64_t
>(Bit->getValue()) << i;
526 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
529 NewBits[i] =
getBit(Bits[i]);
535 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
543 std::string Result =
"{ ";
544 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
545 if (i) Result +=
", ";
547 Result += Bit->getAsString();
551 return Result +
" }";
557 bool Changed =
false;
560 const Init *CachedBitVarRef =
nullptr;
561 const Init *CachedBitVarResolved =
nullptr;
563 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
565 const Init *NewBit = CurBit;
567 if (
const auto *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
568 if (CurBitVar->getBitVar() != CachedBitVarRef) {
569 CachedBitVarRef = CurBitVar->getBitVar();
572 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
573 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
579 if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
582 Changed |= CurBit != NewBit;
599 return itostr(
Value);
604 return (NumBits >=
sizeof(
Value) * 8) ||
605 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
609 if (isa<IntRecTy>(Ty))
612 if (isa<BitRecTy>(Ty)) {
614 if (Val != 0 && Val != 1)
return nullptr;
618 if (
const auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
625 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
638 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
657 return "anonymous_" + utostr(
Value);
662 auto *New = R.resolve(Old);
663 New = New ? New : Old;
665 if (
const auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
666 return Anonymous->getNameInit();
675 auto &Entry = *InitMap.try_emplace(V,
nullptr).first;
682 if (isa<StringRecTy>(Ty))
689 const RecTy *EltTy) {
691 ID.AddPointer(EltTy);
698 const RecTy *EltTy) {
708 cast<TypedInit>(
Range[0])->getType()->typeIsConvertibleTo(EltTy));
711 totalSizeToAlloc<const Init *>(
Range.size()),
alignof(
ListInit));
713 std::uninitialized_copy(
Range.begin(),
Range.end(),
714 I->getTrailingObjects<
const Init *>());
720 const RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
729 if (
const auto *LRT = dyn_cast<ListRecTy>(Ty)) {
735 bool Changed =
false;
736 const RecTy *ElementType = LRT->getElementType();
738 if (
const Init *CI =
I->convertInitializerTo(ElementType)) {
739 Elements.push_back(CI);
754 assert(i < NumValues &&
"List element index out of range!");
755 const auto *DI = dyn_cast<DefInit>(
getElement(i));
763 Resolved.reserve(
size());
764 bool Changed =
false;
768 Changed |= E != CurElt;
769 Resolved.push_back(E);
778 for (
const Init *Element : *
this) {
786 for (
const Init *Element : *
this) {
794 std::string Result =
"[";
795 const char *sep =
"";
796 for (
const Init *Element : *
this) {
812 ID.AddInteger(Opcode);
841 if (
const auto *Def = dyn_cast<DefInit>(LHS)) {
844 OS << *Def->getDef();
857 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
861 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
865 if (isa<StringRecTy>(
getType())) {
866 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
869 if (
const auto *LHSd = dyn_cast<DefInit>(LHS))
872 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
876 }
else if (isa<RecordRecTy>(
getType())) {
877 if (
const auto *
Name = dyn_cast<StringInit>(LHS)) {
882 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
884 (Anonymous &&
Name == Anonymous->getNameInit())) {
891 auto PrintFatalErrorHelper = [CurRec](
const Twine &
T) {
900 PrintFatalErrorHelper(
Twine(
"Undefined reference to record: '") +
901 Name->getValue() +
"'\n");
908 PrintFatalErrorHelper(
Twine(
"Expected type '") +
922 if (isa<UnsetInit>(LHS))
929 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
935 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
936 assert(!LHSl->empty() &&
"Empty list in head");
937 return LHSl->getElement(0);
942 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
943 assert(!LHSl->empty() &&
"Empty list in tail");
946 return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
951 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
953 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
955 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
960 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
962 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
964 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
969 if (
const auto *Dag = dyn_cast<DagInit>(LHS)) {
972 auto *TI = cast<TypedInit>(Dag->getOperator());
973 if (!TI->getType()->typeIsA(
getType())) {
976 "', got '" + TI->getType()->getAsString() +
979 return Dag->getOperator();
985 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
987 int64_t LHSv = LHSi->getValue();
990 "Illegal operation: logtwo is undefined "
991 "on arguments less than or equal to 0");
995 "Log of an int64_t must be smaller than INT64_MAX");
1002 if (
const auto *LHSList = dyn_cast<ListInit>(LHS)) {
1003 const auto *InnerListTy = dyn_cast<ListRecTy>(LHSList->getElementType());
1009 [](
const ListInit *
List) -> std::optional<std::vector<const Init *>> {
1010 std::vector<const Init *> Flattened;
1012 for (
const Init *InnerInit :
List->getValues()) {
1013 const auto *InnerList = dyn_cast<ListInit>(InnerInit);
1015 return std::nullopt;
1016 for (
const Init *InnerElem : InnerList->getValues())
1017 Flattened.push_back(InnerElem);
1022 auto Flattened = Flatten(LHSList);
1024 return ListInit::get(*Flattened, InnerListTy->getElementType());
1036 ->Fold(R.getCurrentRecord(), R.isFinal());
1044 case NOT: Result =
"!not";
break;
1045 case HEAD: Result =
"!head";
break;
1046 case TAIL: Result =
"!tail";
break;
1047 case SIZE: Result =
"!size";
break;
1048 case EMPTY: Result =
"!empty";
break;
1049 case GETDAGOP: Result =
"!getdagop";
break;
1050 case LOG2 : Result =
"!logtwo";
break;
1052 Result =
"!listflatten";
1058 Result =
"!tolower";
1061 Result =
"!toupper";
1064 Result =
"!initialized";
1073 ID.AddInteger(Opcode);
1101 Concat.append(I1->getValue());
1109 if (
List->size() == 0)
1111 const auto *Element = dyn_cast<StringInit>(
List->getElement(0));
1117 for (
unsigned I = 1, E =
List->size();
I < E; ++
I) {
1119 const auto *Element = dyn_cast<StringInit>(
List->getElement(
I));
1122 Result.append(Element->getValue());
1131 if (
List->size() == 0)
1133 const auto *Element = dyn_cast_or_null<IntInit>(
1139 for (
unsigned I = 1, E =
List->size();
I < E; ++
I) {
1141 const auto *Element = dyn_cast_or_null<IntInit>(
1145 Result.append(Element->getAsString());
1152 if (
const auto *I0s = dyn_cast<StringInit>(I0))
1153 if (
const auto *I1s = dyn_cast<StringInit>(I1))
1171 if (
const auto *LHSList = dyn_cast<ListInit>(
LHS))
1172 if (
const auto *RHSList = dyn_cast<ListInit>(
RHS))
1178 const Init *RHS)
const {
1180 const auto *LHSi = dyn_cast_or_null<IntInit>(
1182 const auto *RHSi = dyn_cast_or_null<IntInit>(
1189 Result = LHSi->getValue() == RHSi->getValue();
1192 Result = LHSi->getValue() != RHSi->getValue();
1195 Result = LHSi->getValue() <= RHSi->getValue();
1198 Result = LHSi->getValue() < RHSi->getValue();
1201 Result = LHSi->getValue() >= RHSi->getValue();
1204 Result = LHSi->getValue() > RHSi->getValue();
1213 const auto *LHSs = dyn_cast<StringInit>(
LHS);
1214 const auto *RHSs = dyn_cast<StringInit>(
RHS);
1220 Result = LHSs->getValue() == RHSs->getValue();
1223 Result = LHSs->getValue() != RHSs->getValue();
1226 Result = LHSs->getValue() <= RHSs->getValue();
1229 Result = LHSs->getValue() < RHSs->getValue();
1232 Result = LHSs->getValue() >= RHSs->getValue();
1235 Result = LHSs->getValue() > RHSs->getValue();
1245 const auto *LHSd = dyn_cast<DefInit>(
LHS);
1246 const auto *RHSd = dyn_cast<DefInit>(
RHS);
1248 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1251 return std::nullopt;
1254static std::optional<unsigned>
1257 if (
const auto *
Idx = dyn_cast<IntInit>(Key)) {
1258 int64_t Pos =
Idx->getValue();
1262 (
Twine(
"index ") + std::to_string(Pos) +
Twine(
" is negative")).str();
1263 return std::nullopt;
1265 if (Pos >= Dag->getNumArgs()) {
1267 Error = (
Twine(
"index ") + std::to_string(Pos) +
1268 " is out of range (dag has " +
1269 std::to_string(Dag->getNumArgs()) +
" arguments)")
1271 return std::nullopt;
1275 assert(isa<StringInit>(Key));
1277 const auto *
Name = dyn_cast<StringInit>(Key);
1278 auto ArgNo = Dag->getArgNo(
Name->getValue());
1282 return std::nullopt;
1290 const auto *LHSs = dyn_cast<DagInit>(LHS);
1291 const auto *RHSs = dyn_cast<DagInit>(RHS);
1293 const auto *LOp = dyn_cast<DefInit>(LHSs->getOperator());
1294 const auto *ROp = dyn_cast<DefInit>(RHSs->getOperator());
1295 if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
1296 (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
1298 if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1300 LHSs->getAsString() +
"' vs. '" + RHSs->getAsString() +
1303 const Init *
Op = LOp ? LOp : ROp;
1309 for (
unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
1310 Args.push_back(LHSs->getArg(i));
1311 ArgNames.
push_back(LHSs->getArgName(i));
1313 for (
unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
1314 Args.push_back(RHSs->getArg(i));
1315 ArgNames.
push_back(RHSs->getArgName(i));
1322 const auto *LHSs = dyn_cast<ListInit>(LHS);
1323 const auto *RHSs = dyn_cast<ListInit>(RHS);
1333 const auto *
Value = dyn_cast<TypedInit>(LHS);
1334 const auto *
Size = dyn_cast<IntInit>(RHS);
1342 const auto *LHSs = dyn_cast<ListInit>(LHS);
1343 const auto *RHSs = dyn_cast<ListInit>(RHS);
1346 for (
const Init *EltLHS : *LHSs) {
1348 for (
const Init *EltRHS : *RHSs) {
1349 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1357 Args.push_back(EltLHS);
1364 const auto *TheList = dyn_cast<ListInit>(LHS);
1365 const auto *
Idx = dyn_cast<IntInit>(RHS);
1366 if (!TheList || !
Idx)
1368 auto i =
Idx->getValue();
1369 if (i < 0 || i >= (ssize_t)TheList->size())
1371 return TheList->getElement(i);
1374 const auto *TheList = dyn_cast<ListInit>(LHS);
1375 const auto *SliceIdxs = dyn_cast<ListInit>(RHS);
1376 if (!TheList || !SliceIdxs)
1379 Args.reserve(SliceIdxs->size());
1380 for (
auto *
I : *SliceIdxs) {
1381 auto *
II = dyn_cast<IntInit>(
I);
1384 auto i =
II->getValue();
1385 if (i < 0 || i >= (ssize_t)TheList->size())
1387 Args.push_back(TheList->getElement(i));
1392 const auto *LHSi = dyn_cast<IntInit>(LHS);
1393 const auto *RHSi = dyn_cast<IntInit>(RHS);
1397 auto Start = LHSi->getValue();
1398 auto End = RHSi->getValue();
1404 Args.reserve(
End - Start + 1);
1405 for (
auto i = Start; i <=
End; ++i)
1409 Args.reserve(Start -
End + 1);
1410 for (
auto i = Start; i >=
End; --i)
1413 }
else if (Start <
End) {
1415 Args.reserve(
End - Start);
1416 for (
auto i = Start; i <
End; ++i)
1424 const auto *LHSs = dyn_cast<StringInit>(LHS);
1425 const auto *RHSs = dyn_cast<StringInit>(RHS);
1431 const auto *
List = dyn_cast<ListInit>(LHS);
1432 const auto *Delim = dyn_cast<StringInit>(RHS);
1433 if (
List && Delim) {
1435 if (isa<StringRecTy>(
List->getElementType()))
1455 const auto *Dag = dyn_cast<DagInit>(LHS);
1456 if (Dag && isa<IntInit, StringInit>(RHS)) {
1462 assert(*ArgNo < Dag->getNumArgs());
1464 const Init *Arg = Dag->getArg(*ArgNo);
1465 if (
const auto *TI = dyn_cast<TypedInit>(Arg))
1466 if (!TI->getType()->typeIsConvertibleTo(
getType()))
1473 const auto *Dag = dyn_cast<DagInit>(LHS);
1474 const auto *
Idx = dyn_cast<IntInit>(RHS);
1476 int64_t Pos =
Idx->getValue();
1477 if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1480 Twine(
"!getdagname index is out of range 0...") +
1481 std::to_string(Dag->getNumArgs() - 1) +
": " +
1482 std::to_string(Pos));
1484 const Init *ArgName = Dag->getArgName(Pos);
1492 const auto *Dag = dyn_cast<DagInit>(LHS);
1493 const auto *
Op = dyn_cast<DefInit>(RHS);
1497 for (
unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
1498 Args.push_back(Dag->getArg(i));
1515 const auto *LHSi = dyn_cast_or_null<IntInit>(
1517 const auto *RHSi = dyn_cast_or_null<IntInit>(
1520 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
1524 case ADD: Result = LHSv + RHSv;
break;
1525 case SUB: Result = LHSv - RHSv;
break;
1526 case MUL: Result = LHSv * RHSv;
break;
1530 "Illegal operation: division by zero");
1531 else if (LHSv ==
INT64_MIN && RHSv == -1)
1533 "Illegal operation: INT64_MIN / -1");
1535 Result = LHSv / RHSv;
1537 case AND: Result = LHSv & RHSv;
break;
1538 case OR: Result = LHSv | RHSv;
break;
1539 case XOR: Result = LHSv ^ RHSv;
break;
1541 case SRA: Result = LHSv >> RHSv;
break;
1566 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1568 if ((
Opc ==
AND && !LHSi->getValue()) ||
1569 (
Opc ==
OR && LHSi->getValue() == -1))
1574 if (LHS != lhs || RHS != rhs)
1576 ->Fold(R.getCurrentRecord());
1588 case CONCAT: Result =
"!con";
break;
1589 case ADD: Result =
"!add";
break;
1590 case SUB: Result =
"!sub";
break;
1591 case MUL: Result =
"!mul";
break;
1592 case DIV: Result =
"!div";
break;
1593 case AND: Result =
"!and";
break;
1594 case OR: Result =
"!or";
break;
1595 case XOR: Result =
"!xor";
break;
1596 case SHL: Result =
"!shl";
break;
1597 case SRA: Result =
"!sra";
break;
1598 case SRL: Result =
"!srl";
break;
1599 case EQ: Result =
"!eq";
break;
1600 case NE: Result =
"!ne";
break;
1601 case LE: Result =
"!le";
break;
1602 case LT: Result =
"!lt";
break;
1603 case GE: Result =
"!ge";
break;
1604 case GT: Result =
"!gt";
break;
1605 case LISTCONCAT: Result =
"!listconcat";
break;
1606 case LISTSPLAT: Result =
"!listsplat";
break;
1608 Result =
"!listremove";
1610 case STRCONCAT: Result =
"!strconcat";
break;
1611 case INTERLEAVE: Result =
"!interleave";
break;
1612 case SETDAGOP: Result =
"!setdagop";
break;
1617 Result =
"!getdagname";
1626 ID.AddInteger(Opcode);
1657 return RHS->resolveReferences(R);
1662 bool Change =
false;
1668 for (
unsigned int i = 0; i < MHSd->
getNumArgs(); ++i) {
1673 if (
const auto *Argd = dyn_cast<DagInit>(Arg))
1692 if (
const auto *MHSd = dyn_cast<DagInit>(MHS))
1695 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1698 for (
const Init *&Item : NewList) {
1700 if (NewItem != Item)
1714 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1717 for (
const Init *Item : MHSl->getValues()) {
1721 if (
const auto *IncludeInt =
1722 dyn_cast_or_null<IntInit>(
Include->convertInitializerTo(
1724 if (IncludeInt->getValue())
1740 const auto *LHSd = dyn_cast<DefInit>(LHS);
1741 const auto *LHSv = dyn_cast<VarInit>(LHS);
1742 const auto *LHSs = dyn_cast<StringInit>(LHS);
1744 const auto *MHSd = dyn_cast<DefInit>(MHS);
1745 const auto *MHSv = dyn_cast<VarInit>(MHS);
1746 const auto *MHSs = dyn_cast<StringInit>(MHS);
1748 const auto *RHSd = dyn_cast<DefInit>(RHS);
1749 const auto *RHSv = dyn_cast<VarInit>(RHS);
1750 const auto *RHSs = dyn_cast<StringInit>(RHS);
1752 if (LHSd && MHSd && RHSd) {
1753 const Record *Val = RHSd->getDef();
1754 if (LHSd->getAsString() == RHSd->getAsString())
1755 Val = MHSd->getDef();
1758 if (LHSv && MHSv && RHSv) {
1759 std::string Val = std::string(RHSv->getName());
1760 if (LHSv->getAsString() == RHSv->getAsString())
1761 Val = std::string(MHSv->getName());
1764 if (LHSs && MHSs && RHSs) {
1765 std::string Val = std::string(RHSs->getValue());
1767 std::string::size_type found;
1768 std::string::size_type idx = 0;
1770 found = Val.find(std::string(LHSs->getValue()), idx);
1771 if (found == std::string::npos)
1773 Val.replace(found, LHSs->getValue().size(),
1774 std::string(MHSs->getValue()));
1775 idx = found + MHSs->getValue().size();
1796 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1798 if (LHSi->getValue())
1806 const auto *MHSl = dyn_cast<ListInit>(MHS);
1807 const auto *RHSl = dyn_cast<ListInit>(RHS);
1808 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1809 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1811 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1814 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
1816 unsigned Size = MHSl ? MHSl->size() : RHSl->size();
1817 for (
unsigned i = 0; i !=
Size; ++i) {
1820 if (!isa<StringInit>(
Name) && !isa<UnsetInit>(
Name))
1822 Children.emplace_back(
Node, dyn_cast<StringInit>(
Name));
1830 const auto *LHSi = dyn_cast<IntInit>(LHS);
1831 const auto *MHSi = dyn_cast<IntInit>(MHS);
1832 const auto *RHSi = dyn_cast<IntInit>(RHS);
1833 if (!LHSi || !MHSi || !RHSi)
1836 auto Start = LHSi->getValue();
1837 auto End = MHSi->getValue();
1838 auto Step = RHSi->getValue();
1843 if (Start < End && Step > 0) {
1844 Args.reserve((
End - Start) / Step);
1845 for (
auto I = Start;
I <
End;
I += Step)
1847 }
else if (Start >
End && Step < 0) {
1848 Args.reserve((Start -
End) / -Step);
1849 for (
auto I = Start;
I >
End;
I += Step)
1858 const auto *LHSs = dyn_cast<StringInit>(LHS);
1859 const auto *MHSi = dyn_cast<IntInit>(MHS);
1860 const auto *RHSi = dyn_cast<IntInit>(RHS);
1861 if (LHSs && MHSi && RHSi) {
1862 int64_t StringSize = LHSs->getValue().size();
1863 int64_t Start = MHSi->getValue();
1864 int64_t
Length = RHSi->getValue();
1865 if (Start < 0 || Start > StringSize)
1867 Twine(
"!substr start position is out of range 0...") +
1868 std::to_string(StringSize) +
": " +
1869 std::to_string(Start));
1879 const auto *LHSs = dyn_cast<StringInit>(LHS);
1880 const auto *MHSs = dyn_cast<StringInit>(MHS);
1881 const auto *RHSi = dyn_cast<IntInit>(RHS);
1882 if (LHSs && MHSs && RHSi) {
1883 int64_t SourceSize = LHSs->getValue().size();
1884 int64_t Start = RHSi->getValue();
1885 if (Start < 0 || Start > SourceSize)
1887 Twine(
"!find start position is out of range 0...") +
1888 std::to_string(SourceSize) +
": " +
1889 std::to_string(Start));
1890 auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1891 if (
I == std::string::npos)
1899 const auto *Dag = dyn_cast<DagInit>(LHS);
1900 if (Dag && isa<IntInit, StringInit>(MHS)) {
1906 assert(*ArgNo < Dag->getNumArgs());
1911 return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
1917 const auto *Dag = dyn_cast<DagInit>(LHS);
1918 if (Dag && isa<IntInit, StringInit>(MHS)) {
1924 assert(*ArgNo < Dag->getNumArgs());
1928 Names[*ArgNo] = dyn_cast<StringInit>(RHS);
1929 return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
1942 if (
const auto *
Value = dyn_cast_or_null<IntInit>(
1945 if (
Value->getValue())
1962 if (LHS != lhs || MHS != mhs || RHS != rhs)
1964 ->Fold(R.getCurrentRecord());
1970 bool UnquotedLHS =
false;
1972 case DAG: Result =
"!dag";
break;
1973 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
1974 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
1975 case IF: Result =
"!if";
break;
1979 case SUBST: Result =
"!subst";
break;
1980 case SUBSTR: Result =
"!substr";
break;
1981 case FIND: Result =
"!find";
break;
1983 Result =
"!setdagarg";
1986 Result =
"!setdagname";
1989 return (Result +
"(" +
1997 ID.AddPointer(Start);
2001 ID.AddPointer(Expr);
2026 if (
const auto *LI = dyn_cast<ListInit>(List)) {
2027 const Init *Accum = Start;
2028 for (
const Init *Elt : *LI) {
2047 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
2051 ->
Fold(R.getCurrentRecord());
2068 ID.AddPointer(Expr);
2091 if (
const auto *TI = dyn_cast<TypedInit>(Expr)) {
2093 if (TI->getType()->typeIsConvertibleTo(CheckType))
2096 if (isa<RecordRecTy>(CheckType)) {
2130 ID.AddPointer(Expr);
2154 if (
const auto *
Name = dyn_cast<StringInit>(Expr)) {
2160 D->getDefInit()->getType()->typeIsA(CheckType));
2166 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
2168 (Anonymous &&
Name == Anonymous->getNameInit())) {
2187 if (Expr !=
NewExpr || R.isFinal())
2188 return get(CheckType,
NewExpr)->
Fold(R.getCurrentRecord(), R.isFinal());
2206 return Field->getType();
2216 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
2217 cast<BitsRecTy>(Ty)->getNumBits() == 1)
2225 const auto *
T = dyn_cast<BitsRecTy>(
getType());
2226 if (!
T)
return nullptr;
2227 unsigned NumBits =
T->getNumBits();
2231 for (
unsigned Bit : Bits) {
2246 assert(!isa<TypedInit>(Converted) ||
2247 cast<TypedInit>(Converted)->
getType()->typeIsA(Ty));
2251 if (!
getType()->typeIsConvertibleTo(Ty))
2271 const auto *NameString = cast<StringInit>(
getNameInit());
2272 return NameString->getValue();
2282 if (
const Init *Val = R.resolve(VarName))
2296 return TI->
getAsString() +
"{" + utostr(Bit) +
"}";
2307DefInit::DefInit(
const Record *
D)
2311 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
2312 if (
getType()->typeIsConvertibleTo(RRT))
2319 return RV->getType();
2327 ID.AddInteger(Args.size());
2328 ID.AddPointer(Class);
2330 for (
const Init *
I : Args)
2334VarDefInit::VarDefInit(
SMLoc Loc,
const Record *Class,
unsigned N)
2349 totalSizeToAlloc<const ArgumentInit *>(Args.size()),
alignof(
VarDefInit));
2351 std::uninitialized_copy(Args.begin(), Args.end(),
2361const DefInit *VarDefInit::instantiate() {
2366 auto NewRecOwner = std::make_unique<Record>(
2368 Record *NewRec = NewRecOwner.get();
2384 for (
const Init *Arg : TArgs) {
2389 for (
auto *Arg :
args()) {
2390 if (Arg->isPositional())
2391 R.set(TArgs[Arg->getIndex()], Arg->getValue());
2393 R.set(Arg->getName(), Arg->getValue());
2407 Records.addDef(std::move(NewRecOwner));
2420 bool Changed =
false;
2425 const auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
2427 Changed |= NewArg != Arg;
2433 return const_cast<VarDefInit *
>(New)->instantiate();
2445 Arg->resolveReferences(R);
2447 if (!R.foundUnresolved())
2448 return const_cast<VarDefInit *
>(
this)->instantiate();
2454 const char *sep =
"";
2458 Result += Arg->getAsString();
2460 return Result +
">";
2485 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2486 const Record *Def = DI->getDef();
2489 Twine(
"Attempting to access field '") +
2491 Rec->
getAsString() +
"' is a forbidden self-reference");
2492 const Init *FieldVal = Def->getValue(FieldName)->getValue();
2500 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2501 const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2510 const RecTy *ValType) {
2512 "Number of conditions and values must match!");
2513 ID.AddPointer(ValType);
2517 while (Case != CondRange.
end()) {
2518 ID.AddPointer(*Case++);
2519 ID.AddPointer(*Val++);
2525 ID,
ArrayRef(getTrailingObjects<const Init *>(), NumConds),
2526 ArrayRef(getTrailingObjects<const Init *>() + NumConds, NumConds),
2534 "Number of conditions and values must match!");
2545 totalSizeToAlloc<const Init *>(2 * CondRange.
size()),
alignof(
BitsInit));
2548 std::uninitialized_copy(CondRange.
begin(), CondRange.
end(),
2549 I->getTrailingObjects<
const Init *>());
2550 std::uninitialized_copy(ValRange.
begin(), ValRange.
end(),
2551 I->getTrailingObjects<
const Init *>() +
2559 bool Changed =
false;
2563 Changed |= NewCase != Case;
2570 Changed |= NewVal != Val;
2582 for (
unsigned i = 0; i < NumConds; ++i) {
2586 if (
const auto *CondI = dyn_cast_or_null<IntInit>(
2588 if (CondI->getValue())
2597 " does not have any true condition in:" +
2598 this->getAsString());
2604 if (!Case->isConcrete())
2608 if (!Val->isConcrete())
2616 if (!Case->isComplete())
2620 if (!Val->isConcrete())
2627 std::string Result =
"!cond(";
2634 return Result +
")";
2650 while (Arg != ArgRange.
end()) {
2652 ID.AddPointer(*Arg++);
2672 ArgRange.
size(), NameRange.
size()),
2675 std::uninitialized_copy(ArgRange.
begin(), ArgRange.
end(),
2676 I->getTrailingObjects<
const Init *>());
2677 std::uninitialized_copy(NameRange.
begin(), NameRange.
end(),
2685 ArrayRef<std::pair<const Init *, const StringInit *>>
args) {
2689 for (
const auto &Arg :
args) {
2690 Args.push_back(Arg.first);
2699 ID, Val, ValName,
ArrayRef(getTrailingObjects<const Init *>(), NumArgs),
2700 ArrayRef(getTrailingObjects<const StringInit *>(), NumArgNames));
2704 if (
const auto *DefI = dyn_cast<DefInit>(Val))
2705 return DefI->getDef();
2711 for (
unsigned i = 0, e =
getNumArgs(); i < e; ++i) {
2716 return std::nullopt;
2722 bool ArgsChanged =
false;
2726 ArgsChanged |= NewArg != Arg;
2730 if (
Op != Val || ArgsChanged)
2740 if (!Elt->isConcrete())
2753 for (
unsigned i = 1, e =
getNumArgs(); i != e; ++i) {
2758 return Result +
")";
2766 :
Name(
N), TyAndKind(
T, K) {
2768 assert(
Value &&
"Cannot create unset value for current type!");
2774 :
Name(
N), Loc(Loc), TyAndKind(
T, K) {
2776 assert(
Value &&
"Cannot create unset value for current type!");
2780 return cast<StringInit>(
getNameInit())->getValue();
2785 if (
const auto *StrInit = dyn_cast<StringInit>(
Value)) {
2786 if (StrInit->hasCodeFormat())
2794 return TyAndKind.getPointer()->getAsString();
2804 if (
const auto *BTy = dyn_cast<BitsRecTy>(
getType())) {
2805 if (!isa<BitsInit>(
Value)) {
2807 Bits.reserve(BTy->getNumBits());
2808 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2809 Bits.push_back(
Value->getBit(
I));
2814 return Value ==
nullptr;
2829 if (
const auto *BTy = dyn_cast<BitsRecTy>(
getType())) {
2830 if (!isa<BitsInit>(
Value)) {
2832 Bits.reserve(BTy->getNumBits());
2833 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2834 Bits.push_back(
Value->getBit(
I));
2839 return Value ==
nullptr;
2845#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2857 if (PrintSem)
OS <<
";\n";
2861 assert(Locs.size() == 1);
2862 ForwardDeclarationLocs.push_back(Locs.front());
2865 Locs.push_back(Loc);
2868void Record::checkName() {
2870 const auto *TypedName = cast<const TypedInit>(Name);
2871 if (!isa<StringRecTy>(TypedName->getType()))
2873 "' is not a string!");
2883 if (!CorrespondingDefInit) {
2884 CorrespondingDefInit =
2887 return CorrespondingDefInit;
2918 for (
int I = SCs.
size() - 1;
I >= 0; --
I) {
2919 const Record *SC = SCs[
I].first;
2920 if (SC == Superclass)
2922 I -= SC->getSuperClasses().size();
2932 while (!SCs.
empty()) {
2934 SCs = SCs.
drop_back(1 + SC->getSuperClasses().size());
2942 if (NewName != OldName) {
2949 if (SkipVal == &
Value)
2952 const Init *VR = V->resolveReferences(R);
2953 if (
Value.setValue(VR)) {
2955 if (
const auto *VRT = dyn_cast<TypedInit>(VR))
2957 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
2960 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
2961 Value.getNameInitAsString() +
"' of type '" +
2970 for (
auto &Assertion : Assertions) {
2971 const Init *
Value = Assertion.Condition->resolveReferences(R);
2972 Assertion.Condition =
Value;
2973 Value = Assertion.Message->resolveReferences(R);
2974 Assertion.Message =
Value;
2977 for (
auto &Dump : Dumps) {
2978 const Init *
Value = Dump.Message->resolveReferences(R);
2979 Dump.Message =
Value;
2990#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2995 OS << R.getNameInitAsString();
2998 if (!TArgs.
empty()) {
3000 bool NeedComma =
false;
3001 for (
const Init *TA : TArgs) {
3002 if (NeedComma)
OS <<
", ";
3005 assert(RV &&
"Template argument record not found??");
3015 for (
const auto &[SC,
_] : SC)
3016 OS <<
" " << SC->getNameInitAsString();
3020 for (
const RecordVal &Val : R.getValues())
3021 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3023 for (
const RecordVal &Val : R.getValues())
3024 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3034 "' does not have a field named `" + FieldName +
"'!\n");
3040 if (!R || !R->getValue())
3042 "' does not have a field named `" + FieldName +
"'!\n");
3043 return R->getValue();
3050 "' does not have a field named `" + FieldName +
"'!\n");
3054std::optional<StringRef>
3057 if (!R || !R->getValue())
3058 return std::nullopt;
3059 if (isa<UnsetInit>(R->getValue()))
3060 return std::nullopt;
3062 if (
const auto *SI = dyn_cast<StringInit>(R->getValue()))
3063 return SI->getValue();
3066 "Record `" +
getName() +
"', ` field `" + FieldName +
3067 "' exists but does not have a string initializer!");
3072 if (!R || !R->getValue())
3074 "' does not have a field named `" + FieldName +
"'!\n");
3076 if (
const auto *BI = dyn_cast<BitsInit>(R->getValue()))
3079 "' exists but does not have a bits value");
3084 if (!R || !R->getValue())
3086 "' does not have a field named `" + FieldName +
"'!\n");
3088 if (
const auto *LI = dyn_cast<ListInit>(R->getValue()))
3091 "' exists but does not have a list value");
3094std::vector<const Record *>
3097 std::vector<const Record *> Defs;
3098 for (
const Init *
I :
List->getValues()) {
3099 if (
const auto *DI = dyn_cast<DefInit>(
I))
3100 Defs.push_back(DI->getDef());
3104 "' list is not entirely DefInit!");
3111 if (!R || !R->getValue())
3113 "' does not have a field named `" + FieldName +
"'!\n");
3115 if (
const auto *
II = dyn_cast<IntInit>(R->getValue()))
3116 return II->getValue();
3119 "' exists but does not have an int value: " +
3120 R->getValue()->getAsString());
3126 std::vector<int64_t> Ints;
3127 for (
const Init *
I :
List->getValues()) {
3128 if (
const auto *
II = dyn_cast<IntInit>(
I))
3129 Ints.push_back(
II->getValue());
3132 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3133 "' exists but does not have a list of ints value: " +
3139std::vector<StringRef>
3142 std::vector<StringRef> Strings;
3143 for (
const Init *
I :
List->getValues()) {
3144 if (
const auto *SI = dyn_cast<StringInit>(
I))
3145 Strings.push_back(SI->getValue());
3148 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3149 "' exists but does not have a list of strings value: " +
3157 if (!R || !R->getValue())
3159 "' does not have a field named `" + FieldName +
"'!\n");
3161 if (
const auto *DI = dyn_cast<DefInit>(R->getValue()))
3162 return DI->getDef();
3164 FieldName +
"' does not have a def initializer!");
3169 if (!R || !R->getValue())
3171 "' does not have a field named `" + FieldName +
"'!\n");
3173 if (
const auto *DI = dyn_cast<DefInit>(R->getValue()))
3174 return DI->getDef();
3175 if (isa<UnsetInit>(R->getValue()))
3178 FieldName +
"' does not have either a def initializer or '?'!");
3183 if (!R || !R->getValue())
3185 "' does not have a field named `" + FieldName +
"'!\n");
3187 if (
const auto *BI = dyn_cast<BitInit>(R->getValue()))
3188 return BI->getValue();
3190 FieldName +
"' does not have a bit initializer!");
3195 if (!R || !R->getValue())
3197 "' does not have a field named `" + FieldName.
str() +
"'!\n");
3199 if (isa<UnsetInit>(R->getValue())) {
3204 if (
const auto *BI = dyn_cast<BitInit>(R->getValue()))
3205 return BI->getValue();
3207 FieldName +
"' does not have a bit initializer!");
3212 if (!R || !R->getValue())
3214 "' does not have a field named `" + FieldName +
"'!\n");
3216 if (
const auto *DI = dyn_cast<DagInit>(R->getValue()))
3219 FieldName +
"' does not have a dag initializer!");
3230 bool AnyFailed =
false;
3234 AnyFailed |=
CheckAssert(Assertion.Loc, Condition, Message);
3242 PrintError(
this,
"assertion failed in this record");
3249 for (
const auto &Dump :
getDumps()) {
3250 const Init *Message = Dump.Message->resolveReferences(R);
3266 : Impl(
std::make_unique<
detail::RecordKeeperImpl>(*this)),
3271#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3276 OS <<
"------------- Classes -----------------\n";
3278 OS <<
"class " << *
C.second;
3280 OS <<
"------------- Defs -----------------\n";
3282 OS <<
"def " << *
D.second;
3296 auto [Iter, Inserted] = Cache.try_emplace(ClassName.
str());
3299 return Iter->second;
3302std::vector<const Record *>
3305 std::vector<const Record *> Defs;
3307 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
3308 for (
const auto &ClassName : ClassNames) {
3315 for (
const auto &OneDef :
getDefs()) {
3317 return OneDef.second->isSubClassOf(Class);
3319 Defs.push_back(OneDef.second.get());
3333 Impl->dumpAllocationStats(
OS);
3337 auto It = Map.find(VarName);
3338 if (It == Map.end())
3341 const Init *
I = It->second.V;
3343 if (!It->second.Resolved && Map.size() > 1) {
3347 I =
I->resolveReferences(*
this);
3348 Map[VarName] = {
I,
true};
3355 const Init *Val = Cache.lookup(VarName);
3363 if (!isa<UnsetInit>(RV->getValue())) {
3364 Val = RV->getValue();
3365 Stack.push_back(VarName);
3370 Stack.push_back(VarName);
3375 Cache[VarName] = Val;
3380 const Init *
I =
nullptr;
3384 if (
I && !FoundUnresolved) {
3389 I->resolveReferences(Sub);
3390 FoundUnresolved |= Sub.FoundUnresolved;
3395 FoundUnresolved =
true;
3400 if (VarName == VarNameToTrack)
This file defines the StringMap class.
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines a hash set that can be used to remove duplication of nodes in a graph.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Range)
static bool canFitInBitfield(int64_t Value, unsigned NumBits)
static std::optional< unsigned > getDagArgNoByKey(const DagInit *Dag, const Init *Key, std::string &Error)
static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *LHS, const Init *RHS, const RecTy *Type)
static const StringInit * ConcatStringInits(const StringInit *I0, const StringInit *I1)
static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type)
static void ProfileExistsOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)
static const ListInit * ConcatListInits(const ListInit *LHS, const ListInit *RHS)
static void ProfileCondOpInit(FoldingSetNodeID &ID, ArrayRef< const Init * > CondRange, ArrayRef< const Init * > ValRange, const RecTy *ValType)
static const StringInit * interleaveStringList(const ListInit *List, const StringInit *Delim)
static void ProfileFoldOpInit(FoldingSetNodeID &ID, const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *Op, const RecTy *Type)
static void ProfileArgumentInit(FoldingSetNodeID &ID, const Init *Value, ArgAuxType Aux)
static const Init * ForeachDagApply(const Init *LHS, const DagInit *MHSd, const Init *RHS, const Record *CurRec)
static const Init * FilterHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)
static const Init * ItemApply(const Init *LHS, const Init *MHSe, const Init *RHS, const Record *CurRec)
static const RecordRecTy * resolveRecordTypes(const RecordRecTy *T1, const RecordRecTy *T2)
static void ProfileRecordRecTy(FoldingSetNodeID &ID, ArrayRef< const Record * > Classes)
static const Init * ForeachHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)
static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V, const StringInit *VN, ArrayRef< const Init * > ArgRange, ArrayRef< const StringInit * > NameRange)
static void ProfileVarDefInit(FoldingSetNodeID &ID, const Record *Class, ArrayRef< const ArgumentInit * > Args)
static void ProfileIsAOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)
static const StringInit * interleaveIntList(const ListInit *List, const StringInit *Delim)
static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Range, const RecTy *EltTy)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckType(MVT::SimpleValueType VT, SDValue N, const TargetLowering *TLI, const DataLayout &DL)
This file defines the SmallString class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static constexpr int Concat[]
"anonymous_n" - Represent an anonymous record name
static AnonymousNameInit * get(RecordKeeper &RK, unsigned)
const StringInit * getNameInit() const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const ArgumentInit * cloneWithValue(const Init *Value) const
void Profile(FoldingSetNodeID &ID) const
static const ArgumentInit * get(const Init *Value, ArgAuxType Aux)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
size_t size() const
size - Get the array size.
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
bool empty() const
empty - Check if the array is empty.
!op (X, Y) - Combine two inits.
static const BinOpInit * get(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
void Profile(FoldingSetNodeID &ID) const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
static const Init * getStrConcat(const Init *lhs, const Init *rhs)
std::string getAsString() const override
Convert this value to a literal form.
BinaryOp getOpcode() const
const Init * getRHS() const
std::optional< bool > CompareInit(unsigned Opc, const Init *LHS, const Init *RHS) const
const Init * getLHS() const
static const Init * getListConcat(const TypedInit *lhs, const Init *rhs)
const Init * Fold(const Record *CurRec) const
'true'/'false' - Represent a concrete initializer for a bit.
static BitInit * get(RecordKeeper &RK, bool V)
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
'bit' - Represent a single bit
static const BitRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
'{ a, b, c }' - Represents an initializer for a BitsRecTy value.
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
unsigned getNumBits() const
std::optional< int64_t > convertInitializerToInt() const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
static BitsInit * get(RecordKeeper &RK, ArrayRef< const Init * > Range)
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
'bits<n>' - Represent a fixed number of bits
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
static const BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
std::string getAsString() const override
Allocate memory in an ever growing pool, as if by bump-pointer.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
!cond(condition_1: value1, ... , condition_n: value) Selects the first value for which condition is t...
static const CondOpInit * get(ArrayRef< const Init * > C, ArrayRef< const Init * > V, const RecTy *Type)
const Init * Fold(const Record *CurRec) const
ArrayRef< const Init * > getVals() const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * getCond(unsigned Num) const
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
unsigned getNumConds() const
const RecTy * getValType() const
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
const Init * getVal(unsigned Num) const
ArrayRef< const Init * > getConds() const
This class represents an Operation in the Expression.
(v a, b) - Represent a DAG tree value.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
unsigned getNumArgs() const
const StringInit * getArgName(unsigned Num) const
std::optional< unsigned > getArgNo(StringRef Name) const
This method looks up the specified argument name and returns its argument number or std::nullopt if t...
void Profile(FoldingSetNodeID &ID) const
const Init * getOperator() const
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > ArgRange, ArrayRef< const StringInit * > NameRange)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
ArrayRef< const StringInit * > getArgNames() const
const Record * getOperatorAsDef(ArrayRef< SMLoc > Loc) const
const Init * getArg(unsigned Num) const
ArrayRef< const Init * > getArgs() const
std::string getAsString() const override
Convert this value to a literal form.
'dag' - Represent a dag fragment
std::string getAsString() const override
static const DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
std::string getAsString() const override
Convert this value to a literal form.
const RecTy * getFieldType(const StringInit *FieldName) const override
This method is used to implement the FieldInit class.
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
Lightweight error class with error context and mandatory checking.
!exists<type>(expr) - Dynamically determine if a record of type named expr exists.
void Profile(FoldingSetNodeID &ID) const
static const ExistsOpInit * get(const RecTy *CheckType, const Init *Expr)
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
X.Y - Represent a reference to a subfield of a variable.
const Init * Fold(const Record *CurRec) const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
static const FieldInit * get(const Init *R, const StringInit *FN)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
!foldl (a, b, expr, start, lst) - Fold over a list.
const Init * Fold(const Record *CurRec) const
std::string getAsString() const override
Convert this value to a literal form.
static const FoldOpInit * get(const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
void Profile(FoldingSetNodeID &ID) const
void InsertNode(T *N, void *InsertPos)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
virtual const Init * resolveReferences(Resolver &R) const
This function is used by classes that refer to other variables which may not be defined at the time t...
virtual std::string getAsUnquotedString() const
Convert this value to a literal form, without adding quotes around a string.
void dump() const
Debugging method that may be called through a debugger; just invokes print on stderr.
void print(raw_ostream &OS) const
Print this value.
virtual std::string getAsString() const =0
Convert this value to a literal form.
virtual bool isConcrete() const
Is this a concrete and fully resolved value without any references or stuck operations?...
virtual bool isComplete() const
Is this a complete value with no unset (uninitialized) subvalues?
virtual const Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual const Init * convertInitializerTo(const RecTy *Ty) const =0
Convert to a value whose type is Ty, or return null if this is not possible.
RecordKeeper & getRecordKeeper() const
Get the record keeper that initialized this Init.
'7' - Represent an initialization by a literal integer value.
static IntInit * get(RecordKeeper &RK, int64_t V)
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
std::string getAsString() const override
Convert this value to a literal form.
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
'int' - Represent an integer value of no particular size
static const IntRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
!isa<type>(expr) - Dynamically determine the type of an expression.
static const IsAOpInit * get(const RecTy *CheckType, const Init *Expr)
void Profile(FoldingSetNodeID &ID) const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * Fold() const
[AL, AH, CL] - Represent a list of defs
std::string getAsString() const override
Convert this value to a literal form.
const RecTy * getElementType() const
const Record * getElementAsRecord(unsigned i) const
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
const Init * resolveReferences(Resolver &R) const override
This method is used by classes that refer to other variables which may not be defined at the time the...
const Init * getElement(unsigned i) const
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
void Profile(FoldingSetNodeID &ID) const
ArrayRef< const Init * > getValues() const
'list<Ty>' - Represent a list of element values, all of which must be of the specified type.
const RecTy * getElementType() const
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
std::string getAsString() const override
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
Resolve arbitrary mappings.
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
const Init * getBit(unsigned Bit) const final
Get the Init value of the specified bit.
RecordKeeper & getRecordKeeper() const
Return the RecordKeeper that uniqued this Type.
virtual bool typeIsA(const RecTy *RHS) const
Return true if 'this' type is equal to or a subtype of RHS.
virtual bool typeIsConvertibleTo(const RecTy *RHS) const
Return true if all values of 'this' type can be converted to the specified type.
RecTyKind
Subclass discriminator (for dyn_cast<> et al.)
virtual std::string getAsString() const =0
const ListRecTy * getListTy() const
Returns the type representing list<thistype>.
void print(raw_ostream &OS) const
const Record * getClass(StringRef Name) const
Get the class with the specified name.
const RecordMap & getClasses() const
Get the map of classes.
const Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
const RecordMap & getDefs() const
Get the map of records (defs).
detail::RecordKeeperImpl & getImpl()
Return the internal implementation of the RecordKeeper.
void dumpAllocationStats(raw_ostream &OS) const
ArrayRef< const Record * > getAllDerivedDefinitionsIfDefined(StringRef ClassName) const
Get all the concrete records that inherit from specified class, if the class is defined.
const Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
ArrayRef< const Record * > getAllDerivedDefinitions(StringRef ClassName) const
Get all the concrete records that inherit from the one specified class.
'[classname]' - Type of record values that have zero or more superclasses.
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
bool isSubClassOf(const Record *Class) const
ArrayRef< const Record * > getClasses() const
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
static const RecordRecTy * get(RecordKeeper &RK, ArrayRef< const Record * > Classes)
Get the record type with the given non-redundant list of superclasses.
Resolve all variables from a record except for unset variables.
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
This class represents a field in a record, including its name, type, value, and source location.
std::string getNameInitAsString() const
Get the name of the field as a std::string.
bool isNonconcreteOK() const
Is this a field where nonconcrete values are okay?
bool setValue(const Init *V)
Set the value of the field from an Init.
RecordKeeper & getRecordKeeper() const
Get the record keeper used to unique this value.
const SMLoc & getLoc() const
Get the source location of the point where the field was defined.
const Init * getValue() const
Get the value of the field as an Init.
StringRef getName() const
Get the name of the field as a StringRef.
void print(raw_ostream &OS, bool PrintSem=true) const
Print the value to an output stream, possibly with a semicolon.
RecordVal(const Init *N, const RecTy *T, FieldKind K)
const Init * getNameInit() const
Get the name of the field as an Init.
std::string getPrintType() const
Get the type of the field for printing purposes.
const RecTy * getType() const
Get the type of the field value as a RecTy.
std::vector< int64_t > getValueAsListOfInts(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of integers,...
const RecordRecTy * getType() const
const Init * getValueInit(StringRef FieldName) const
Return the initializer for a value with the specified name, or throw an exception if the field does n...
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const
This method looks up the specified field and returns its value as a bit.
bool getValueAsBit(StringRef FieldName) const
This method looks up the specified field and returns its value as a bit, throwing an exception if the...
ArrayRef< std::pair< const Record *, SMRange > > getSuperClasses() const
static unsigned getNewUID(RecordKeeper &RK)
ArrayRef< SMLoc > getLoc() const
void checkUnusedTemplateArgs()
ArrayRef< DumpInfo > getDumps() const
std::vector< const Record * > getValueAsListOfDefs(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of records,...
ArrayRef< AssertionInfo > getAssertions() const
std::string getNameInitAsString() const
const Record * getValueAsDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, throwing an exception if ...
RecordKeeper & getRecords() const
const DagInit * getValueAsDag(StringRef FieldName) const
This method looks up the specified field and returns its value as an Dag, throwing an exception if th...
std::vector< StringRef > getValueAsListOfStrings(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of strings,...
const RecordVal * getValue(const Init *Name) const
void addValue(const RecordVal &RV)
const Record * getValueAsOptionalDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, returning null if the fie...
bool hasDirectSuperClass(const Record *SuperClass) const
Determine whether this record has the specified direct superclass.
StringRef getName() const
void setName(const Init *Name)
const ListInit * getValueAsListInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a ListInit, throwing an exception i...
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
DefInit * getDefInit() const
get the corresponding DefInit.
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void resolveReferences(const Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
std::optional< StringRef > getValueAsOptionalString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
void removeValue(const Init *Name)
ArrayRef< const Init * > getTemplateArgs() const
void updateClassLoc(SMLoc Loc)
const BitsInit * getValueAsBitsInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a BitsInit, throwing an exception i...
void getDirectSuperClasses(SmallVectorImpl< const Record * > &Classes) const
Append the direct superclasses of this record to Classes.
void appendAssertions(const Record *Rec)
const Init * getNameInit() const
int64_t getValueAsInt(StringRef FieldName) const
This method looks up the specified field and returns its value as an int64_t, throwing an exception i...
void addSuperClass(const Record *R, SMRange Range)
void checkRecordAssertions()
StringRef getValueAsString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
const Record * getCurrentRecord() const
virtual const Init * resolve(const Init *VarName)=0
Return the initializer for the given variable name (should normally be a StringInit),...
Represents a location in source code.
Represents a range in source code.
Delegate resolving to a sub-resolver, but shadow some variable names.
void addShadow(const Init *Key)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
"foo" - Represent an initialization by a string value.
static const StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
StringFormat getFormat() const
StringRef getValue() const
static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2)
std::string getAsUnquotedString() const override
Convert this value to a literal form, without adding quotes around a string.
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
'string' - Represent an string value
std::string getAsString() const override
static const StringRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
!op (X, Y, Z) - Combine two inits.
const Init * Fold(const Record *CurRec) const
const Init * getLHS() const
void Profile(FoldingSetNodeID &ID) const
const Init * getMHS() const
const Init * getRHS() const
static const TernOpInit * get(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs, const RecTy *Type)
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
TernaryOp getOpcode() const
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
(Optionally) delegate resolving to a sub-resolver, and keep track whether there were unresolved refer...
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
bool foundUnresolved() const
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This is the common superclass of types that have a specific, explicit type, stored in ValueTy.
const RecTy * getFieldType(const StringInit *FieldName) const override
This method is used to implement the FieldInit class.
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
RecordKeeper & getRecordKeeper() const
Get the record keeper that initialized this Init.
const Init * getCastTo(const RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
const RecTy * getType() const
Get the type of the Init as a RecTy.
!op (X) - Transform an init.
const Init * getOperand() const
UnaryOp getOpcode() const
static const UnOpInit * get(UnaryOp opc, const Init *lhs, const RecTy *Type)
void Profile(FoldingSetNodeID &ID) const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
'?' - Represents an uninitialized value.
const Init * getCastTo(const RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
static UnsetInit * get(RecordKeeper &RK)
Get the singleton unset Init.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
Opcode{0} - Represent access to one bit of a variable or field.
static const VarBitInit * get(const TypedInit *T, unsigned B)
unsigned getBitNum() const
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
classname<targs...> - Represent an uninstantiated anonymous class instantiation.
ArrayRef< const ArgumentInit * > args() const
static const VarDefInit * get(SMLoc Loc, const Record *Class, ArrayRef< const ArgumentInit * > Args)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * Fold() const
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
'Opcode' - Represent a reference to an entire variable object.
static const VarInit * get(StringRef VN, const RecTy *T)
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
StringRef getName() const
const Init * getNameInit() const
const Init * resolveReferences(Resolver &R) const override
This method is used by classes that refer to other variables which may not be defined at the time the...
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
void PrintFatalError(const Twine &Msg)
void PrintError(const Twine &Msg)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void PrintWarning(const Twine &Msg)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
std::variant< unsigned, const Init * > ArgAuxType
void dumpMessage(SMLoc Loc, const Init *Message)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
Implement std::hash so that hash_code can be used in STL containers.
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
Sorting predicate to sort record pointers by name.
This class represents the internal implementation of the RecordKeeper.
FoldingSet< BitsInit > TheBitsInitPool
std::map< int64_t, IntInit * > TheIntInitPool
FoldingSet< FoldOpInit > TheFoldOpInitPool
DenseMap< std::pair< const RecTy *, const Init * >, VarInit * > TheVarInitPool
FoldingSet< IsAOpInit > TheIsAOpInitPool
FoldingSet< DagInit > TheDagInitPool
FoldingSet< CondOpInit > TheCondOpInitPool
FoldingSet< BinOpInit > TheBinOpInitPool
FoldingSet< ArgumentInit > TheArgumentInitPool
StringRecTy SharedStringRecTy
FoldingSet< RecordRecTy > RecordTypePool
FoldingSet< VarDefInit > TheVarDefInitPool
StringMap< const StringInit *, BumpPtrAllocator & > StringInitCodePool
DenseMap< std::pair< const TypedInit *, unsigned >, VarBitInit * > TheVarBitInitPool
std::vector< BitsRecTy * > SharedBitsRecTys
FoldingSet< UnOpInit > TheUnOpInitPool
void dumpAllocationStats(raw_ostream &OS) const
DenseMap< std::pair< const Init *, const StringInit * >, FieldInit * > TheFieldInitPool
FoldingSet< TernOpInit > TheTernOpInitPool
BumpPtrAllocator Allocator
FoldingSet< ExistsOpInit > TheExistsOpInitPool
StringMap< const StringInit *, BumpPtrAllocator & > StringInitStringPool
FoldingSet< ListInit > TheListInitPool
RecordKeeperImpl(RecordKeeper &RK)