22#include "llvm/Config/llvm-config.h"
41#define DEBUG_TYPE "tblgen-records"
102#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
114 return Kind ==
RHS->getRecTyKind();
127 return BitsTy->getNumBits() == 1;
142 return "bits<" + utostr(Size) +
">";
147 return cast<BitsRecTy>(
RHS)->Size == Size;
179 if (
const auto *ListTy = dyn_cast<ListRecTy>(
RHS))
200 ID.AddInteger(Classes.
size());
208 if (UnsortedClasses.
empty())
214 UnsortedClasses.
end());
216 return LHS->getNameInitAsString() <
RHS->getNameInitAsString();
228 for (
unsigned i = 0; i < Classes.
size(); ++i) {
229 for (
unsigned j = 0; j < Classes.
size(); ++j) {
232 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
239 std::uninitialized_copy(Classes.
begin(), Classes.
end(),
245 assert(Class &&
"unexpected null class");
246 return get(Class->getRecords(), Class);
255 return getClasses()[0]->getNameInitAsString();
257 std::string Str =
"{";
263 Str += R->getNameInitAsString();
271 return MySuperClass == Class ||
285 return isSubClassOf(TargetClass);
297 while (!Stack.empty()) {
298 Record *R = Stack.pop_back_val();
303 R->getDirectSuperClasses(Stack);
315 if (
RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
319 assert(
T1 !=
nullptr &&
"Invalid record type");
320 if (
T1->typeIsConvertibleTo(T2))
323 assert(T2 !=
nullptr &&
"Invalid record type");
327 if (
ListRecTy *ListTy1 = dyn_cast<ListRecTy>(
T1)) {
328 if (
ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
330 ListTy2->getElementType());
343void Init::anchor() {}
345#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
350 if (
auto *TyInit = dyn_cast<TypedInit>(
this))
351 return TyInit->getType()->getRecordKeeper();
352 return cast<UnsetInit>(
this)->getRecordKeeper();
372 if (isa<BitRecTy>(Ty))
373 return const_cast<BitInit *
>(
this);
375 if (isa<IntRecTy>(Ty))
378 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
380 if (BRT->getNumBits() == 1)
389 ID.AddInteger(Range.size());
391 for (
Init *
I : Range)
407 std::uninitialized_copy(Range.begin(), Range.end(),
408 I->getTrailingObjects<
Init *>());
418 if (isa<BitRecTy>(Ty)) {
423 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
426 if (
getNumBits() != BRT->getNumBits())
return nullptr;
427 return const_cast<BitsInit *
>(
this);
430 if (isa<IntRecTy>(Ty)) {
432 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i)
433 if (
auto *Bit = dyn_cast<BitInit>(
getBit(i)))
434 Result |=
static_cast<int64_t
>(Bit->getValue()) << i;
447 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
450 NewBits[i] =
getBit(Bits[i]);
456 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
464 std::string Result =
"{ ";
465 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
466 if (i) Result +=
", ";
468 Result += Bit->getAsString();
472 return Result +
" }";
478 bool Changed =
false;
481 Init *CachedBitVarRef =
nullptr;
482 Init *CachedBitVarResolved =
nullptr;
484 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
486 Init *NewBit = CurBit;
488 if (
VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
489 if (CurBitVar->getBitVar() != CachedBitVarRef) {
490 CachedBitVarRef = CurBitVar->getBitVar();
493 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
494 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
500 if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
503 Changed |= CurBit != NewBit;
509 return const_cast<BitsInit *
>(
this);
520 return itostr(
Value);
525 return (NumBits >=
sizeof(
Value) * 8) ||
526 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
530 if (isa<IntRecTy>(Ty))
531 return const_cast<IntInit *
>(
this);
533 if (isa<BitRecTy>(Ty)) {
535 if (Val != 0 && Val != 1)
return nullptr;
539 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
546 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
560 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
579 return "anonymous_" + utostr(
Value);
583 auto *Old =
const_cast<Init *
>(
static_cast<const Init *
>(
this));
584 auto *New = R.resolve(Old);
585 New = New ? New : Old;
587 if (
auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
588 return Anonymous->getNameInit();
596 auto &Entry = *InitMap.insert(std::make_pair(V,
nullptr)).first;
603 if (isa<StringRecTy>(Ty))
612 ID.AddInteger(Range.size());
613 ID.AddPointer(EltTy);
615 for (
Init *
I : Range)
628 assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
629 cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
634 std::uninitialized_copy(Range.begin(), Range.end(),
635 I->getTrailingObjects<
Init *>());
641 RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
650 if (
auto *LRT = dyn_cast<ListRecTy>(Ty)) {
656 bool Changed =
false;
657 RecTy *ElementType = LRT->getElementType();
659 if (
Init *CI =
I->convertInitializerTo(ElementType)) {
660 Elements.push_back(CI);
675 assert(i < NumValues &&
"List element index out of range!");
684 Resolved.reserve(
size());
685 bool Changed =
false;
688 Init *
E = CurElt->resolveReferences(R);
689 Changed |=
E != CurElt;
690 Resolved.push_back(
E);
695 return const_cast<ListInit *
>(
this);
699 for (
Init *Element : *
this) {
707 for (
Init *Element : *
this) {
715 std::string Result =
"[";
716 const char *sep =
"";
717 for (
Init *Element : *
this) {
727 return const_cast<OpInit*
>(
this);
733 ID.AddInteger(Opcode);
760 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
764 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
768 if (isa<StringRecTy>(
getType())) {
769 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
772 if (
DefInit *LHSd = dyn_cast<DefInit>(LHS))
775 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
779 }
else if (isa<RecordRecTy>(
getType())) {
785 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
787 (Anonymous &&
Name == Anonymous->getNameInit())) {
794 auto PrintFatalErrorHelper = [CurRec](
const Twine &
T) {
803 PrintFatalErrorHelper(
Twine(
"Undefined reference to record: '") +
804 Name->getValue() +
"'\n");
811 PrintFatalErrorHelper(
Twine(
"Expected type '") +
825 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
831 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
832 assert(!LHSl->empty() &&
"Empty list in head");
833 return LHSl->getElement(0);
838 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
839 assert(!LHSl->empty() &&
"Empty list in tail");
842 return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
847 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
849 if (
DagInit *LHSd = dyn_cast<DagInit>(LHS))
851 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
856 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
858 if (
DagInit *LHSd = dyn_cast<DagInit>(LHS))
860 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
865 if (
DagInit *Dag = dyn_cast<DagInit>(LHS)) {
869 Twine(
"Expected type '") +
880 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
882 int64_t LHSv = LHSi->getValue();
885 "Illegal operation: logtwo is undefined "
886 "on arguments less than or equal to 0");
890 "Log of an int64_t must be smaller than INT64_MAX");
896 return const_cast<UnOpInit *
>(
this);
904 ->Fold(R.getCurrentRecord(), R.isFinal());
905 return const_cast<UnOpInit *
>(
this);
912 case NOT: Result =
"!not";
break;
913 case HEAD: Result =
"!head";
break;
914 case TAIL: Result =
"!tail";
break;
915 case SIZE: Result =
"!size";
break;
916 case EMPTY: Result =
"!empty";
break;
917 case GETDAGOP: Result =
"!getdagop";
break;
918 case LOG2 : Result =
"!logtwo";
break;
932 ID.AddInteger(Opcode);
959 Concat.append(I1->getValue());
967 if (
List->size() == 0)
975 for (
unsigned I = 1,
E =
List->size();
I <
E; ++
I) {
989 if (
List->size() == 0)
991 IntInit *Element = dyn_cast_or_null<IntInit>(
997 for (
unsigned I = 1,
E =
List->size();
I <
E; ++
I) {
999 IntInit *Element = dyn_cast_or_null<IntInit>(
1010 if (
const StringInit *I0s = dyn_cast<StringInit>(I0))
1011 if (
const StringInit *I1s = dyn_cast<StringInit>(I1))
1029 if (
const ListInit *LHSList = dyn_cast<ListInit>(
LHS))
1030 if (
const ListInit *RHSList = dyn_cast<ListInit>(
RHS))
1038 IntInit *LHSi = dyn_cast_or_null<IntInit>(
1040 IntInit *RHSi = dyn_cast_or_null<IntInit>(
1106 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1109 return std::nullopt;
1113 std::string &
Error) {
1116 int64_t Pos =
Idx->getValue();
1120 (
Twine(
"index ") + std::to_string(Pos) +
Twine(
" is negative")).str();
1121 return std::nullopt;
1123 if (Pos >= Dag->getNumArgs()) {
1125 Error = (
Twine(
"index ") + std::to_string(Pos) +
1126 " is out of range (dag has " +
1127 std::to_string(Dag->getNumArgs()) +
" arguments)")
1129 return std::nullopt;
1133 assert(isa<StringInit>(Key));
1136 auto ArgNo = Dag->getArgNo(
Name->getValue());
1140 return std::nullopt;
1148 DagInit *LHSs = dyn_cast<DagInit>(LHS);
1149 DagInit *RHSs = dyn_cast<DagInit>(RHS);
1153 if ((!LOp && !isa<UnsetInit>(LHSs->
getOperator())) ||
1161 Init *Op = LOp ? LOp : ROp;
1167 for (
unsigned i = 0, e = LHSs->
getNumArgs(); i != e; ++i) {
1168 Args.push_back(LHSs->
getArg(i));
1171 for (
unsigned i = 0, e = RHSs->
getNumArgs(); i != e; ++i) {
1172 Args.push_back(RHSs->
getArg(i));
1180 ListInit *LHSs = dyn_cast<ListInit>(LHS);
1181 ListInit *RHSs = dyn_cast<ListInit>(RHS);
1200 ListInit *LHSs = dyn_cast<ListInit>(LHS);
1201 ListInit *RHSs = dyn_cast<ListInit>(RHS);
1204 for (
Init *EltLHS : *LHSs) {
1206 for (
Init *EltRHS : *RHSs) {
1207 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1215 Args.push_back(EltLHS);
1222 auto *TheList = dyn_cast<ListInit>(LHS);
1223 auto *
Idx = dyn_cast<IntInit>(RHS);
1224 if (!TheList || !
Idx)
1226 auto i =
Idx->getValue();
1227 if (i < 0 || i >= (ssize_t)TheList->size())
1229 return TheList->getElement(i);
1232 auto *TheList = dyn_cast<ListInit>(LHS);
1233 auto *SliceIdxs = dyn_cast<ListInit>(RHS);
1234 if (!TheList || !SliceIdxs)
1237 Args.reserve(SliceIdxs->size());
1238 for (
auto *
I : *SliceIdxs) {
1239 auto *II = dyn_cast<IntInit>(
I);
1242 auto i = II->getValue();
1243 if (i < 0 || i >= (ssize_t)TheList->size())
1245 Args.push_back(TheList->getElement(i));
1251 auto *LHSi = dyn_cast<IntInit>(LHS);
1252 auto *RHSi = dyn_cast<IntInit>(RHS);
1256 auto Start = LHSi->getValue();
1257 auto End = RHSi->getValue();
1263 Args.reserve(
End - Start + 1);
1264 for (
auto i = Start; i <=
End; ++i)
1268 Args.reserve(Start -
End + 1);
1269 for (
auto i = Start; i >=
End; --i)
1272 }
else if (Start <
End) {
1274 Args.reserve(
End - Start);
1275 for (
auto i = Start; i <
End; ++i)
1283 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1284 StringInit *RHSs = dyn_cast<StringInit>(RHS);
1291 StringInit *Delim = dyn_cast<StringInit>(RHS);
1292 if (
List && Delim) {
1294 if (isa<StringRecTy>(
List->getElementType()))
1314 DagInit *Dag = dyn_cast<DagInit>(LHS);
1315 if (Dag && isa<IntInit, StringInit>(RHS)) {
1321 assert(*ArgNo < Dag->getNumArgs());
1323 Init *
Arg = Dag->getArg(*ArgNo);
1324 if (
auto *TI = dyn_cast<TypedInit>(
Arg))
1325 if (!TI->getType()->typeIsConvertibleTo(
getType()))
1332 DagInit *Dag = dyn_cast<DagInit>(LHS);
1335 int64_t Pos =
Idx->getValue();
1336 if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1339 Twine(
"!getdagname index is out of range 0...") +
1340 std::to_string(Dag->getNumArgs() - 1) +
": " +
1341 std::to_string(Pos));
1343 Init *ArgName = Dag->getArgName(Pos);
1351 DagInit *Dag = dyn_cast<DagInit>(LHS);
1352 DefInit *Op = dyn_cast<DefInit>(RHS);
1356 for (
unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
1357 Args.push_back(Dag->getArg(i));
1374 IntInit *LHSi = dyn_cast_or_null<IntInit>(
1376 IntInit *RHSi = dyn_cast_or_null<IntInit>(
1383 case ADD: Result = LHSv + RHSv;
break;
1384 case SUB: Result = LHSv - RHSv;
break;
1385 case MUL: Result = LHSv * RHSv;
break;
1389 "Illegal operation: division by zero");
1390 else if (LHSv ==
INT64_MIN && RHSv == -1)
1392 "Illegal operation: INT64_MIN / -1");
1394 Result = LHSv / RHSv;
1396 case AND: Result = LHSv & RHSv;
break;
1397 case OR: Result = LHSv | RHSv;
break;
1398 case XOR: Result = LHSv ^ RHSv;
break;
1400 case SRA: Result = LHSv >> RHSv;
break;
1416 if (LHS != lhs || RHS != rhs)
1418 ->Fold(R.getCurrentRecord());
1430 case CONCAT: Result =
"!con";
break;
1431 case ADD: Result =
"!add";
break;
1432 case SUB: Result =
"!sub";
break;
1433 case MUL: Result =
"!mul";
break;
1434 case DIV: Result =
"!div";
break;
1435 case AND: Result =
"!and";
break;
1436 case OR: Result =
"!or";
break;
1437 case XOR: Result =
"!xor";
break;
1438 case SHL: Result =
"!shl";
break;
1439 case SRA: Result =
"!sra";
break;
1440 case SRL: Result =
"!srl";
break;
1441 case EQ: Result =
"!eq";
break;
1442 case NE: Result =
"!ne";
break;
1443 case LE: Result =
"!le";
break;
1444 case LT: Result =
"!lt";
break;
1445 case GE: Result =
"!ge";
break;
1446 case GT: Result =
"!gt";
break;
1447 case LISTCONCAT: Result =
"!listconcat";
break;
1448 case LISTSPLAT: Result =
"!listsplat";
break;
1449 case LISTREMOVE: Result =
"!listremove";
break;
1450 case RANGE: Result =
"!range";
break;
1451 case STRCONCAT: Result =
"!strconcat";
break;
1452 case INTERLEAVE: Result =
"!interleave";
break;
1453 case SETDAGOP: Result =
"!setdagop";
break;
1458 Result =
"!getdagname";
1467 ID.AddInteger(Opcode);
1496 return RHS->resolveReferences(R);
1501 bool Change =
false;
1507 for (
unsigned int i = 0; i < MHSd->
getNumArgs(); ++i) {
1517 NewArgs.
push_back(std::make_pair(NewArg, ArgName));
1530 if (
DagInit *MHSd = dyn_cast<DagInit>(MHS))
1533 if (
ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1536 for (
Init *&Item : NewList) {
1538 if (NewItem != Item)
1551 if (
ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1554 for (
Init *Item : MHSl->getValues()) {
1559 dyn_cast_or_null<IntInit>(
Include->convertInitializerTo(
1561 if (IncludeInt->getValue())
1577 DefInit *LHSd = dyn_cast<DefInit>(LHS);
1578 VarInit *LHSv = dyn_cast<VarInit>(LHS);
1579 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1581 DefInit *MHSd = dyn_cast<DefInit>(MHS);
1582 VarInit *MHSv = dyn_cast<VarInit>(MHS);
1583 StringInit *MHSs = dyn_cast<StringInit>(MHS);
1585 DefInit *RHSd = dyn_cast<DefInit>(RHS);
1586 VarInit *RHSv = dyn_cast<VarInit>(RHS);
1587 StringInit *RHSs = dyn_cast<StringInit>(RHS);
1589 if (LHSd && MHSd && RHSd) {
1595 if (LHSv && MHSv && RHSv) {
1596 std::string Val = std::string(RHSv->
getName());
1598 Val = std::string(MHSv->
getName());
1601 if (LHSs && MHSs && RHSs) {
1602 std::string Val = std::string(RHSs->
getValue());
1604 std::string::size_type found;
1605 std::string::size_type idx = 0;
1607 found = Val.find(std::string(LHSs->
getValue()), idx);
1608 if (found == std::string::npos)
1633 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
1635 if (LHSi->getValue())
1643 ListInit *MHSl = dyn_cast<ListInit>(MHS);
1644 ListInit *RHSl = dyn_cast<ListInit>(RHS);
1645 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1646 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1648 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1651 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->
size() == RHSl->
size())) {
1654 for (
unsigned i = 0; i !=
Size; ++i) {
1657 if (!isa<StringInit>(
Name) && !isa<UnsetInit>(
Name))
1659 Children.emplace_back(
Node, dyn_cast<StringInit>(
Name));
1667 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1668 IntInit *MHSi = dyn_cast<IntInit>(MHS);
1669 IntInit *RHSi = dyn_cast<IntInit>(RHS);
1670 if (LHSs && MHSi && RHSi) {
1674 if (Start < 0 || Start > StringSize)
1676 Twine(
"!substr start position is out of range 0...") +
1677 std::to_string(StringSize) +
": " +
1678 std::to_string(Start));
1688 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1689 StringInit *MHSs = dyn_cast<StringInit>(MHS);
1690 IntInit *RHSi = dyn_cast<IntInit>(RHS);
1691 if (LHSs && MHSs && RHSi) {
1694 if (Start < 0 || Start > SourceSize)
1696 Twine(
"!find start position is out of range 0...") +
1697 std::to_string(SourceSize) +
": " +
1698 std::to_string(Start));
1700 if (
I == std::string::npos)
1708 DagInit *Dag = dyn_cast<DagInit>(LHS);
1709 if (Dag && isa<IntInit, StringInit>(MHS)) {
1715 assert(*ArgNo < Dag->getNumArgs());
1726 DagInit *Dag = dyn_cast<DagInit>(LHS);
1727 if (Dag && isa<IntInit, StringInit>(MHS)) {
1733 assert(*ArgNo < Dag->getNumArgs());
1737 Names[*ArgNo] = dyn_cast<StringInit>(RHS);
1754 if (
Value->getValue())
1771 if (LHS != lhs || MHS != mhs || RHS != rhs)
1773 ->Fold(R.getCurrentRecord());
1779 bool UnquotedLHS =
false;
1781 case DAG: Result =
"!dag";
break;
1782 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
1783 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
1784 case IF: Result =
"!if";
break;
1785 case SUBST: Result =
"!subst";
break;
1786 case SUBSTR: Result =
"!substr";
break;
1787 case FIND: Result =
"!find";
break;
1789 Result =
"!setdagarg";
1792 Result =
"!setdagname";
1795 return (Result +
"(" +
1802 ID.AddPointer(Start);
1806 ID.AddPointer(Expr);
1830 if (
ListInit *LI = dyn_cast<ListInit>(List)) {
1831 Init *Accum = Start;
1832 for (
Init *Elt : *LI) {
1851 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
1855 ->
Fold(R.getCurrentRecord());
1872 ID.AddPointer(Expr);
1895 if (
TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
1897 if (TI->getType()->typeIsConvertibleTo(CheckType))
1900 if (isa<RecordRecTy>(CheckType)) {
1934 ID.AddPointer(Expr);
1969 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
1971 (Anonymous &&
Name == Anonymous->getNameInit())) {
1991 if (Expr !=
NewExpr || R.isFinal())
1992 return get(CheckType,
NewExpr)->
Fold(R.getCurrentRecord(), R.isFinal());
2010 return Field->getType();
2021 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
2022 cast<BitsRecTy>(Ty)->getNumBits() == 1)
2030 if (!
T)
return nullptr;
2031 unsigned NumBits =
T->getNumBits();
2035 for (
unsigned Bit : Bits) {
2050 assert(!isa<TypedInit>(Converted) ||
2051 cast<TypedInit>(Converted)->
getType()->typeIsA(Ty));
2055 if (!
getType()->typeIsConvertibleTo(Ty))
2082 return const_cast<VarInit*
>(
this);
2087 if (
Init *Val = R.resolve(VarName))
2089 return const_cast<VarInit *
>(
this);
2101 return TI->
getAsString() +
"{" + utostr(Bit) +
"}";
2116 return R->getDefInit();
2120 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
2121 if (
getType()->typeIsConvertibleTo(RRT))
2122 return const_cast<DefInit *
>(
this);
2128 return RV->getType();
2137 ID.AddInteger(Args.size());
2138 ID.AddPointer(Class);
2140 for (
Init *
I : Args)
2144VarDefInit::VarDefInit(
Record *Class,
unsigned N)
2160 std::uninitialized_copy(Args.begin(), Args.end(),
2161 I->getTrailingObjects<
Init *>());
2170DefInit *VarDefInit::instantiate() {
2174 Class->
getLoc(), Records,
2176 Record *NewRec = NewRecOwner.get();
2189 for (
unsigned i = 0, e = TArgs.
size(); i != e; ++i) {
2191 R.set(TArgs[i],
getArg(i));
2202 for (
const auto &SCPair : SCs)
2207 Class->
getLoc().back()));
2211 Records.
addDef(std::move(NewRecOwner));
2224 bool Changed =
false;
2229 Init *NewArg =
Arg->resolveReferences(UR);
2231 Changed |= NewArg !=
Arg;
2237 return New->instantiate();
2249 Arg->resolveReferences(R);
2251 if (!R.foundUnresolved())
2252 return const_cast<VarDefInit *
>(
this)->instantiate();
2258 const char *sep =
"";
2262 Result +=
Arg->getAsString();
2264 return Result +
">";
2289 if (
DefInit *DI = dyn_cast<DefInit>(Rec)) {
2290 Record *Def = DI->getDef();
2293 Twine(
"Attempting to access field '") +
2295 Rec->
getAsString() +
"' is a forbidden self-reference");
2296 Init *FieldVal = Def->getValue(FieldName)->getValue();
2304 if (
DefInit *DI = dyn_cast<DefInit>(Rec)) {
2305 Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2314 const RecTy *ValType) {
2316 "Number of conditions and values must match!");
2317 ID.AddPointer(ValType);
2321 while (Case != CondRange.
end()) {
2322 ID.AddPointer(*Case++);
2323 ID.AddPointer(*Val++);
2329 ArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds),
2336 "Number of conditions and values must match!");
2347 totalSizeToAlloc<Init *>(2 * CondRange.
size()),
alignof(
BitsInit));
2350 std::uninitialized_copy(CondRange.
begin(), CondRange.
end(),
2351 I->getTrailingObjects<
Init *>());
2352 std::uninitialized_copy(ValRange.
begin(), ValRange.
end(),
2353 I->getTrailingObjects<
Init *>()+CondRange.
size());
2360 bool Changed =
false;
2364 Changed |= NewCase != Case;
2371 Changed |= NewVal != Val;
2383 for (
unsigned i = 0; i < NumConds; ++i) {
2387 if (
IntInit *CondI = dyn_cast_or_null<IntInit>(
2389 if (CondI->getValue())
2398 " does not have any true condition in:" +
2399 this->getAsString());
2405 if (!Case->isConcrete())
2409 if (!Val->isConcrete())
2417 if (!Case->isComplete())
2421 if (!Val->isConcrete())
2428 std::string Result =
"!cond(";
2435 return Result +
")";
2450 while (
Arg != ArgRange.
end()) {
2452 ID.AddPointer(*
Arg++);
2470 totalSizeToAlloc<Init *, StringInit *>(ArgRange.
size(), NameRange.
size()),
2473 std::uninitialized_copy(ArgRange.
begin(), ArgRange.
end(),
2474 I->getTrailingObjects<
Init *>());
2475 std::uninitialized_copy(NameRange.
begin(), NameRange.
end(),
2487 for (
const auto &
Arg :
args) {
2488 Args.push_back(
Arg.first);
2497 ArrayRef(getTrailingObjects<Init *>(), NumArgs),
2498 ArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
2502 if (
DefInit *DefI = dyn_cast<DefInit>(Val))
2503 return DefI->getDef();
2509 for (
unsigned i = 0, e =
getNumArgs(); i < e; ++i) {
2514 return std::nullopt;
2520 bool ArgsChanged =
false;
2522 Init *NewArg =
Arg->resolveReferences(R);
2524 ArgsChanged |= NewArg !=
Arg;
2528 if (Op != Val || ArgsChanged)
2531 return const_cast<DagInit *
>(
this);
2538 if (!Elt->isConcrete())
2551 for (
unsigned i = 1, e =
getNumArgs(); i != e; ++i) {
2556 return Result +
")";
2564 :
Name(
N), TyAndKind(
T, K) {
2566 assert(
Value &&
"Cannot create unset value for current type!");
2572 :
Name(
N), Loc(Loc), TyAndKind(
T, K) {
2574 assert(
Value &&
"Cannot create unset value for current type!");
2578 return cast<StringInit>(
getNameInit())->getValue();
2583 if (
auto *StrInit = dyn_cast<StringInit>(
Value)) {
2584 if (StrInit->hasCodeFormat())
2592 return TyAndKind.getPointer()->getAsString();
2603 if (!isa<BitsInit>(
Value)) {
2605 Bits.reserve(BTy->getNumBits());
2606 for (
unsigned I = 0,
E = BTy->getNumBits();
I <
E; ++
I)
2607 Bits.push_back(
Value->getBit(
I));
2612 return Value ==
nullptr;
2628 if (!isa<BitsInit>(
Value)) {
2630 Bits.reserve(BTy->getNumBits());
2631 for (
unsigned I = 0,
E = BTy->getNumBits();
I <
E; ++
I)
2632 Bits.push_back(
Value->getBit(
I));
2637 return Value ==
nullptr;
2643#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2655 if (PrintSem)
OS <<
";\n";
2659 assert(Locs.size() == 1);
2660 ForwardDeclarationLocs.push_back(Locs.front());
2663 Locs.push_back(Loc);
2666void Record::checkName() {
2668 const TypedInit *TypedName = cast<const TypedInit>(Name);
2669 if (!isa<StringRecTy>(TypedName->
getType()))
2671 "' is not a string!");
2681 if (!CorrespondingDefInit) {
2682 CorrespondingDefInit =
2685 return CorrespondingDefInit;
2716 for (
int I = SCs.
size() - 1;
I >= 0; --
I) {
2717 const Record *SC = SCs[
I].first;
2718 if (SC == Superclass)
2720 I -= SC->getSuperClasses().size();
2729 while (!SCs.
empty()) {
2731 SCs = SCs.
drop_back(1 + SC->getSuperClasses().size());
2739 if (NewName != OldName) {
2746 if (SkipVal == &
Value)
2749 Init *VR = V->resolveReferences(R);
2750 if (
Value.setValue(VR)) {
2752 if (
TypedInit *VRT = dyn_cast<TypedInit>(VR))
2754 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
2757 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
2758 Value.getNameInitAsString() +
"' of type '" +
2767 for (
auto &Assertion : Assertions) {
2768 Init *
Value = Assertion.Condition->resolveReferences(R);
2769 Assertion.Condition =
Value;
2770 Value = Assertion.Message->resolveReferences(R);
2771 Assertion.Message =
Value;
2782#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2787 OS << R.getNameInitAsString();
2790 if (!TArgs.
empty()) {
2792 bool NeedComma =
false;
2793 for (
const Init *TA : TArgs) {
2794 if (NeedComma)
OS <<
", ";
2797 assert(RV &&
"Template argument record not found??");
2807 for (
const auto &SuperPair : SC)
2808 OS <<
" " << SuperPair.first->getNameInitAsString();
2812 for (
const RecordVal &Val : R.getValues())
2813 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
2815 for (
const RecordVal &Val : R.getValues())
2816 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
2826 "' does not have a field named `" + FieldName +
"'!\n");
2832 if (!R || !R->getValue())
2834 "' does not have a field named `" + FieldName +
"'!\n");
2835 return R->getValue();
2842 "' does not have a field named `" + FieldName +
"'!\n");
2846std::optional<StringRef>
2849 if (!R || !R->getValue())
2850 return std::nullopt;
2851 if (isa<UnsetInit>(R->getValue()))
2852 return std::nullopt;
2854 if (
StringInit *
SI = dyn_cast<StringInit>(R->getValue()))
2855 return SI->getValue();
2858 "Record `" +
getName() +
"', ` field `" + FieldName +
2859 "' exists but does not have a string initializer!");
2864 if (!R || !R->getValue())
2866 "' does not have a field named `" + FieldName +
"'!\n");
2868 if (
BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
2871 "' exists but does not have a bits value");
2876 if (!R || !R->getValue())
2878 "' does not have a field named `" + FieldName +
"'!\n");
2880 if (
ListInit *LI = dyn_cast<ListInit>(R->getValue()))
2883 "' exists but does not have a list value");
2889 std::vector<Record*> Defs;
2891 if (
DefInit *DI = dyn_cast<DefInit>(
I))
2892 Defs.push_back(DI->getDef());
2895 FieldName +
"' list is not entirely DefInit!");
2902 if (!R || !R->getValue())
2904 "' does not have a field named `" + FieldName +
"'!\n");
2906 if (
IntInit *II = dyn_cast<IntInit>(R->getValue()))
2907 return II->getValue();
2910 "' exists but does not have an int value: " +
2911 R->getValue()->getAsString());
2917 std::vector<int64_t> Ints;
2919 if (
IntInit *II = dyn_cast<IntInit>(
I))
2920 Ints.push_back(II->getValue());
2923 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2924 "' exists but does not have a list of ints value: " +
2930std::vector<StringRef>
2933 std::vector<StringRef> Strings;
2936 Strings.push_back(
SI->getValue());
2939 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2940 "' exists but does not have a list of strings value: " +
2948 if (!R || !R->getValue())
2950 "' does not have a field named `" + FieldName +
"'!\n");
2952 if (
DefInit *DI = dyn_cast<DefInit>(R->getValue()))
2953 return DI->getDef();
2955 FieldName +
"' does not have a def initializer!");
2960 if (!R || !R->getValue())
2962 "' does not have a field named `" + FieldName +
"'!\n");
2964 if (
DefInit *DI = dyn_cast<DefInit>(R->getValue()))
2965 return DI->getDef();
2966 if (isa<UnsetInit>(R->getValue()))
2969 FieldName +
"' does not have either a def initializer or '?'!");
2975 if (!R || !R->getValue())
2977 "' does not have a field named `" + FieldName +
"'!\n");
2979 if (
BitInit *BI = dyn_cast<BitInit>(R->getValue()))
2980 return BI->getValue();
2982 FieldName +
"' does not have a bit initializer!");
2987 if (!R || !R->getValue())
2989 "' does not have a field named `" + FieldName.
str() +
"'!\n");
2991 if (isa<UnsetInit>(R->getValue())) {
2996 if (
BitInit *BI = dyn_cast<BitInit>(R->getValue()))
2997 return BI->getValue();
2999 FieldName +
"' does not have a bit initializer!");
3004 if (!R || !R->getValue())
3006 "' does not have a field named `" + FieldName +
"'!\n");
3008 if (
DagInit *DI = dyn_cast<DagInit>(R->getValue()))
3011 FieldName +
"' does not have a dag initializer!");
3035 "unused template argument: " +
Twine(
Arg->getName()));
3040 : Impl(
std::make_unique<detail::RecordKeeperImpl>(*this)) {}
3043#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3048 OS <<
"------------- Classes -----------------\n";
3050 OS <<
"class " << *
C.second;
3052 OS <<
"------------- Defs -----------------\n";
3054 OS <<
"def " << *
D.second;
3069 if (LastTimer && LastTimer->
isRunning()) {
3073 BackendTimer =
false;
3077 LastTimer =
new Timer(
"",
Name, *TimingGroup);
3084 assert(LastTimer &&
"No phase timer was started");
3092 BackendTimer =
true;
3100 BackendTimer =
false;
3105std::vector<Record *>
3109 auto Pair = ClassRecordsMap.try_emplace(ClassName);
3113 return Pair.first->second;
3119 std::vector<Record *> Defs;
3121 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
3122 for (
const auto &ClassName : ClassNames) {
3129 for (
const auto &OneDef :
getDefs()) {
3131 return OneDef.second->isSubClassOf(Class);
3133 Defs.push_back(OneDef.second.get());
3143std::vector<Record *>
3146 : std::vector<Record *>();
3150 auto It = Map.find(VarName);
3151 if (It == Map.end())
3154 Init *
I = It->second.V;
3156 if (!It->second.Resolved && Map.size() > 1) {
3160 I =
I->resolveReferences(*
this);
3161 Map[VarName] = {
I,
true};
3168 Init *Val = Cache.lookup(VarName);
3176 if (!isa<UnsetInit>(RV->getValue())) {
3177 Val = RV->getValue();
3178 Stack.push_back(VarName);
3183 Stack.push_back(VarName);
3188 Cache[VarName] = Val;
3197 if (
I && !FoundUnresolved) {
3202 I->resolveReferences(Sub);
3203 FoundUnresolved |= Sub.FoundUnresolved;
3208 FoundUnresolved =
true;
3214 if (VarName == VarNameToTrack)
This file defines the StringMap class.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file defines the BumpPtrAllocator interface.
SmallVector< MachineOperand, 4 > Cond
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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#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.
static bool canFitInBitfield(int64_t Value, unsigned NumBits)
static StringInit * interleaveIntList(const ListInit *List, const StringInit *Delim)
static void ProfileExistsOpInit(FoldingSetNodeID &ID, RecTy *CheckType, Init *Expr)
static std::optional< unsigned > getDagArgNoByKey(DagInit *Dag, Init *Key, std::string &Error)
static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS, RecTy *Type)
static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS, Init *RHS, RecTy *Type)
static StringInit * interleaveStringList(const ListInit *List, const StringInit *Delim)
static void ProfileVarDefInit(FoldingSetNodeID &ID, Record *Class, ArrayRef< Init * > Args)
static Init * ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec)
static void ProfileRecordRecTy(FoldingSetNodeID &ID, ArrayRef< Record * > Classes)
static StringInit * ConcatStringInits(const StringInit *I0, const StringInit *I1)
static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType, Init *Expr)
static RecordRecTy * resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2)
static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN, ArrayRef< Init * > ArgRange, ArrayRef< StringInit * > NameRange)
static Init * ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Record *CurRec)
static Init * FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Record *CurRec)
static Init * ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS, Record *CurRec)
static void ProfileCondOpInit(FoldingSetNodeID &ID, ArrayRef< Init * > CondRange, ArrayRef< Init * > ValRange, const RecTy *ValType)
static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef< Init * > Range)
static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef< Init * > Range, RecTy *EltTy)
static ListInit * ConcatListInits(const ListInit *LHS, const ListInit *RHS)
static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type)
static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, 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
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...
StringInit * getNameInit() const
static AnonymousNameInit * get(RecordKeeper &RK, unsigned)
std::string getAsString() const override
Convert this value to a literal form.
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.
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
std::optional< bool > CompareInit(unsigned Opc, Init *LHS, Init *RHS) const
std::string getAsString() const override
Convert this value to a literal form.
BinaryOp getOpcode() const
Init * Fold(Record *CurRec) const
static Init * getStrConcat(Init *lhs, Init *rhs)
static Init * getListConcat(TypedInit *lhs, Init *rhs)
static BinOpInit * get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type)
'true'/'false' - Represent a concrete initializer for a bit.
static BitInit * get(RecordKeeper &RK, bool V)
Init * convertInitializerTo(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 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
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.
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
unsigned getNumBits() const
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
static BitsInit * get(RecordKeeper &RK, ArrayRef< Init * > Range)
'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.
std::string getAsString() const override
static BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
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...
Init * getCond(unsigned Num) const
ArrayRef< Init * > getVals() const
static CondOpInit * get(ArrayRef< Init * > C, ArrayRef< Init * > V, RecTy *Type)
ArrayRef< Init * > getConds() const
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
void Profile(FoldingSetNodeID &ID) const
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
std::string getAsString() const override
Convert this value to a literal form.
Init * Fold(Record *CurRec) const
unsigned getNumConds() const
RecTy * getValType() const
Init * getVal(unsigned Num) 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 isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
(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
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...
Init * getOperator() const
StringInit * getArgName(unsigned Num) const
Record * getOperatorAsDef(ArrayRef< SMLoc > Loc) const
ArrayRef< StringInit * > getArgNames() const
static DagInit * get(Init *V, StringInit *VN, ArrayRef< Init * > ArgRange, ArrayRef< StringInit * > NameRange)
void Profile(FoldingSetNodeID &ID) const
Init * getArg(unsigned Num) const
ArrayRef< Init * > getArgs() 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.
'dag' - Represent a dag fragment
std::string getAsString() const override
static DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
std::string getAsString() const override
Convert this value to a literal form.
RecTy * getFieldType(StringInit *FieldName) const override
This method is used to implement the FieldInit class.
static DefInit * get(Record *)
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
Init * Fold(Record *CurRec, bool IsFinal=false) const
static ExistsOpInit * get(RecTy *CheckType, Init *Expr)
std::string getAsString() const override
Convert this value to a literal form.
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...
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.
Init * Fold(Record *CurRec) const
static FieldInit * get(Init *R, StringInit *FN)
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
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.
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...
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
std::string getAsString() const override
Convert this value to a literal form.
Init * Fold(Record *CurRec) const
static FoldOpInit * get(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type)
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...
Init * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
virtual Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual 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?
RecordKeeper & getRecordKeeper() const
Get the record keeper that initialized this Init.
virtual Init * convertInitializerTo(RecTy *Ty) const =0
Convert to a value whose type is Ty, or return null if this is not possible.
'7' - Represent an initialization by a literal integer value.
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
static IntInit * get(RecordKeeper &RK, int64_t V)
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
std::string getAsString() const override
Convert this value to a literal form.
'int' - Represent an integer value of no particular size
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
static IntRecTy * get(RecordKeeper &RK)
!isa<type>(expr) - Dynamically determine the type of an expression.
void Profile(FoldingSetNodeID &ID) const
static IsAOpInit * get(RecTy *CheckType, Init *Expr)
std::string getAsString() const override
Convert this value to a literal form.
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...
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
[AL, AH, CL] - Represent a list of defs
std::string getAsString() const override
Convert this value to a literal form.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?...
static ListInit * get(ArrayRef< Init * > Range, RecTy *EltTy)
RecTy * getElementType() const
Init * getElement(unsigned i) const
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
Init * convertInitializerTo(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< Init * > getValues() const
Record * getElementAsRecord(unsigned i) 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...
'list<Ty>' - Represent a list of element values, all of which must be of the specified type.
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.
RecTy * getElementType() const
Resolve arbitrary mappings.
Init * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
Base class for operators.
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
RecordKeeper & getRecordKeeper() const
Return the RecordKeeper that uniqued this Type.
ListRecTy * getListTy()
Returns the type representing list<thistype>.
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
void print(raw_ostream &OS) const
void addDef(std::unique_ptr< Record > R)
std::vector< Record * > getAllDerivedDefinitions(StringRef ClassName) const
Get all the concrete records that inherit from the one specified class.
Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
const RecordMap & getClasses() const
Get the map of classes.
Record * getClass(StringRef Name) const
Get the class with the specified name.
std::vector< Record * > getAllDerivedDefinitionsIfDefined(StringRef ClassName) const
Get all the concrete records that inherit from specified class, if the class is defined.
const RecordMap & getDefs() const
Get the map of records (defs).
detail::RecordKeeperImpl & getImpl()
Return the internal implementation of the RecordKeeper.
void stopBackendTimer()
Stop timing the overall backend.
void stopTimer()
Stop timing a phase.
void startTimer(StringRef Name)
Start timing a phase. Automatically stops any previous phase timer.
Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
void startBackendTimer(StringRef Name)
Start timing the overall backend.
'[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.
void Profile(FoldingSetNodeID &ID) const
static RecordRecTy * get(RecordKeeper &RK, ArrayRef< Record * > Classes)
Get the record type with the given non-redundant list of superclasses.
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.
bool isSubClassOf(Record *Class) const
ArrayRef< Record * > getClasses() const
Resolve all variables from a record except for unset variables.
Init * resolve(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.
bool setValue(Init *V)
Set the value of the field from an Init.
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?
RecordKeeper & getRecordKeeper() const
Get the record keeper used to unique this value.
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.
RecTy * getType() const
Get the type of the field value as a RecTy.
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.
RecordVal(Init *N, RecTy *T, FieldKind K)
Init * getValue() const
Get the value of the field as an Init.
std::vector< int64_t > getValueAsListOfInts(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of integers,...
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()
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< AssertionInfo > getAssertions() const
std::string getNameInitAsString() const
Init * getNameInit() 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 getDirectSuperClasses(SmallVectorImpl< Record * > &Classes) const
Append the direct superclasses of this record to Classes.
RecordKeeper & getRecords() const
BitsInit * getValueAsBitsInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a BitsInit, throwing an exception i...
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
Record * getValueAsDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, throwing an exception if ...
void addValue(const RecordVal &RV)
DagInit * getValueAsDag(StringRef FieldName) const
This method looks up the specified field and returns its value as an Dag, throwing an exception if th...
bool hasDirectSuperClass(const Record *SuperClass) const
Determine whether this record has the specified direct superclass.
StringRef getName() const
ArrayRef< Init * > getTemplateArgs() const
bool isSubClassOf(const Record *R) 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...
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
std::vector< Record * > getValueAsListOfDefs(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of records,...
void addSuperClass(Record *R, SMRange Range)
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 ...
DefInit * getDefInit()
get the corresponding DefInit.
void updateClassLoc(SMLoc Loc)
void resolveReferences(Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
void appendAssertions(const Record *Rec)
ArrayRef< std::pair< Record *, SMRange > > getSuperClasses() 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 removeValue(Init *Name)
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.
Record * getCurrentRecord() const
virtual Init * resolve(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(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.
StringFormat getFormat() const
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
StringRef getValue() const
static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2)
static StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
std::string getAsUnquotedString() const override
Convert this value to a literal form, without adding quotes around a string.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
'string' - Represent an string value
static StringRecTy * get(RecordKeeper &RK)
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.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr size_t size() const
size - Get the string size.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
!op (X, Y, Z) - Combine two inits.
Init * Fold(Record *CurRec) const
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
TernaryOp getOpcode() 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 TernOpInit * get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type)
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
bool isRunning() const
Check if the timer is currently running.
void stopTimer()
Stop the timer.
void clear()
Clear the timer state.
void startTimer()
Start the timer running.
(Optionally) delegate resolving to a sub-resolver, and keep track whether there were unresolved refer...
bool foundUnresolved() const
Init * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
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.
Init * getCastTo(RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
RecTy * getFieldType(StringInit *FieldName) const override
This method is used to implement the FieldInit class.
RecordKeeper & getRecordKeeper() const
Get the record keeper that initialized this Init.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
RecTy * getType() const
Get the type of the Init as a RecTy.
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
!op (X) - Transform an init.
Init * getOperand() const
Init * Fold(Record *CurRec, bool IsFinal=false) const
UnaryOp getOpcode() 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
static UnOpInit * get(UnaryOp opc, Init *lhs, RecTy *Type)
std::string getAsString() const override
Convert this value to a literal form.
'?' - Represents an uninitialized value.
Init * getCastTo(RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
static UnsetInit * get(RecordKeeper &RK)
Get the singleton unset Init.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
Opcode{0} - Represent access to one bit of a variable or field.
unsigned getBitNum() const
std::string getAsString() const override
Convert this value to a literal form.
static VarBitInit * get(TypedInit *T, unsigned B)
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.
static VarDefInit * get(Record *Class, ArrayRef< Init * > Args)
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
ArrayRef< Init * > args() const
Init * getArg(unsigned i) const
std::string getAsString() const override
Convert this value to a literal form.
'Opcode' - Represent a reference to an entire variable object.
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...
Init * getNameInit() const
StringRef getName() const
std::string getAsString() const override
Convert this value to a literal form.
Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
static VarInit * get(StringRef VN, RecTy *T)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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 a range to a container.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
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)
RecTy * resolveTypes(RecTy *T1, RecTy *T2)
Find a common type that T1 and T2 convert to.
void CheckAssert(SMLoc Loc, Init *Condition, Init *Message)
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.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
This class represents the internal implementation of the RecordKeeper.
FoldingSet< BitsInit > TheBitsInitPool
DenseMap< std::pair< RecTy *, Init * >, VarInit * > TheVarInitPool
StringMap< StringInit *, BumpPtrAllocator & > StringInitCodePool
std::map< int64_t, IntInit * > TheIntInitPool
FoldingSet< FoldOpInit > TheFoldOpInitPool
FoldingSet< IsAOpInit > TheIsAOpInitPool
FoldingSet< DagInit > TheDagInitPool
FoldingSet< CondOpInit > TheCondOpInitPool
FoldingSet< BinOpInit > TheBinOpInitPool
StringRecTy SharedStringRecTy
FoldingSet< RecordRecTy > RecordTypePool
FoldingSet< VarDefInit > TheVarDefInitPool
DenseMap< std::pair< TypedInit *, unsigned >, VarBitInit * > TheVarBitInitPool
std::vector< BitsRecTy * > SharedBitsRecTys
FoldingSet< UnOpInit > TheUnOpInitPool
StringMap< StringInit *, BumpPtrAllocator & > StringInitStringPool
FoldingSet< TernOpInit > TheTernOpInitPool
BumpPtrAllocator Allocator
FoldingSet< ExistsOpInit > TheExistsOpInitPool
FoldingSet< ListInit > TheListInitPool
RecordKeeperImpl(RecordKeeper &RK)
DenseMap< std::pair< Init *, StringInit * >, FieldInit * > TheFieldInitPool