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 <<
"TheBitsInitPool size = " << TheBitsInitPool.size() <<
'\n';
110 OS <<
"TheListInitPool size = " << TheListInitPool.size() <<
'\n';
111 OS <<
"TheUnOpInitPool size = " << TheUnOpInitPool.size() <<
'\n';
112 OS <<
"TheBinOpInitPool size = " << TheBinOpInitPool.size() <<
'\n';
113 OS <<
"TheTernOpInitPool size = " << TheTernOpInitPool.size() <<
'\n';
114 OS <<
"TheFoldOpInitPool size = " << TheFoldOpInitPool.size() <<
'\n';
115 OS <<
"TheIsAOpInitPool size = " << TheIsAOpInitPool.size() <<
'\n';
116 OS <<
"TheExistsOpInitPool size = " << TheExistsOpInitPool.size() <<
'\n';
117 OS <<
"TheCondOpInitPool size = " << TheCondOpInitPool.size() <<
'\n';
118 OS <<
"TheDagInitPool size = " << TheDagInitPool.size() <<
'\n';
119 OS <<
"RecordTypePool size = " << RecordTypePool.size() <<
'\n';
120 OS <<
"TheVarInitPool size = " << TheVarInitPool.size() <<
'\n';
121 OS <<
"TheVarBitInitPool size = " << TheVarBitInitPool.size() <<
'\n';
122 OS <<
"TheVarDefInitPool size = " << TheVarDefInitPool.size() <<
'\n';
123 OS <<
"TheFieldInitPool size = " << TheFieldInitPool.size() <<
'\n';
124 OS <<
"Bytes allocated = " <<
Allocator.getBytesAllocated() <<
'\n';
125 OS <<
"Total allocator memory = " <<
Allocator.getTotalMemory() <<
"\n\n";
127 OS <<
"Number of records instantiated = " << LastRecordID <<
'\n';
128 OS <<
"Number of anonymous records = " << AnonCounter <<
'\n';
135#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
147 return Kind ==
RHS->getRecTyKind();
159 if (
const auto *BitsTy = dyn_cast<BitsRecTy>(
RHS))
160 return BitsTy->getNumBits() == 1;
175 return "bits<" + utostr(Size) +
">";
180 return cast<BitsRecTy>(
RHS)->Size == Size;
212 if (
const auto *ListTy = dyn_cast<ListRecTy>(
RHS))
218 if (
const auto *RHSl = dyn_cast<ListRecTy>(
RHS))
233 ID.AddInteger(Classes.
size());
234 for (
const Record *R : Classes)
241 if (UnsortedClasses.
empty())
248 return LHS->getNameInitAsString() <
RHS->getNameInitAsString();
260 for (
unsigned i = 0; i < Classes.
size(); ++i) {
261 for (
unsigned j = 0; j < Classes.
size(); ++j) {
264 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
269 totalSizeToAlloc<const Record *>(Classes.
size()),
alignof(
RecordRecTy));
271 std::uninitialized_copy(Classes.
begin(), Classes.
end(),
278 assert(Class &&
"unexpected null class");
279 return get(Class->getRecords(), {Class});
288 return getClasses()[0]->getNameInitAsString();
290 std::string Str =
"{";
296 Str += R->getNameInitAsString();
304 return MySuperClass == Class || MySuperClass->
isSubClassOf(Class);
312 const auto *RTy = dyn_cast<RecordRecTy>(
RHS);
317 return isSubClassOf(TargetClass);
330 while (!Stack.empty()) {
331 const Record *R = Stack.pop_back_val();
336 R->getDirectSuperClasses(Stack);
347 if (
const auto *RecTy1 = dyn_cast<RecordRecTy>(
T1)) {
348 if (
const auto *RecTy2 = dyn_cast<RecordRecTy>(T2))
352 assert(
T1 !=
nullptr &&
"Invalid record type");
353 if (
T1->typeIsConvertibleTo(T2))
356 assert(T2 !=
nullptr &&
"Invalid record type");
360 if (
const auto *ListTy1 = dyn_cast<ListRecTy>(
T1)) {
361 if (
const auto *ListTy2 = dyn_cast<ListRecTy>(T2)) {
362 const RecTy *NewType =
363 resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());
376void Init::anchor() {}
378#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
383 if (
auto *TyInit = dyn_cast<TypedInit>(
this))
384 return TyInit->getType()->getRecordKeeper();
385 if (
auto *ArgInit = dyn_cast<ArgumentInit>(
this))
386 return ArgInit->getRecordKeeper();
387 return cast<UnsetInit>(
this)->getRecordKeeper();
402 auto I = Aux.index();
405 ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
407 ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
432 const Init *NewValue =
Value->resolveReferences(R);
433 if (NewValue !=
Value)
444 if (isa<BitRecTy>(Ty))
447 if (isa<IntRecTy>(Ty))
450 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
452 if (BRT->getNumBits() == 1)
477 totalSizeToAlloc<const Init *>(
Range.size()),
alignof(
BitsInit));
479 std::uninitialized_copy(
Range.begin(),
Range.end(),
480 I->getTrailingObjects<
const Init *>());
490 if (isa<BitRecTy>(Ty)) {
495 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
498 if (
getNumBits() != BRT->getNumBits())
return nullptr;
502 if (isa<IntRecTy>(Ty)) {
513 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i)
514 if (
auto *Bit = dyn_cast<BitInit>(
getBit(i)))
515 Result |=
static_cast<int64_t
>(Bit->getValue()) << i;
525 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
528 NewBits[i] =
getBit(Bits[i]);
534 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
542 std::string Result =
"{ ";
543 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
544 if (i) Result +=
", ";
546 Result += Bit->getAsString();
550 return Result +
" }";
556 bool Changed =
false;
559 const Init *CachedBitVarRef =
nullptr;
560 const Init *CachedBitVarResolved =
nullptr;
562 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
564 const Init *NewBit = CurBit;
566 if (
const auto *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
567 if (CurBitVar->getBitVar() != CachedBitVarRef) {
568 CachedBitVarRef = CurBitVar->getBitVar();
571 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
572 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
578 if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
581 Changed |= CurBit != NewBit;
598 return itostr(
Value);
603 return (NumBits >=
sizeof(
Value) * 8) ||
604 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
608 if (isa<IntRecTy>(Ty))
611 if (isa<BitRecTy>(Ty)) {
613 if (Val != 0 && Val != 1)
return nullptr;
617 if (
const auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
624 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
637 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
656 return "anonymous_" + utostr(
Value);
661 auto *New = R.resolve(Old);
662 New = New ? New : Old;
664 if (
const auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
665 return Anonymous->getNameInit();
674 auto &Entry = *InitMap.insert(std::make_pair(V,
nullptr)).first;
681 if (isa<StringRecTy>(Ty))
688 const RecTy *EltTy) {
690 ID.AddPointer(EltTy);
697 const RecTy *EltTy) {
707 cast<TypedInit>(
Range[0])->getType()->typeIsConvertibleTo(EltTy));
710 totalSizeToAlloc<const Init *>(
Range.size()),
alignof(
ListInit));
712 std::uninitialized_copy(
Range.begin(),
Range.end(),
713 I->getTrailingObjects<
const Init *>());
719 const RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
728 if (
const auto *LRT = dyn_cast<ListRecTy>(Ty)) {
734 bool Changed =
false;
735 const RecTy *ElementType = LRT->getElementType();
737 if (
const Init *CI =
I->convertInitializerTo(ElementType)) {
738 Elements.push_back(CI);
753 assert(i < NumValues &&
"List element index out of range!");
754 const auto *DI = dyn_cast<DefInit>(
getElement(i));
762 Resolved.reserve(
size());
763 bool Changed =
false;
767 Changed |= E != CurElt;
768 Resolved.push_back(E);
777 for (
const Init *Element : *
this) {
785 for (
const Init *Element : *
this) {
793 std::string Result =
"[";
794 const char *sep =
"";
795 for (
const Init *Element : *
this) {
811 ID.AddInteger(Opcode);
840 if (
const auto *Def = dyn_cast<DefInit>(LHS)) {
843 OS << *Def->getDef();
856 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
860 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
864 if (isa<StringRecTy>(
getType())) {
865 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
868 if (
const auto *LHSd = dyn_cast<DefInit>(LHS))
871 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
875 }
else if (isa<RecordRecTy>(
getType())) {
876 if (
const auto *
Name = dyn_cast<StringInit>(LHS)) {
881 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
883 (Anonymous &&
Name == Anonymous->getNameInit())) {
890 auto PrintFatalErrorHelper = [CurRec](
const Twine &
T) {
899 PrintFatalErrorHelper(
Twine(
"Undefined reference to record: '") +
900 Name->getValue() +
"'\n");
907 PrintFatalErrorHelper(
Twine(
"Expected type '") +
921 if (isa<UnsetInit>(LHS))
928 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
934 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
935 assert(!LHSl->empty() &&
"Empty list in head");
936 return LHSl->getElement(0);
941 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
942 assert(!LHSl->empty() &&
"Empty list in tail");
945 return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
950 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
952 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
954 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
959 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
961 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
963 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
968 if (
const auto *Dag = dyn_cast<DagInit>(LHS)) {
971 auto *TI = cast<TypedInit>(Dag->getOperator());
972 if (!TI->getType()->typeIsA(
getType())) {
975 "', got '" + TI->getType()->getAsString() +
978 return Dag->getOperator();
984 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
986 int64_t LHSv = LHSi->getValue();
989 "Illegal operation: logtwo is undefined "
990 "on arguments less than or equal to 0");
994 "Log of an int64_t must be smaller than INT64_MAX");
1001 if (
const auto *LHSList = dyn_cast<ListInit>(LHS)) {
1002 const auto *InnerListTy = dyn_cast<ListRecTy>(LHSList->getElementType());
1008 [](
const ListInit *
List) -> std::optional<std::vector<const Init *>> {
1009 std::vector<const Init *> Flattened;
1011 for (
const Init *InnerInit :
List->getValues()) {
1012 const auto *InnerList = dyn_cast<ListInit>(InnerInit);
1014 return std::nullopt;
1015 for (
const Init *InnerElem : InnerList->getValues())
1016 Flattened.push_back(InnerElem);
1021 auto Flattened = Flatten(LHSList);
1023 return ListInit::get(*Flattened, InnerListTy->getElementType());
1035 ->Fold(R.getCurrentRecord(), R.isFinal());
1043 case NOT: Result =
"!not";
break;
1044 case HEAD: Result =
"!head";
break;
1045 case TAIL: Result =
"!tail";
break;
1046 case SIZE: Result =
"!size";
break;
1047 case EMPTY: Result =
"!empty";
break;
1048 case GETDAGOP: Result =
"!getdagop";
break;
1049 case LOG2 : Result =
"!logtwo";
break;
1051 Result =
"!listflatten";
1057 Result =
"!tolower";
1060 Result =
"!toupper";
1063 Result =
"!initialized";
1072 ID.AddInteger(Opcode);
1100 Concat.append(I1->getValue());
1108 if (
List->size() == 0)
1110 const auto *Element = dyn_cast<StringInit>(
List->getElement(0));
1116 for (
unsigned I = 1, E =
List->size();
I < E; ++
I) {
1118 const auto *Element = dyn_cast<StringInit>(
List->getElement(
I));
1121 Result.append(Element->getValue());
1130 if (
List->size() == 0)
1132 const auto *Element = dyn_cast_or_null<IntInit>(
1138 for (
unsigned I = 1, E =
List->size();
I < E; ++
I) {
1140 const auto *Element = dyn_cast_or_null<IntInit>(
1144 Result.append(Element->getAsString());
1151 if (
const auto *I0s = dyn_cast<StringInit>(I0))
1152 if (
const auto *I1s = dyn_cast<StringInit>(I1))
1170 if (
const auto *LHSList = dyn_cast<ListInit>(
LHS))
1171 if (
const auto *RHSList = dyn_cast<ListInit>(
RHS))
1177 const Init *RHS)
const {
1179 const auto *LHSi = dyn_cast_or_null<IntInit>(
1181 const auto *RHSi = dyn_cast_or_null<IntInit>(
1188 Result = LHSi->getValue() == RHSi->getValue();
1191 Result = LHSi->getValue() != RHSi->getValue();
1194 Result = LHSi->getValue() <= RHSi->getValue();
1197 Result = LHSi->getValue() < RHSi->getValue();
1200 Result = LHSi->getValue() >= RHSi->getValue();
1203 Result = LHSi->getValue() > RHSi->getValue();
1212 const auto *LHSs = dyn_cast<StringInit>(
LHS);
1213 const auto *RHSs = dyn_cast<StringInit>(
RHS);
1219 Result = LHSs->getValue() == RHSs->getValue();
1222 Result = LHSs->getValue() != RHSs->getValue();
1225 Result = LHSs->getValue() <= RHSs->getValue();
1228 Result = LHSs->getValue() < RHSs->getValue();
1231 Result = LHSs->getValue() >= RHSs->getValue();
1234 Result = LHSs->getValue() > RHSs->getValue();
1244 const auto *LHSd = dyn_cast<DefInit>(
LHS);
1245 const auto *RHSd = dyn_cast<DefInit>(
RHS);
1247 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1250 return std::nullopt;
1253static std::optional<unsigned>
1256 if (
const auto *
Idx = dyn_cast<IntInit>(Key)) {
1257 int64_t Pos =
Idx->getValue();
1261 (
Twine(
"index ") + std::to_string(Pos) +
Twine(
" is negative")).str();
1262 return std::nullopt;
1264 if (Pos >= Dag->getNumArgs()) {
1266 Error = (
Twine(
"index ") + std::to_string(Pos) +
1267 " is out of range (dag has " +
1268 std::to_string(Dag->getNumArgs()) +
" arguments)")
1270 return std::nullopt;
1274 assert(isa<StringInit>(Key));
1276 const auto *
Name = dyn_cast<StringInit>(Key);
1277 auto ArgNo = Dag->getArgNo(
Name->getValue());
1281 return std::nullopt;
1289 const auto *LHSs = dyn_cast<DagInit>(LHS);
1290 const auto *RHSs = dyn_cast<DagInit>(RHS);
1292 const auto *LOp = dyn_cast<DefInit>(LHSs->getOperator());
1293 const auto *ROp = dyn_cast<DefInit>(RHSs->getOperator());
1294 if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
1295 (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
1297 if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1299 LHSs->getAsString() +
"' vs. '" + RHSs->getAsString() +
1302 const Init *
Op = LOp ? LOp : ROp;
1308 for (
unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
1309 Args.push_back(LHSs->getArg(i));
1310 ArgNames.
push_back(LHSs->getArgName(i));
1312 for (
unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
1313 Args.push_back(RHSs->getArg(i));
1314 ArgNames.
push_back(RHSs->getArgName(i));
1321 const auto *LHSs = dyn_cast<ListInit>(LHS);
1322 const auto *RHSs = dyn_cast<ListInit>(RHS);
1332 const auto *
Value = dyn_cast<TypedInit>(LHS);
1333 const auto *
Size = dyn_cast<IntInit>(RHS);
1341 const auto *LHSs = dyn_cast<ListInit>(LHS);
1342 const auto *RHSs = dyn_cast<ListInit>(RHS);
1345 for (
const Init *EltLHS : *LHSs) {
1347 for (
const Init *EltRHS : *RHSs) {
1348 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1356 Args.push_back(EltLHS);
1363 const auto *TheList = dyn_cast<ListInit>(LHS);
1364 const auto *
Idx = dyn_cast<IntInit>(RHS);
1365 if (!TheList || !
Idx)
1367 auto i =
Idx->getValue();
1368 if (i < 0 || i >= (ssize_t)TheList->size())
1370 return TheList->getElement(i);
1373 const auto *TheList = dyn_cast<ListInit>(LHS);
1374 const auto *SliceIdxs = dyn_cast<ListInit>(RHS);
1375 if (!TheList || !SliceIdxs)
1378 Args.reserve(SliceIdxs->size());
1379 for (
auto *
I : *SliceIdxs) {
1380 auto *
II = dyn_cast<IntInit>(
I);
1383 auto i =
II->getValue();
1384 if (i < 0 || i >= (ssize_t)TheList->size())
1386 Args.push_back(TheList->getElement(i));
1391 const auto *LHSi = dyn_cast<IntInit>(LHS);
1392 const auto *RHSi = dyn_cast<IntInit>(RHS);
1396 auto Start = LHSi->getValue();
1397 auto End = RHSi->getValue();
1403 Args.reserve(
End - Start + 1);
1404 for (
auto i = Start; i <=
End; ++i)
1408 Args.reserve(Start -
End + 1);
1409 for (
auto i = Start; i >=
End; --i)
1412 }
else if (Start <
End) {
1414 Args.reserve(
End - Start);
1415 for (
auto i = Start; i <
End; ++i)
1423 const auto *LHSs = dyn_cast<StringInit>(LHS);
1424 const auto *RHSs = dyn_cast<StringInit>(RHS);
1430 const auto *
List = dyn_cast<ListInit>(LHS);
1431 const auto *Delim = dyn_cast<StringInit>(RHS);
1432 if (
List && Delim) {
1434 if (isa<StringRecTy>(
List->getElementType()))
1454 const auto *Dag = dyn_cast<DagInit>(LHS);
1455 if (Dag && isa<IntInit, StringInit>(RHS)) {
1461 assert(*ArgNo < Dag->getNumArgs());
1463 const Init *Arg = Dag->getArg(*ArgNo);
1464 if (
const auto *TI = dyn_cast<TypedInit>(Arg))
1465 if (!TI->getType()->typeIsConvertibleTo(
getType()))
1472 const auto *Dag = dyn_cast<DagInit>(LHS);
1473 const auto *
Idx = dyn_cast<IntInit>(RHS);
1475 int64_t Pos =
Idx->getValue();
1476 if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1479 Twine(
"!getdagname index is out of range 0...") +
1480 std::to_string(Dag->getNumArgs() - 1) +
": " +
1481 std::to_string(Pos));
1483 const Init *ArgName = Dag->getArgName(Pos);
1491 const auto *Dag = dyn_cast<DagInit>(LHS);
1492 const auto *
Op = dyn_cast<DefInit>(RHS);
1496 for (
unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
1497 Args.push_back(Dag->getArg(i));
1514 const auto *LHSi = dyn_cast_or_null<IntInit>(
1516 const auto *RHSi = dyn_cast_or_null<IntInit>(
1519 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
1523 case ADD: Result = LHSv + RHSv;
break;
1524 case SUB: Result = LHSv - RHSv;
break;
1525 case MUL: Result = LHSv * RHSv;
break;
1529 "Illegal operation: division by zero");
1530 else if (LHSv ==
INT64_MIN && RHSv == -1)
1532 "Illegal operation: INT64_MIN / -1");
1534 Result = LHSv / RHSv;
1536 case AND: Result = LHSv & RHSv;
break;
1537 case OR: Result = LHSv | RHSv;
break;
1538 case XOR: Result = LHSv ^ RHSv;
break;
1540 case SRA: Result = LHSv >> RHSv;
break;
1565 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1567 if ((
Opc ==
AND && !LHSi->getValue()) ||
1568 (
Opc ==
OR && LHSi->getValue() == -1))
1573 if (LHS != lhs || RHS != rhs)
1575 ->Fold(R.getCurrentRecord());
1587 case CONCAT: Result =
"!con";
break;
1588 case ADD: Result =
"!add";
break;
1589 case SUB: Result =
"!sub";
break;
1590 case MUL: Result =
"!mul";
break;
1591 case DIV: Result =
"!div";
break;
1592 case AND: Result =
"!and";
break;
1593 case OR: Result =
"!or";
break;
1594 case XOR: Result =
"!xor";
break;
1595 case SHL: Result =
"!shl";
break;
1596 case SRA: Result =
"!sra";
break;
1597 case SRL: Result =
"!srl";
break;
1598 case EQ: Result =
"!eq";
break;
1599 case NE: Result =
"!ne";
break;
1600 case LE: Result =
"!le";
break;
1601 case LT: Result =
"!lt";
break;
1602 case GE: Result =
"!ge";
break;
1603 case GT: Result =
"!gt";
break;
1604 case LISTCONCAT: Result =
"!listconcat";
break;
1605 case LISTSPLAT: Result =
"!listsplat";
break;
1607 Result =
"!listremove";
1609 case STRCONCAT: Result =
"!strconcat";
break;
1610 case INTERLEAVE: Result =
"!interleave";
break;
1611 case SETDAGOP: Result =
"!setdagop";
break;
1616 Result =
"!getdagname";
1625 ID.AddInteger(Opcode);
1656 return RHS->resolveReferences(R);
1661 bool Change =
false;
1667 for (
unsigned int i = 0; i < MHSd->
getNumArgs(); ++i) {
1672 if (
const auto *Argd = dyn_cast<DagInit>(Arg))
1677 NewArgs.
push_back(std::make_pair(NewArg, ArgName));
1691 if (
const auto *MHSd = dyn_cast<DagInit>(MHS))
1694 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1697 for (
const Init *&Item : NewList) {
1699 if (NewItem != Item)
1713 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1716 for (
const Init *Item : MHSl->getValues()) {
1720 if (
const auto *IncludeInt =
1721 dyn_cast_or_null<IntInit>(
Include->convertInitializerTo(
1723 if (IncludeInt->getValue())
1739 const auto *LHSd = dyn_cast<DefInit>(LHS);
1740 const auto *LHSv = dyn_cast<VarInit>(LHS);
1741 const auto *LHSs = dyn_cast<StringInit>(LHS);
1743 const auto *MHSd = dyn_cast<DefInit>(MHS);
1744 const auto *MHSv = dyn_cast<VarInit>(MHS);
1745 const auto *MHSs = dyn_cast<StringInit>(MHS);
1747 const auto *RHSd = dyn_cast<DefInit>(RHS);
1748 const auto *RHSv = dyn_cast<VarInit>(RHS);
1749 const auto *RHSs = dyn_cast<StringInit>(RHS);
1751 if (LHSd && MHSd && RHSd) {
1752 const Record *Val = RHSd->getDef();
1753 if (LHSd->getAsString() == RHSd->getAsString())
1754 Val = MHSd->getDef();
1757 if (LHSv && MHSv && RHSv) {
1758 std::string Val = std::string(RHSv->getName());
1759 if (LHSv->getAsString() == RHSv->getAsString())
1760 Val = std::string(MHSv->getName());
1763 if (LHSs && MHSs && RHSs) {
1764 std::string Val = std::string(RHSs->getValue());
1766 std::string::size_type found;
1767 std::string::size_type idx = 0;
1769 found = Val.find(std::string(LHSs->getValue()), idx);
1770 if (found == std::string::npos)
1772 Val.replace(found, LHSs->getValue().size(),
1773 std::string(MHSs->getValue()));
1774 idx = found + MHSs->getValue().size();
1795 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1797 if (LHSi->getValue())
1805 const auto *MHSl = dyn_cast<ListInit>(MHS);
1806 const auto *RHSl = dyn_cast<ListInit>(RHS);
1807 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1808 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1810 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1813 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
1815 unsigned Size = MHSl ? MHSl->size() : RHSl->size();
1816 for (
unsigned i = 0; i !=
Size; ++i) {
1819 if (!isa<StringInit>(
Name) && !isa<UnsetInit>(
Name))
1821 Children.emplace_back(
Node, dyn_cast<StringInit>(
Name));
1829 const auto *LHSi = dyn_cast<IntInit>(LHS);
1830 const auto *MHSi = dyn_cast<IntInit>(MHS);
1831 const auto *RHSi = dyn_cast<IntInit>(RHS);
1832 if (!LHSi || !MHSi || !RHSi)
1835 auto Start = LHSi->getValue();
1836 auto End = MHSi->getValue();
1837 auto Step = RHSi->getValue();
1842 if (Start < End && Step > 0) {
1843 Args.reserve((
End - Start) / Step);
1844 for (
auto I = Start;
I <
End;
I += Step)
1846 }
else if (Start >
End && Step < 0) {
1847 Args.reserve((Start -
End) / -Step);
1848 for (
auto I = Start;
I >
End;
I += Step)
1857 const auto *LHSs = dyn_cast<StringInit>(LHS);
1858 const auto *MHSi = dyn_cast<IntInit>(MHS);
1859 const auto *RHSi = dyn_cast<IntInit>(RHS);
1860 if (LHSs && MHSi && RHSi) {
1861 int64_t StringSize = LHSs->getValue().size();
1862 int64_t Start = MHSi->getValue();
1863 int64_t
Length = RHSi->getValue();
1864 if (Start < 0 || Start > StringSize)
1866 Twine(
"!substr start position is out of range 0...") +
1867 std::to_string(StringSize) +
": " +
1868 std::to_string(Start));
1878 const auto *LHSs = dyn_cast<StringInit>(LHS);
1879 const auto *MHSs = dyn_cast<StringInit>(MHS);
1880 const auto *RHSi = dyn_cast<IntInit>(RHS);
1881 if (LHSs && MHSs && RHSi) {
1882 int64_t SourceSize = LHSs->getValue().size();
1883 int64_t Start = RHSi->getValue();
1884 if (Start < 0 || Start > SourceSize)
1886 Twine(
"!find start position is out of range 0...") +
1887 std::to_string(SourceSize) +
": " +
1888 std::to_string(Start));
1889 auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1890 if (
I == std::string::npos)
1898 const auto *Dag = dyn_cast<DagInit>(LHS);
1899 if (Dag && isa<IntInit, StringInit>(MHS)) {
1905 assert(*ArgNo < Dag->getNumArgs());
1910 return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
1916 const auto *Dag = dyn_cast<DagInit>(LHS);
1917 if (Dag && isa<IntInit, StringInit>(MHS)) {
1923 assert(*ArgNo < Dag->getNumArgs());
1927 Names[*ArgNo] = dyn_cast<StringInit>(RHS);
1928 return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
1941 if (
const auto *
Value = dyn_cast_or_null<IntInit>(
1944 if (
Value->getValue())
1961 if (LHS != lhs || MHS != mhs || RHS != rhs)
1963 ->Fold(R.getCurrentRecord());
1969 bool UnquotedLHS =
false;
1971 case DAG: Result =
"!dag";
break;
1972 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
1973 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
1974 case IF: Result =
"!if";
break;
1978 case SUBST: Result =
"!subst";
break;
1979 case SUBSTR: Result =
"!substr";
break;
1980 case FIND: Result =
"!find";
break;
1982 Result =
"!setdagarg";
1985 Result =
"!setdagname";
1988 return (Result +
"(" +
1996 ID.AddPointer(Start);
2000 ID.AddPointer(Expr);
2025 if (
const auto *LI = dyn_cast<ListInit>(List)) {
2026 const Init *Accum = Start;
2027 for (
const Init *Elt : *LI) {
2046 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
2050 ->
Fold(R.getCurrentRecord());
2067 ID.AddPointer(Expr);
2090 if (
const auto *TI = dyn_cast<TypedInit>(Expr)) {
2092 if (TI->getType()->typeIsConvertibleTo(CheckType))
2095 if (isa<RecordRecTy>(CheckType)) {
2129 ID.AddPointer(Expr);
2153 if (
const auto *
Name = dyn_cast<StringInit>(Expr)) {
2159 D->getDefInit()->getType()->typeIsA(CheckType));
2165 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
2167 (Anonymous &&
Name == Anonymous->getNameInit())) {
2186 if (Expr !=
NewExpr || R.isFinal())
2187 return get(CheckType,
NewExpr)->
Fold(R.getCurrentRecord(), R.isFinal());
2205 return Field->getType();
2215 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
2216 cast<BitsRecTy>(Ty)->getNumBits() == 1)
2224 const auto *
T = dyn_cast<BitsRecTy>(
getType());
2225 if (!
T)
return nullptr;
2226 unsigned NumBits =
T->getNumBits();
2230 for (
unsigned Bit : Bits) {
2245 assert(!isa<TypedInit>(Converted) ||
2246 cast<TypedInit>(Converted)->
getType()->typeIsA(Ty));
2250 if (!
getType()->typeIsConvertibleTo(Ty))
2270 const auto *NameString = cast<StringInit>(
getNameInit());
2271 return NameString->getValue();
2281 if (
const Init *Val = R.resolve(VarName))
2295 return TI->
getAsString() +
"{" + utostr(Bit) +
"}";
2306DefInit::DefInit(
const Record *
D)
2310 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
2311 if (
getType()->typeIsConvertibleTo(RRT))
2318 return RV->getType();
2326 ID.AddInteger(Args.size());
2327 ID.AddPointer(Class);
2329 for (
const Init *
I : Args)
2333VarDefInit::VarDefInit(
SMLoc Loc,
const Record *Class,
unsigned N)
2348 totalSizeToAlloc<const ArgumentInit *>(Args.size()),
alignof(
VarDefInit));
2350 std::uninitialized_copy(Args.begin(), Args.end(),
2360const DefInit *VarDefInit::instantiate() {
2365 auto NewRecOwner = std::make_unique<Record>(
2367 Record *NewRec = NewRecOwner.get();
2383 for (
const Init *Arg : TArgs) {
2388 for (
auto *Arg :
args()) {
2389 if (Arg->isPositional())
2390 R.set(TArgs[Arg->getIndex()], Arg->getValue());
2392 R.set(Arg->getName(), Arg->getValue());
2406 Records.addDef(std::move(NewRecOwner));
2419 bool Changed =
false;
2424 const auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
2426 Changed |= NewArg != Arg;
2432 return const_cast<VarDefInit *
>(New)->instantiate();
2444 Arg->resolveReferences(R);
2446 if (!R.foundUnresolved())
2447 return const_cast<VarDefInit *
>(
this)->instantiate();
2453 const char *sep =
"";
2457 Result += Arg->getAsString();
2459 return Result +
">";
2484 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2485 const Record *Def = DI->getDef();
2488 Twine(
"Attempting to access field '") +
2490 Rec->
getAsString() +
"' is a forbidden self-reference");
2491 const Init *FieldVal = Def->getValue(FieldName)->getValue();
2499 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2500 const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2509 const RecTy *ValType) {
2511 "Number of conditions and values must match!");
2512 ID.AddPointer(ValType);
2516 while (Case != CondRange.
end()) {
2517 ID.AddPointer(*Case++);
2518 ID.AddPointer(*Val++);
2524 ID,
ArrayRef(getTrailingObjects<const Init *>(), NumConds),
2525 ArrayRef(getTrailingObjects<const Init *>() + NumConds, NumConds),
2533 "Number of conditions and values must match!");
2544 totalSizeToAlloc<const Init *>(2 * CondRange.
size()),
alignof(
BitsInit));
2547 std::uninitialized_copy(CondRange.
begin(), CondRange.
end(),
2548 I->getTrailingObjects<
const Init *>());
2549 std::uninitialized_copy(ValRange.
begin(), ValRange.
end(),
2550 I->getTrailingObjects<
const Init *>() +
2558 bool Changed =
false;
2562 Changed |= NewCase != Case;
2569 Changed |= NewVal != Val;
2581 for (
unsigned i = 0; i < NumConds; ++i) {
2585 if (
const auto *CondI = dyn_cast_or_null<IntInit>(
2587 if (CondI->getValue())
2596 " does not have any true condition in:" +
2597 this->getAsString());
2603 if (!Case->isConcrete())
2607 if (!Val->isConcrete())
2615 if (!Case->isComplete())
2619 if (!Val->isConcrete())
2626 std::string Result =
"!cond(";
2633 return Result +
")";
2649 while (Arg != ArgRange.
end()) {
2651 ID.AddPointer(*Arg++);
2671 ArgRange.
size(), NameRange.
size()),
2674 std::uninitialized_copy(ArgRange.
begin(), ArgRange.
end(),
2675 I->getTrailingObjects<
const Init *>());
2676 std::uninitialized_copy(NameRange.
begin(), NameRange.
end(),
2684 ArrayRef<std::pair<const Init *, const StringInit *>>
args) {
2688 for (
const auto &Arg :
args) {
2689 Args.push_back(Arg.first);
2698 ID, Val, ValName,
ArrayRef(getTrailingObjects<const Init *>(), NumArgs),
2699 ArrayRef(getTrailingObjects<const StringInit *>(), NumArgNames));
2703 if (
const auto *DefI = dyn_cast<DefInit>(Val))
2704 return DefI->getDef();
2710 for (
unsigned i = 0, e =
getNumArgs(); i < e; ++i) {
2715 return std::nullopt;
2721 bool ArgsChanged =
false;
2725 ArgsChanged |= NewArg != Arg;
2729 if (
Op != Val || ArgsChanged)
2739 if (!Elt->isConcrete())
2752 for (
unsigned i = 1, e =
getNumArgs(); i != e; ++i) {
2757 return Result +
")";
2765 :
Name(
N), TyAndKind(
T, K) {
2767 assert(
Value &&
"Cannot create unset value for current type!");
2773 :
Name(
N), Loc(Loc), TyAndKind(
T, K) {
2775 assert(
Value &&
"Cannot create unset value for current type!");
2779 return cast<StringInit>(
getNameInit())->getValue();
2784 if (
const auto *StrInit = dyn_cast<StringInit>(
Value)) {
2785 if (StrInit->hasCodeFormat())
2793 return TyAndKind.getPointer()->getAsString();
2803 if (
const auto *BTy = dyn_cast<BitsRecTy>(
getType())) {
2804 if (!isa<BitsInit>(
Value)) {
2806 Bits.reserve(BTy->getNumBits());
2807 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2808 Bits.push_back(
Value->getBit(
I));
2813 return Value ==
nullptr;
2828 if (
const auto *BTy = dyn_cast<BitsRecTy>(
getType())) {
2829 if (!isa<BitsInit>(
Value)) {
2831 Bits.reserve(BTy->getNumBits());
2832 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2833 Bits.push_back(
Value->getBit(
I));
2838 return Value ==
nullptr;
2844#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2856 if (PrintSem)
OS <<
";\n";
2860 assert(Locs.size() == 1);
2861 ForwardDeclarationLocs.push_back(Locs.front());
2864 Locs.push_back(Loc);
2867void Record::checkName() {
2869 const auto *TypedName = cast<const TypedInit>(Name);
2870 if (!isa<StringRecTy>(TypedName->getType()))
2872 "' is not a string!");
2882 if (!CorrespondingDefInit) {
2883 CorrespondingDefInit =
2886 return CorrespondingDefInit;
2917 for (
int I = SCs.
size() - 1;
I >= 0; --
I) {
2918 const Record *SC = SCs[
I].first;
2919 if (SC == Superclass)
2921 I -= SC->getSuperClasses().size();
2931 while (!SCs.
empty()) {
2933 SCs = SCs.
drop_back(1 + SC->getSuperClasses().size());
2941 if (NewName != OldName) {
2948 if (SkipVal == &
Value)
2951 const Init *VR = V->resolveReferences(R);
2952 if (
Value.setValue(VR)) {
2954 if (
const auto *VRT = dyn_cast<TypedInit>(VR))
2956 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
2959 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
2960 Value.getNameInitAsString() +
"' of type '" +
2969 for (
auto &Assertion : Assertions) {
2970 const Init *
Value = Assertion.Condition->resolveReferences(R);
2971 Assertion.Condition =
Value;
2972 Value = Assertion.Message->resolveReferences(R);
2973 Assertion.Message =
Value;
2976 for (
auto &Dump : Dumps) {
2977 const Init *
Value = Dump.Message->resolveReferences(R);
2978 Dump.Message =
Value;
2989#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2994 OS << R.getNameInitAsString();
2997 if (!TArgs.
empty()) {
2999 bool NeedComma =
false;
3000 for (
const Init *TA : TArgs) {
3001 if (NeedComma)
OS <<
", ";
3004 assert(RV &&
"Template argument record not found??");
3014 for (
const auto &[SC,
_] : SC)
3015 OS <<
" " << SC->getNameInitAsString();
3019 for (
const RecordVal &Val : R.getValues())
3020 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3022 for (
const RecordVal &Val : R.getValues())
3023 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3033 "' does not have a field named `" + FieldName +
"'!\n");
3039 if (!R || !R->getValue())
3041 "' does not have a field named `" + FieldName +
"'!\n");
3042 return R->getValue();
3049 "' does not have a field named `" + FieldName +
"'!\n");
3053std::optional<StringRef>
3056 if (!R || !R->getValue())
3057 return std::nullopt;
3058 if (isa<UnsetInit>(R->getValue()))
3059 return std::nullopt;
3061 if (
const auto *SI = dyn_cast<StringInit>(R->getValue()))
3062 return SI->getValue();
3065 "Record `" +
getName() +
"', ` field `" + FieldName +
3066 "' exists but does not have a string initializer!");
3071 if (!R || !R->getValue())
3073 "' does not have a field named `" + FieldName +
"'!\n");
3075 if (
const auto *BI = dyn_cast<BitsInit>(R->getValue()))
3078 "' exists but does not have a bits value");
3083 if (!R || !R->getValue())
3085 "' does not have a field named `" + FieldName +
"'!\n");
3087 if (
const auto *LI = dyn_cast<ListInit>(R->getValue()))
3090 "' exists but does not have a list value");
3093std::vector<const Record *>
3096 std::vector<const Record *> Defs;
3097 for (
const Init *
I :
List->getValues()) {
3098 if (
const auto *DI = dyn_cast<DefInit>(
I))
3099 Defs.push_back(DI->getDef());
3103 "' list is not entirely DefInit!");
3110 if (!R || !R->getValue())
3112 "' does not have a field named `" + FieldName +
"'!\n");
3114 if (
const auto *
II = dyn_cast<IntInit>(R->getValue()))
3115 return II->getValue();
3118 "' exists but does not have an int value: " +
3119 R->getValue()->getAsString());
3125 std::vector<int64_t> Ints;
3126 for (
const Init *
I :
List->getValues()) {
3127 if (
const auto *
II = dyn_cast<IntInit>(
I))
3128 Ints.push_back(
II->getValue());
3131 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3132 "' exists but does not have a list of ints value: " +
3138std::vector<StringRef>
3141 std::vector<StringRef> Strings;
3142 for (
const Init *
I :
List->getValues()) {
3143 if (
const auto *SI = dyn_cast<StringInit>(
I))
3144 Strings.push_back(SI->getValue());
3147 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3148 "' exists but does not have a list of strings value: " +
3156 if (!R || !R->getValue())
3158 "' does not have a field named `" + FieldName +
"'!\n");
3160 if (
const auto *DI = dyn_cast<DefInit>(R->getValue()))
3161 return DI->getDef();
3163 FieldName +
"' does not have a def initializer!");
3168 if (!R || !R->getValue())
3170 "' does not have a field named `" + FieldName +
"'!\n");
3172 if (
const auto *DI = dyn_cast<DefInit>(R->getValue()))
3173 return DI->getDef();
3174 if (isa<UnsetInit>(R->getValue()))
3177 FieldName +
"' does not have either a def initializer or '?'!");
3182 if (!R || !R->getValue())
3184 "' does not have a field named `" + FieldName +
"'!\n");
3186 if (
const auto *BI = dyn_cast<BitInit>(R->getValue()))
3187 return BI->getValue();
3189 FieldName +
"' does not have a bit initializer!");
3194 if (!R || !R->getValue())
3196 "' does not have a field named `" + FieldName.
str() +
"'!\n");
3198 if (isa<UnsetInit>(R->getValue())) {
3203 if (
const auto *BI = dyn_cast<BitInit>(R->getValue()))
3204 return BI->getValue();
3206 FieldName +
"' does not have a bit initializer!");
3211 if (!R || !R->getValue())
3213 "' does not have a field named `" + FieldName +
"'!\n");
3215 if (
const auto *DI = dyn_cast<DagInit>(R->getValue()))
3218 FieldName +
"' does not have a dag initializer!");
3229 bool AnyFailed =
false;
3233 AnyFailed |=
CheckAssert(Assertion.Loc, Condition, Message);
3241 PrintError(
this,
"assertion failed in this record");
3248 for (
const auto &Dump :
getDumps()) {
3249 const Init *Message = Dump.Message->resolveReferences(R);
3265 : Impl(
std::make_unique<
detail::RecordKeeperImpl>(*this)),
3270#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3275 OS <<
"------------- Classes -----------------\n";
3277 OS <<
"class " << *
C.second;
3279 OS <<
"------------- Defs -----------------\n";
3281 OS <<
"def " << *
D.second;
3295 auto [Iter, Inserted] = Cache.try_emplace(ClassName.
str());
3298 return Iter->second;
3301std::vector<const Record *>
3304 std::vector<const Record *> Defs;
3306 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
3307 for (
const auto &ClassName : ClassNames) {
3314 for (
const auto &OneDef :
getDefs()) {
3316 return OneDef.second->isSubClassOf(Class);
3318 Defs.push_back(OneDef.second.get());
3332 Impl->dumpAllocationStats(
OS);
3336 auto It = Map.find(VarName);
3337 if (It == Map.end())
3340 const Init *
I = It->second.V;
3342 if (!It->second.Resolved && Map.size() > 1) {
3346 I =
I->resolveReferences(*
this);
3347 Map[VarName] = {
I,
true};
3354 const Init *Val = Cache.lookup(VarName);
3362 if (!isa<UnsetInit>(RV->getValue())) {
3363 Val = RV->getValue();
3364 Stack.push_back(VarName);
3369 Stack.push_back(VarName);
3374 Cache[VarName] = Val;
3379 const Init *
I =
nullptr;
3383 if (
I && !FoundUnresolved) {
3388 I->resolveReferences(Sub);
3389 FoundUnresolved |= Sub.FoundUnresolved;
3394 FoundUnresolved =
true;
3399 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 override
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...
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)