22#include "llvm/Config/llvm-config.h"
43#define DEBUG_TYPE "tblgen-records"
108 OS <<
"TheArgumentInitPool size = " << TheArgumentInitPool.size() <<
'\n';
109 OS <<
"TheBitsInitPool size = " << TheBitsInitPool.size() <<
'\n';
110 OS <<
"TheIntInitPool size = " << TheIntInitPool.size() <<
'\n';
111 OS <<
"StringInitStringPool size = " << StringInitStringPool.size() <<
'\n';
112 OS <<
"StringInitCodePool size = " << StringInitCodePool.size() <<
'\n';
113 OS <<
"TheListInitPool size = " << TheListInitPool.size() <<
'\n';
114 OS <<
"TheUnOpInitPool size = " << TheUnOpInitPool.size() <<
'\n';
115 OS <<
"TheBinOpInitPool size = " << TheBinOpInitPool.size() <<
'\n';
116 OS <<
"TheTernOpInitPool size = " << TheTernOpInitPool.size() <<
'\n';
117 OS <<
"TheFoldOpInitPool size = " << TheFoldOpInitPool.size() <<
'\n';
118 OS <<
"TheIsAOpInitPool size = " << TheIsAOpInitPool.size() <<
'\n';
119 OS <<
"TheExistsOpInitPool size = " << TheExistsOpInitPool.size() <<
'\n';
120 OS <<
"TheCondOpInitPool size = " << TheCondOpInitPool.size() <<
'\n';
121 OS <<
"TheDagInitPool size = " << TheDagInitPool.size() <<
'\n';
122 OS <<
"RecordTypePool size = " << RecordTypePool.size() <<
'\n';
123 OS <<
"TheVarInitPool size = " << TheVarInitPool.size() <<
'\n';
124 OS <<
"TheVarBitInitPool size = " << TheVarBitInitPool.size() <<
'\n';
125 OS <<
"TheVarDefInitPool size = " << TheVarDefInitPool.size() <<
'\n';
126 OS <<
"TheFieldInitPool size = " << TheFieldInitPool.size() <<
'\n';
127 OS <<
"Bytes allocated = " <<
Allocator.getBytesAllocated() <<
'\n';
128 OS <<
"Total allocator memory = " <<
Allocator.getTotalMemory() <<
"\n\n";
130 OS <<
"Number of records instantiated = " << LastRecordID <<
'\n';
131 OS <<
"Number of anonymous records = " << AnonCounter <<
'\n';
138#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
150 return Kind ==
RHS->getRecTyKind();
162 if (
const auto *BitsTy = dyn_cast<BitsRecTy>(
RHS))
163 return BitsTy->getNumBits() == 1;
178 return "bits<" + utostr(Size) +
">";
183 return cast<BitsRecTy>(
RHS)->Size == Size;
215 if (
const auto *ListTy = dyn_cast<ListRecTy>(
RHS))
221 if (
const auto *RHSl = dyn_cast<ListRecTy>(
RHS))
236 ID.AddInteger(Classes.
size());
237 for (
const Record *R : Classes)
242 :
RecTy(RecordRecTyKind, RK), NumClasses(Classes.
size()) {
249 if (UnsortedClasses.
empty())
256 return LHS->getNameInitAsString() <
RHS->getNameInitAsString();
268 for (
unsigned i = 0; i < Classes.
size(); ++i) {
269 for (
unsigned j = 0; j < Classes.
size(); ++j) {
272 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
277 totalSizeToAlloc<const Record *>(Classes.
size()),
alignof(
RecordRecTy));
284 assert(Class &&
"unexpected null class");
285 return get(Class->getRecords(), {Class});
294 return getClasses()[0]->getNameInitAsString();
296 std::string Str =
"{";
300 Str += R->getNameInitAsString();
308 return MySuperClass == Class || MySuperClass->
isSubClassOf(Class);
316 const auto *RTy = dyn_cast<RecordRecTy>(
RHS);
321 return isSubClassOf(TargetClass);
334 while (!Stack.empty()) {
335 const Record *R = Stack.pop_back_val();
350 if (
const auto *RecTy1 = dyn_cast<RecordRecTy>(
T1)) {
351 if (
const auto *RecTy2 = dyn_cast<RecordRecTy>(T2))
355 assert(
T1 !=
nullptr &&
"Invalid record type");
356 if (
T1->typeIsConvertibleTo(T2))
359 assert(T2 !=
nullptr &&
"Invalid record type");
363 if (
const auto *ListTy1 = dyn_cast<ListRecTy>(
T1)) {
364 if (
const auto *ListTy2 = dyn_cast<ListRecTy>(T2)) {
365 const RecTy *NewType =
366 resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());
379void Init::anchor() {}
381#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
386 if (
auto *TyInit = dyn_cast<TypedInit>(
this))
387 return TyInit->getType()->getRecordKeeper();
388 if (
auto *ArgInit = dyn_cast<ArgumentInit>(
this))
389 return ArgInit->getRecordKeeper();
390 return cast<UnsetInit>(
this)->getRecordKeeper();
405 auto I = Aux.index();
408 ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
410 ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
435 const Init *NewValue =
Value->resolveReferences(R);
436 if (NewValue !=
Value)
447 if (isa<BitRecTy>(Ty))
450 if (isa<IntRecTy>(Ty))
453 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
455 if (BRT->getNumBits() == 1)
486 totalSizeToAlloc<const Init *>(Bits.size()),
alignof(
BitsInit));
497 if (isa<BitRecTy>(Ty)) {
502 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
505 if (
getNumBits() != BRT->getNumBits())
return nullptr;
509 if (isa<IntRecTy>(Ty)) {
521 if (
auto *Bit = dyn_cast<BitInit>(InitV))
522 Result |=
static_cast<int64_t
>(Bit->getValue()) <<
Idx;
532 for (
auto [Bit, NewBit] :
zip_equal(Bits, NewBits)) {
551 std::string Result =
"{ ";
556 Result += Bit->getAsString();
560 return Result +
" }";
566 bool Changed =
false;
569 const Init *CachedBitVarRef =
nullptr;
570 const Init *CachedBitVarResolved =
nullptr;
575 if (
const auto *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
576 if (CurBitVar->getBitVar() != CachedBitVarRef) {
577 CachedBitVarRef = CurBitVar->getBitVar();
580 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
581 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
587 if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
589 Changed |= CurBit != NewBit;
606 return itostr(
Value);
611 return (NumBits >=
sizeof(
Value) * 8) ||
612 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
616 if (isa<IntRecTy>(Ty))
619 if (isa<BitRecTy>(Ty)) {
621 if (Val != 0 && Val != 1)
return nullptr;
625 if (
const auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
632 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
645 for (
auto [Bit, NewBit] :
zip_equal(Bits, NewBits)) {
663 return "anonymous_" + utostr(
Value);
668 auto *New = R.resolve(Old);
669 New = New ? New : Old;
671 if (
const auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
672 return Anonymous->getNameInit();
681 auto &Entry = *InitMap.try_emplace(V,
nullptr).first;
688 if (isa<StringRecTy>(Ty))
696 const RecTy *EltTy) {
697 ID.AddInteger(Elements.size());
698 ID.AddPointer(EltTy);
700 for (
const Init *E : Elements)
711 const RecTy *EltTy) {
720 assert(Elements.empty() || !isa<TypedInit>(Elements[0]) ||
721 cast<TypedInit>(Elements[0])->getType()->typeIsConvertibleTo(EltTy));
724 totalSizeToAlloc<const Init *>(Elements.size()),
alignof(
ListInit));
731 const RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
739 if (
const auto *LRT = dyn_cast<ListRecTy>(Ty)) {
741 Elements.reserve(
size());
745 bool Changed =
false;
746 const RecTy *ElementType = LRT->getElementType();
748 if (
const Init *CI =
I->convertInitializerTo(ElementType)) {
749 Elements.push_back(CI);
773 Resolved.reserve(
size());
774 bool Changed =
false;
778 Changed |= E != CurElt;
779 Resolved.push_back(E);
798 std::string Result =
"[";
800 for (
const Init *Element : *
this) {
815 ID.AddInteger(Opcode);
844 if (
const auto *Def = dyn_cast<DefInit>(LHS)) {
847 OS << *Def->getDef();
860 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
864 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
868 if (isa<StringRecTy>(
getType())) {
869 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
872 if (
const auto *LHSd = dyn_cast<DefInit>(LHS))
875 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
879 }
else if (isa<RecordRecTy>(
getType())) {
880 if (
const auto *
Name = dyn_cast<StringInit>(LHS)) {
885 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
887 (Anonymous &&
Name == Anonymous->getNameInit())) {
894 auto PrintFatalErrorHelper = [CurRec](
const Twine &
T) {
903 PrintFatalErrorHelper(
Twine(
"Undefined reference to record: '") +
904 Name->getValue() +
"'\n");
911 PrintFatalErrorHelper(
Twine(
"Expected type '") +
925 if (isa<UnsetInit>(LHS))
932 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
938 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
939 assert(!LHSl->empty() &&
"Empty list in head");
940 return LHSl->getElement(0);
945 if (
const auto *LHSl = dyn_cast<ListInit>(LHS)) {
946 assert(!LHSl->empty() &&
"Empty list in tail");
950 LHSl->getElementType());
955 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
957 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
959 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
964 if (
const auto *LHSl = dyn_cast<ListInit>(LHS))
966 if (
const auto *LHSd = dyn_cast<DagInit>(LHS))
968 if (
const auto *LHSs = dyn_cast<StringInit>(LHS))
973 if (
const auto *Dag = dyn_cast<DagInit>(LHS)) {
976 auto *TI = cast<TypedInit>(Dag->getOperator());
977 if (!TI->getType()->typeIsA(
getType())) {
980 "', got '" + TI->getType()->getAsString() +
983 return Dag->getOperator();
989 if (
const auto *Dag = dyn_cast<DagInit>(LHS)) {
990 return Dag->getName();
995 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
997 int64_t LHSv = LHSi->getValue();
1000 "Illegal operation: logtwo is undefined "
1001 "on arguments less than or equal to 0");
1005 "Log of an int64_t must be smaller than INT64_MAX");
1012 if (
const auto *LHSList = dyn_cast<ListInit>(LHS)) {
1013 const auto *InnerListTy = dyn_cast<ListRecTy>(LHSList->getElementType());
1019 [](
const ListInit *
List) -> std::optional<std::vector<const Init *>> {
1020 std::vector<const Init *> Flattened;
1022 for (
const Init *InnerInit :
List->getElements()) {
1023 const auto *InnerList = dyn_cast<ListInit>(InnerInit);
1025 return std::nullopt;
1031 auto Flattened = Flatten(LHSList);
1033 return ListInit::get(*Flattened, InnerListTy->getElementType());
1045 ->Fold(R.getCurrentRecord(), R.isFinal());
1053 case NOT: Result =
"!not";
break;
1054 case HEAD: Result =
"!head";
break;
1055 case TAIL: Result =
"!tail";
break;
1056 case SIZE: Result =
"!size";
break;
1057 case EMPTY: Result =
"!empty";
break;
1058 case GETDAGOP: Result =
"!getdagop";
break;
1060 Result =
"!getdagopname";
1062 case LOG2 : Result =
"!logtwo";
break;
1064 Result =
"!listflatten";
1070 Result =
"!tolower";
1073 Result =
"!toupper";
1076 Result =
"!initialized";
1085 ID.AddInteger(Opcode);
1113 Concat.append(I1->getValue());
1121 if (
List->size() == 0)
1123 const auto *Element = dyn_cast<StringInit>(
List->getElement(0));
1129 for (
const Init *Elem :
List->getElements().drop_front()) {
1131 const auto *Element = dyn_cast<StringInit>(Elem);
1134 Result.append(Element->getValue());
1143 if (
List->size() == 0)
1145 const auto *Element = dyn_cast_or_null<IntInit>(
1151 for (
const Init *Elem :
List->getElements().drop_front()) {
1153 const auto *Element = dyn_cast_or_null<IntInit>(
1157 Result.append(Element->getAsString());
1164 if (
const auto *I0s = dyn_cast<StringInit>(I0))
1165 if (
const auto *I1s = dyn_cast<StringInit>(I1))
1183 if (
const auto *LHSList = dyn_cast<ListInit>(
LHS))
1184 if (
const auto *RHSList = dyn_cast<ListInit>(
RHS))
1190 const Init *RHS)
const {
1192 const auto *LHSi = dyn_cast_or_null<IntInit>(
1194 const auto *RHSi = dyn_cast_or_null<IntInit>(
1201 Result = LHSi->getValue() == RHSi->getValue();
1204 Result = LHSi->getValue() != RHSi->getValue();
1207 Result = LHSi->getValue() <= RHSi->getValue();
1210 Result = LHSi->getValue() < RHSi->getValue();
1213 Result = LHSi->getValue() >= RHSi->getValue();
1216 Result = LHSi->getValue() > RHSi->getValue();
1225 const auto *LHSs = dyn_cast<StringInit>(
LHS);
1226 const auto *RHSs = dyn_cast<StringInit>(
RHS);
1232 Result = LHSs->getValue() == RHSs->getValue();
1235 Result = LHSs->getValue() != RHSs->getValue();
1238 Result = LHSs->getValue() <= RHSs->getValue();
1241 Result = LHSs->getValue() < RHSs->getValue();
1244 Result = LHSs->getValue() >= RHSs->getValue();
1247 Result = LHSs->getValue() > RHSs->getValue();
1257 const auto *LHSd = dyn_cast<DefInit>(
LHS);
1258 const auto *RHSd = dyn_cast<DefInit>(
RHS);
1260 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1263 return std::nullopt;
1266static std::optional<unsigned>
1269 if (
const auto *
Idx = dyn_cast<IntInit>(Key)) {
1270 int64_t Pos =
Idx->getValue();
1274 (
Twine(
"index ") + std::to_string(Pos) +
Twine(
" is negative")).str();
1275 return std::nullopt;
1277 if (Pos >= Dag->getNumArgs()) {
1279 Error = (
Twine(
"index ") + std::to_string(Pos) +
1280 " is out of range (dag has " +
1281 std::to_string(Dag->getNumArgs()) +
" arguments)")
1283 return std::nullopt;
1287 assert(isa<StringInit>(Key));
1289 const auto *
Name = dyn_cast<StringInit>(Key);
1290 auto ArgNo = Dag->getArgNo(
Name->getValue());
1294 return std::nullopt;
1302 const auto *LHSs = dyn_cast<DagInit>(LHS);
1303 const auto *RHSs = dyn_cast<DagInit>(RHS);
1305 const auto *LOp = dyn_cast<DefInit>(LHSs->getOperator());
1306 const auto *ROp = dyn_cast<DefInit>(RHSs->getOperator());
1307 if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
1308 (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
1310 if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1312 LHSs->getAsString() +
"' vs. '" + RHSs->getAsString() +
1315 const Init *
Op = LOp ? LOp : ROp;
1323 const auto *NameInit = LHSs->getName();
1325 NameInit = RHSs->getName();
1331 const auto *StrInit = dyn_cast<StringInit>(LHS);
1335 const auto *RegexInit = dyn_cast<StringInit>(RHS);
1339 StringRef RegexStr = RegexInit->getValue();
1345 Matcher.
match(StrInit->getValue()));
1348 const auto *LHSs = dyn_cast<ListInit>(LHS);
1349 const auto *RHSs = dyn_cast<ListInit>(RHS);
1359 const auto *
Value = dyn_cast<TypedInit>(LHS);
1360 const auto *
Size = dyn_cast<IntInit>(RHS);
1368 const auto *LHSs = dyn_cast<ListInit>(LHS);
1369 const auto *RHSs = dyn_cast<ListInit>(RHS);
1372 for (
const Init *EltLHS : *LHSs) {
1374 for (
const Init *EltRHS : *RHSs) {
1375 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1383 Args.push_back(EltLHS);
1390 const auto *TheList = dyn_cast<ListInit>(LHS);
1391 const auto *
Idx = dyn_cast<IntInit>(RHS);
1392 if (!TheList || !
Idx)
1394 auto i =
Idx->getValue();
1395 if (i < 0 || i >= (ssize_t)TheList->size())
1397 return TheList->getElement(i);
1400 const auto *TheList = dyn_cast<ListInit>(LHS);
1401 const auto *SliceIdxs = dyn_cast<ListInit>(RHS);
1402 if (!TheList || !SliceIdxs)
1405 Args.reserve(SliceIdxs->size());
1406 for (
auto *
I : *SliceIdxs) {
1407 auto *
II = dyn_cast<IntInit>(
I);
1410 auto i =
II->getValue();
1411 if (i < 0 || i >= (ssize_t)TheList->size())
1413 Args.push_back(TheList->getElement(i));
1418 const auto *LHSi = dyn_cast<IntInit>(LHS);
1419 const auto *RHSi = dyn_cast<IntInit>(RHS);
1423 int64_t Start = LHSi->getValue();
1424 int64_t
End = RHSi->getValue();
1430 Args.reserve(
End - Start + 1);
1431 for (
auto i = Start; i <=
End; ++i)
1435 Args.reserve(Start -
End + 1);
1436 for (
auto i = Start; i >=
End; --i)
1439 }
else if (Start <
End) {
1441 Args.reserve(
End - Start);
1442 for (
auto i = Start; i <
End; ++i)
1450 const auto *LHSs = dyn_cast<StringInit>(LHS);
1451 const auto *RHSs = dyn_cast<StringInit>(RHS);
1457 const auto *
List = dyn_cast<ListInit>(LHS);
1458 const auto *Delim = dyn_cast<StringInit>(RHS);
1459 if (
List && Delim) {
1461 if (isa<StringRecTy>(
List->getElementType()))
1481 const auto *Dag = dyn_cast<DagInit>(LHS);
1482 if (Dag && isa<IntInit, StringInit>(RHS)) {
1488 assert(*ArgNo < Dag->getNumArgs());
1490 const Init *Arg = Dag->getArg(*ArgNo);
1491 if (
const auto *TI = dyn_cast<TypedInit>(Arg))
1492 if (!TI->getType()->typeIsConvertibleTo(
getType()))
1499 const auto *Dag = dyn_cast<DagInit>(LHS);
1500 const auto *
Idx = dyn_cast<IntInit>(RHS);
1502 int64_t Pos =
Idx->getValue();
1503 if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1506 Twine(
"!getdagname index is out of range 0...") +
1507 std::to_string(Dag->getNumArgs() - 1) +
": " +
1508 std::to_string(Pos));
1510 const Init *ArgName = Dag->getArgName(Pos);
1518 const auto *Dag = dyn_cast<DagInit>(LHS);
1519 const auto *
Op = dyn_cast<DefInit>(RHS);
1525 const auto *Dag = dyn_cast<DagInit>(LHS);
1526 const auto *
Op = dyn_cast<StringInit>(RHS);
1529 Dag->getArgNames());
1542 const auto *LHSi = dyn_cast_or_null<IntInit>(
1544 const auto *RHSi = dyn_cast_or_null<IntInit>(
1547 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
1551 case ADD: Result = LHSv + RHSv;
break;
1552 case SUB: Result = LHSv - RHSv;
break;
1553 case MUL: Result = LHSv * RHSv;
break;
1557 "Illegal operation: division by zero");
1558 else if (LHSv ==
INT64_MIN && RHSv == -1)
1560 "Illegal operation: INT64_MIN / -1");
1562 Result = LHSv / RHSv;
1564 case AND: Result = LHSv & RHSv;
break;
1565 case OR: Result = LHSv | RHSv;
break;
1566 case XOR: Result = LHSv ^ RHSv;
break;
1568 if (RHSv < 0 || RHSv >= 64)
1570 "Illegal operation: out of bounds shift");
1574 if (RHSv < 0 || RHSv >= 64)
1576 "Illegal operation: out of bounds shift");
1580 if (RHSv < 0 || RHSv >= 64)
1582 "Illegal operation: out of bounds shift");
1607 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1609 if ((
Opc ==
AND && !LHSi->getValue()) ||
1610 (
Opc ==
OR && LHSi->getValue() == -1))
1617 if (LHS != NewLHS || RHS != NewRHS)
1619 ->Fold(R.getCurrentRecord());
1631 case CONCAT: Result =
"!con";
break;
1635 case ADD: Result =
"!add";
break;
1636 case SUB: Result =
"!sub";
break;
1637 case MUL: Result =
"!mul";
break;
1638 case DIV: Result =
"!div";
break;
1639 case AND: Result =
"!and";
break;
1640 case OR: Result =
"!or";
break;
1641 case XOR: Result =
"!xor";
break;
1642 case SHL: Result =
"!shl";
break;
1643 case SRA: Result =
"!sra";
break;
1644 case SRL: Result =
"!srl";
break;
1645 case EQ: Result =
"!eq";
break;
1646 case NE: Result =
"!ne";
break;
1647 case LE: Result =
"!le";
break;
1648 case LT: Result =
"!lt";
break;
1649 case GE: Result =
"!ge";
break;
1650 case GT: Result =
"!gt";
break;
1651 case LISTCONCAT: Result =
"!listconcat";
break;
1652 case LISTSPLAT: Result =
"!listsplat";
break;
1654 Result =
"!listremove";
1656 case STRCONCAT: Result =
"!strconcat";
break;
1657 case INTERLEAVE: Result =
"!interleave";
break;
1658 case SETDAGOP: Result =
"!setdagop";
break;
1660 Result =
"!setdagopname";
1666 Result =
"!getdagname";
1675 ID.AddInteger(Opcode);
1706 return RHS->resolveReferences(R);
1711 bool Change =
false;
1720 if (
const auto *Argd = dyn_cast<DagInit>(Arg))
1739 if (
const auto *MHSd = dyn_cast<DagInit>(MHS))
1742 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1745 for (
const Init *&Item : NewList) {
1747 if (NewItem != Item)
1761 if (
const auto *MHSl = dyn_cast<ListInit>(MHS)) {
1764 for (
const Init *Item : MHSl->getElements()) {
1768 if (
const auto *IncludeInt =
1769 dyn_cast_or_null<IntInit>(
Include->convertInitializerTo(
1771 if (IncludeInt->getValue())
1787 const auto *LHSd = dyn_cast<DefInit>(LHS);
1788 const auto *LHSv = dyn_cast<VarInit>(LHS);
1789 const auto *LHSs = dyn_cast<StringInit>(LHS);
1791 const auto *MHSd = dyn_cast<DefInit>(MHS);
1792 const auto *MHSv = dyn_cast<VarInit>(MHS);
1793 const auto *MHSs = dyn_cast<StringInit>(MHS);
1795 const auto *RHSd = dyn_cast<DefInit>(RHS);
1796 const auto *RHSv = dyn_cast<VarInit>(RHS);
1797 const auto *RHSs = dyn_cast<StringInit>(RHS);
1799 if (LHSd && MHSd && RHSd) {
1800 const Record *Val = RHSd->getDef();
1801 if (LHSd->getAsString() == RHSd->getAsString())
1802 Val = MHSd->getDef();
1805 if (LHSv && MHSv && RHSv) {
1806 std::string Val = RHSv->getName().str();
1807 if (LHSv->getAsString() == RHSv->getAsString())
1808 Val = MHSv->getName().str();
1811 if (LHSs && MHSs && RHSs) {
1812 std::string Val = RHSs->getValue().str();
1814 std::string::size_type
Idx = 0;
1816 std::string::size_type Found = Val.find(LHSs->getValue(),
Idx);
1817 if (Found == std::string::npos)
1819 Val.replace(Found, LHSs->getValue().size(), MHSs->getValue().str());
1820 Idx = Found + MHSs->getValue().size();
1841 if (
const auto *LHSi = dyn_cast_or_null<IntInit>(
1843 if (LHSi->getValue())
1851 const auto *MHSl = dyn_cast<ListInit>(MHS);
1852 const auto *RHSl = dyn_cast<ListInit>(RHS);
1853 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1854 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1856 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1859 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
1861 unsigned Size = MHSl ? MHSl->size() : RHSl->size();
1862 for (
unsigned i = 0; i !=
Size; ++i) {
1865 if (!isa<StringInit>(
Name) && !isa<UnsetInit>(
Name))
1867 Children.emplace_back(
Node, dyn_cast<StringInit>(
Name));
1875 const auto *LHSi = dyn_cast<IntInit>(LHS);
1876 const auto *MHSi = dyn_cast<IntInit>(MHS);
1877 const auto *RHSi = dyn_cast<IntInit>(RHS);
1878 if (!LHSi || !MHSi || !RHSi)
1881 auto Start = LHSi->getValue();
1882 auto End = MHSi->getValue();
1883 auto Step = RHSi->getValue();
1888 if (Start < End && Step > 0) {
1889 Args.reserve((
End - Start) / Step);
1890 for (
auto I = Start;
I <
End;
I += Step)
1892 }
else if (Start >
End && Step < 0) {
1893 Args.reserve((Start -
End) / -Step);
1894 for (
auto I = Start;
I >
End;
I += Step)
1903 const auto *LHSs = dyn_cast<StringInit>(LHS);
1904 const auto *MHSi = dyn_cast<IntInit>(MHS);
1905 const auto *RHSi = dyn_cast<IntInit>(RHS);
1906 if (LHSs && MHSi && RHSi) {
1907 int64_t StringSize = LHSs->getValue().size();
1908 int64_t Start = MHSi->getValue();
1909 int64_t
Length = RHSi->getValue();
1910 if (Start < 0 || Start > StringSize)
1912 Twine(
"!substr start position is out of range 0...") +
1913 std::to_string(StringSize) +
": " +
1914 std::to_string(Start));
1924 const auto *LHSs = dyn_cast<StringInit>(LHS);
1925 const auto *MHSs = dyn_cast<StringInit>(MHS);
1926 const auto *RHSi = dyn_cast<IntInit>(RHS);
1927 if (LHSs && MHSs && RHSi) {
1928 int64_t SourceSize = LHSs->getValue().size();
1929 int64_t Start = RHSi->getValue();
1930 if (Start < 0 || Start > SourceSize)
1932 Twine(
"!find start position is out of range 0...") +
1933 std::to_string(SourceSize) +
": " +
1934 std::to_string(Start));
1935 auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1936 if (
I == std::string::npos)
1944 const auto *Dag = dyn_cast<DagInit>(LHS);
1945 if (Dag && isa<IntInit, StringInit>(MHS)) {
1951 assert(*ArgNo < Dag->getNumArgs());
1955 return DagInit::get(Dag->getOperator(), Dag->getName(), Args,
1956 Dag->getArgNames());
1962 const auto *Dag = dyn_cast<DagInit>(LHS);
1963 if (Dag && isa<IntInit, StringInit>(MHS)) {
1969 assert(*ArgNo < Dag->getNumArgs());
1972 Names[*ArgNo] = dyn_cast<StringInit>(RHS);
1973 return DagInit::get(Dag->getOperator(), Dag->getName(), Dag->getArgs(),
1987 if (
const auto *
Value = dyn_cast_or_null<IntInit>(
1990 if (
Value->getValue())
2007 if (LHS != lhs || MHS != mhs || RHS != rhs)
2009 ->Fold(R.getCurrentRecord());
2015 bool UnquotedLHS =
false;
2017 case DAG: Result =
"!dag";
break;
2018 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
2019 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
2020 case IF: Result =
"!if";
break;
2024 case SUBST: Result =
"!subst";
break;
2025 case SUBSTR: Result =
"!substr";
break;
2026 case FIND: Result =
"!find";
break;
2028 Result =
"!setdagarg";
2031 Result =
"!setdagname";
2034 return (Result +
"(" +
2042 ID.AddPointer(Start);
2046 ID.AddPointer(Expr);
2071 if (
const auto *LI = dyn_cast<ListInit>(List)) {
2072 const Init *Accum = Start;
2073 for (
const Init *Elt : *LI) {
2092 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
2096 ->
Fold(R.getCurrentRecord());
2113 ID.AddPointer(Expr);
2136 if (
const auto *TI = dyn_cast<TypedInit>(Expr)) {
2138 if (TI->getType()->typeIsConvertibleTo(
CheckType))
2145 if ((!
CheckType->typeIsConvertibleTo(TI->getType()) &&
2177 ID.AddPointer(Expr);
2201 if (
const auto *
Name = dyn_cast<StringInit>(Expr)) {
2207 D->getDefInit()->getType()->typeIsA(
CheckType));
2213 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
2215 (Anonymous &&
Name == Anonymous->getNameInit())) {
2234 if (Expr !=
NewExpr || R.isFinal())
2276 if (CurRec && !IsFinal)
2279 const auto *RegexInit = dyn_cast<StringInit>(
Regex);
2283 StringRef RegexStr = RegexInit->getValue();
2291 if (Matcher.
match(Def->getName()))
2298 const Init *NewRegex =
Regex->resolveReferences(R);
2299 if (
Regex != NewRegex || R.isFinal())
2300 return get(
Type, NewRegex)->
Fold(R.getCurrentRecord(), R.isFinal());
2309 return "!instances<" +
Type->getAsString() +
">(" +
Regex->getAsString() +
2317 return Field->getType();
2327 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
2328 cast<BitsRecTy>(Ty)->getNumBits() == 1)
2336 const auto *
T = dyn_cast<BitsRecTy>(
getType());
2337 if (!
T)
return nullptr;
2338 unsigned NumBits =
T->getNumBits();
2342 for (
unsigned Bit : Bits) {
2357 assert(!isa<TypedInit>(Converted) ||
2358 cast<TypedInit>(Converted)->
getType()->typeIsA(Ty));
2362 if (!
getType()->typeIsConvertibleTo(Ty))
2382 const auto *NameString = cast<StringInit>(
getNameInit());
2383 return NameString->getValue();
2393 if (
const Init *Val = R.resolve(VarName))
2407 return TI->
getAsString() +
"{" + utostr(Bit) +
"}";
2418DefInit::DefInit(
const Record *
D)
2422 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
2423 if (
getType()->typeIsConvertibleTo(RRT))
2430 return RV->getType();
2438 ID.AddInteger(Args.size());
2439 ID.AddPointer(Class);
2441 for (
const Init *
I : Args)
2445VarDefInit::VarDefInit(
SMLoc Loc,
const Record *Class,
2463 totalSizeToAlloc<const ArgumentInit *>(Args.size()),
alignof(
VarDefInit));
2473const DefInit *VarDefInit::instantiate() {
2478 auto NewRecOwner = std::make_unique<Record>(
2480 Record *NewRec = NewRecOwner.get();
2483 for (
const RecordVal &Val : Class->getValues())
2496 for (
const Init *Arg : TArgs) {
2501 for (
auto *Arg :
args()) {
2502 if (Arg->isPositional())
2503 R.set(TArgs[Arg->getIndex()], Arg->getValue());
2505 R.set(Arg->getName(), Arg->getValue());
2516 Records.addDef(std::move(NewRecOwner));
2529 bool Changed =
false;
2534 const auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
2536 Changed |= NewArg != Arg;
2542 return const_cast<VarDefInit *
>(New)->instantiate();
2554 Arg->resolveReferences(R);
2556 if (!R.foundUnresolved())
2557 return const_cast<VarDefInit *
>(
this)->instantiate();
2562 std::string Result = Class->getNameInitAsString() +
"<";
2566 Result += Arg->getAsString();
2568 return Result +
">";
2593 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2594 const Record *Def = DI->getDef();
2597 Twine(
"Attempting to access field '") +
2599 Rec->
getAsString() +
"' is a forbidden self-reference");
2600 const Init *FieldVal = Def->getValue(FieldName)->getValue();
2608 if (
const auto *DI = dyn_cast<DefInit>(Rec)) {
2609 const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2618 const RecTy *ValType) {
2620 "Number of conditions and values must match!");
2621 ID.AddPointer(ValType);
2623 for (
const auto &[
Cond, Val] :
zip(Conds, Vals)) {
2645 "Number of conditions and values must match!");
2656 totalSizeToAlloc<const Init *>(2 * Conds.
size()),
alignof(
CondOpInit));
2666 bool Changed =
false;
2668 const Init *NewCond =
Cond->resolveReferences(R);
2670 Changed |= NewCond !=
Cond;
2674 Changed |= NewVal != Val;
2687 if (
const auto *CondI = dyn_cast_or_null<IntInit>(
2689 if (CondI->getValue())
2690 return Val->convertInitializerTo(
getValType());
2698 " does not have any true condition in:" +
2699 this->getAsString());
2705 return std::get<0>(Pair)->isConcrete() && std::get<1>(Pair)->isConcrete();
2711 return std::get<0>(Pair)->isComplete() && std::get<1>(Pair)->isComplete();
2716 std::string Result =
"!cond(";
2720 Result +=
Cond->getAsString() +
": ";
2721 Result += Val->getAsString();
2723 return Result +
")";
2746 ValName(VN), NumArgs(
Args.
size()) {
2755 "Number of DAG args and arg names must match!");
2767 Args.size(), ArgNames.
size()),
2776 ArrayRef<std::pair<const Init *, const StringInit *>> ArgAndNames) {
2787 if (
const auto *DefI = dyn_cast<DefInit>(Val))
2788 return DefI->getDef();
2798 if (It == ArgNames.
end())
2799 return std::nullopt;
2800 return std::distance(ArgNames.
begin(), It);
2806 bool ArgsChanged =
false;
2810 ArgsChanged |= NewArg != Arg;
2814 if (
Op != Val || ArgsChanged)
2835 Result += Arg->getAsString();
2837 Result +=
":$" +
Name->getAsUnquotedString();
2840 return Result +
")";
2848 :
Name(
N), TyAndKind(
T, K) {
2850 assert(
Value &&
"Cannot create unset value for current type!");
2856 :
Name(
N), Loc(Loc), TyAndKind(
T, K) {
2858 assert(
Value &&
"Cannot create unset value for current type!");
2862 return cast<StringInit>(
getNameInit())->getValue();
2867 if (
const auto *StrInit = dyn_cast<StringInit>(
Value)) {
2868 if (StrInit->hasCodeFormat())
2876 return TyAndKind.getPointer()->getAsString();
2892 if (
const auto *BTy = dyn_cast<BitsRecTy>(
getType())) {
2893 if (isa<BitsInit>(
Value))
2896 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2911#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2922 if (PrintSem)
OS <<
";\n";
2926 assert(Locs.size() == 1);
2927 ForwardDeclarationLocs.push_back(Locs.front());
2930 Locs.push_back(Loc);
2933void Record::checkName() {
2935 const auto *TypedName = cast<const TypedInit>(Name);
2936 if (!isa<StringRecTy>(TypedName->getType()))
2938 "' is not a string!");
2948 if (!CorrespondingDefInit) {
2949 CorrespondingDefInit =
2952 return CorrespondingDefInit;
2978 if (NewName != OldName) {
2985 if (SkipVal == &
Value)
2988 const Init *VR = V->resolveReferences(R);
2989 if (
Value.setValue(VR)) {
2991 if (
const auto *VRT = dyn_cast<TypedInit>(VR))
2993 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
2996 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
2997 Value.getNameInitAsString() +
"' of type '" +
3007 const Init *
Value = Assertion.Condition->resolveReferences(R);
3008 Assertion.Condition =
Value;
3009 Value = Assertion.Message->resolveReferences(R);
3010 Assertion.Message =
Value;
3014 const Init *
Value = Dump.Message->resolveReferences(R);
3015 Dump.Message =
Value;
3026#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3031 OS << R.getNameInitAsString();
3034 if (!TArgs.
empty()) {
3037 for (
const Init *TA : TArgs) {
3039 assert(RV &&
"Template argument record not found??");
3047 std::vector<const Record *> SCs = R.getSuperClasses();
3050 for (
const Record *SC : SCs)
3051 OS <<
" " << SC->getNameInitAsString();
3055 for (
const RecordVal &Val : R.getValues())
3056 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3058 for (
const RecordVal &Val : R.getValues())
3059 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3069 "' does not have a field named `" + FieldName +
"'!\n");
3075 if (!R || !R->getValue())
3077 "' does not have a field named `" + FieldName +
"'!\n");
3078 return R->getValue();
3083 if (
const auto *SI = dyn_cast<StringInit>(
I))
3084 return SI->getValue();
3086 "' exists but does not have a string value");
3089std::optional<StringRef>
3092 if (!R || !R->getValue())
3093 return std::nullopt;
3094 if (isa<UnsetInit>(R->getValue()))
3095 return std::nullopt;
3097 if (
const auto *SI = dyn_cast<StringInit>(R->getValue()))
3098 return SI->getValue();
3101 "Record `" +
getName() +
"', ` field `" + FieldName +
3102 "' exists but does not have a string initializer!");
3107 if (
const auto *BI = dyn_cast<BitsInit>(
I))
3110 "' exists but does not have a bits value");
3115 if (
const auto *LI = dyn_cast<ListInit>(
I))
3118 "' exists but does not have a list value");
3121std::vector<const Record *>
3124 std::vector<const Record *> Defs;
3125 for (
const Init *
I :
List->getElements()) {
3126 if (
const auto *DI = dyn_cast<DefInit>(
I))
3127 Defs.push_back(DI->getDef());
3131 "' list is not entirely DefInit!");
3138 if (
const auto *
II = dyn_cast<IntInit>(
I))
3139 return II->getValue();
3142 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3143 "' exists but does not have an int value: " +
I->getAsString());
3149 std::vector<int64_t> Ints;
3150 for (
const Init *
I :
List->getElements()) {
3151 if (
const auto *
II = dyn_cast<IntInit>(
I))
3152 Ints.push_back(
II->getValue());
3155 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3156 "' exists but does not have a list of ints value: " +
3162std::vector<StringRef>
3165 std::vector<StringRef> Strings;
3166 for (
const Init *
I :
List->getElements()) {
3167 if (
const auto *SI = dyn_cast<StringInit>(
I))
3168 Strings.push_back(SI->getValue());
3171 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3172 "' exists but does not have a list of strings value: " +
3180 if (
const auto *DI = dyn_cast<DefInit>(
I))
3181 return DI->getDef();
3183 FieldName +
"' does not have a def initializer!");
3188 if (
const auto *DI = dyn_cast<DefInit>(
I))
3189 return DI->getDef();
3190 if (isa<UnsetInit>(
I))
3193 FieldName +
"' does not have either a def initializer or '?'!");
3198 if (
const auto *BI = dyn_cast<BitInit>(
I))
3199 return BI->getValue();
3201 FieldName +
"' does not have a bit initializer!");
3206 if (isa<UnsetInit>(
I)) {
3211 if (
const auto *BI = dyn_cast<BitInit>(
I))
3212 return BI->getValue();
3214 FieldName +
"' does not have a bit initializer!");
3219 if (
const auto *DI = dyn_cast<DagInit>(
I))
3222 FieldName +
"' does not have a dag initializer!");
3233 bool AnyFailed =
false;
3237 AnyFailed |=
CheckAssert(Assertion.Loc, Condition, Message);
3245 PrintError(
this,
"assertion failed in this record");
3253 const Init *Message = Dump.Message->resolveReferences(R);
3269 : Impl(
std::make_unique<
detail::RecordKeeperImpl>(*this)),
3274#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3279 OS <<
"------------- Classes -----------------\n";
3281 OS <<
"class " << *
C;
3283 OS <<
"------------- Defs -----------------\n";
3299 auto [Iter, Inserted] = Cache.try_emplace(ClassName.
str());
3302 return Iter->second;
3305std::vector<const Record *>
3308 std::vector<const Record *> Defs;
3310 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
3311 for (
StringRef ClassName : ClassNames) {
3318 for (
const auto &OneDef :
getDefs()) {
3320 return OneDef.second->isSubClassOf(Class);
3322 Defs.push_back(OneDef.second.get());
3336 Impl->dumpAllocationStats(
OS);
3340 auto It = Map.find(VarName);
3341 if (It == Map.end())
3344 const Init *
I = It->second.V;
3346 if (!It->second.Resolved && Map.size() > 1) {
3350 I =
I->resolveReferences(*
this);
3351 Map[VarName] = {
I,
true};
3358 const Init *Val = Cache.lookup(VarName);
3366 if (!isa<UnsetInit>(RV->getValue())) {
3367 Val = RV->getValue();
3368 Stack.push_back(VarName);
3373 Stack.push_back(VarName);
3378 Cache[VarName] = Val;
3383 const Init *
I =
nullptr;
3387 if (
I && !FoundUnresolved) {
3392 I->resolveReferences(
Sub);
3393 FoundUnresolved |=
Sub.FoundUnresolved;
3398 FoundUnresolved =
true;
3403 if (VarName == VarNameToTrack)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 void ProfileCondOpInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Conds, ArrayRef< const Init * > Vals, const RecTy *ValType)
static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Elements, const RecTy *EltTy)
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 const StringInit * interleaveStringList(const ListInit *List, const StringInit *Delim)
static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
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 ProfileInstancesOpInit(FoldingSetNodeID &ID, const RecTy *Type, const Init *Regex)
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 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)
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),...
size_t size() const
size - Get the array size.
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.
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
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.
ArrayRef< const Init * > getBits() const
bool allInComplete() const
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...
const Init * Fold(const Record *CurRec) const
auto getCondAndVals() 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.
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.
static const CondOpInit * get(ArrayRef< const Init * > Conds, ArrayRef< const Init * > Values, const RecTy *Type)
const RecTy * getValType() const
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
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?...
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...
const StringInit * getName() const
void Profile(FoldingSetNodeID &ID) const
const Init * getOperator() 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...
ArrayRef< const StringInit * > getArgNames() const
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
const Record * getOperatorAsDef(ArrayRef< SMLoc > Loc) const
auto getArgAndNames() 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.
!instances<type>([regex]) - Produces a list of records whose type is type.
void Profile(FoldingSetNodeID &ID) const
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.
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.
static const InstancesOpInit * get(const RecTy *Type, const Init *Regex)
'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
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 * 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
const Record * getElementAsRecord(unsigned Idx) const
ArrayRef< const Init * > getElements() const
const Init * getElement(unsigned Idx) 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...
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 ...
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...
ArrayRef< std::pair< const Record *, SMRange > > getDirectSuperClasses() const
Return the direct superclasses of this record.
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.
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 addDirectSuperClass(const Record *R, SMRange Range)
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 checkRecordAssertions()
StringRef getValueAsString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
LLVM_ABI bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, if any.
LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
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...
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
See the file comment for details on the usage of the TrailingObjects type.
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.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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.
auto uninitialized_copy(R &&Src, IterTy Dst)
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)
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Sub
Subtraction of integers.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
std::variant< unsigned, const Init * > ArgAuxType
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
void dumpMessage(SMLoc Loc, const Init *Message)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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
FoldingSet< InstancesOpInit > TheInstancesOpInitPool
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)