22#include "llvm/Config/llvm-config.h"
41#define DEBUG_TYPE "tblgen-records"
104#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
116 return Kind ==
RHS->getRecTyKind();
129 return BitsTy->getNumBits() == 1;
144 return "bits<" + utostr(Size) +
">";
149 return cast<BitsRecTy>(
RHS)->Size == Size;
156 return RHSb->Size == Size;
187 if (
const auto *ListTy = dyn_cast<ListRecTy>(
RHS))
208 ID.AddInteger(Classes.
size());
216 if (UnsortedClasses.
empty())
222 UnsortedClasses.
end());
224 return LHS->getNameInitAsString() <
RHS->getNameInitAsString();
236 for (
unsigned i = 0; i < Classes.
size(); ++i) {
237 for (
unsigned j = 0; j < Classes.
size(); ++j) {
240 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
247 std::uninitialized_copy(Classes.
begin(), Classes.
end(),
253 assert(Class &&
"unexpected null class");
254 return get(Class->getRecords(), Class);
263 return getClasses()[0]->getNameInitAsString();
265 std::string Str =
"{";
271 Str += R->getNameInitAsString();
279 return MySuperClass == Class ||
293 return isSubClassOf(TargetClass);
305 while (!Stack.empty()) {
306 Record *R = Stack.pop_back_val();
311 R->getDirectSuperClasses(Stack);
323 if (
RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
327 if (
T1->typeIsConvertibleTo(T2))
332 if (
ListRecTy *ListTy1 = dyn_cast<ListRecTy>(
T1)) {
333 if (
ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
335 ListTy2->getElementType());
348void Init::anchor() {}
350#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
355 if (
auto *TyInit = dyn_cast<TypedInit>(
this))
356 return TyInit->getType()->getRecordKeeper();
357 return cast<UnsetInit>(
this)->getRecordKeeper();
377 if (isa<BitRecTy>(Ty))
378 return const_cast<BitInit *
>(
this);
380 if (isa<IntRecTy>(Ty))
383 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
385 if (BRT->getNumBits() == 1)
394 ID.AddInteger(Range.size());
396 for (
Init *
I : Range)
412 std::uninitialized_copy(Range.begin(), Range.end(),
413 I->getTrailingObjects<
Init *>());
423 if (isa<BitRecTy>(Ty)) {
428 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
431 if (
getNumBits() != BRT->getNumBits())
return nullptr;
432 return const_cast<BitsInit *
>(
this);
435 if (isa<IntRecTy>(Ty)) {
437 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i)
438 if (
auto *Bit = dyn_cast<BitInit>(
getBit(i)))
439 Result |=
static_cast<int64_t
>(Bit->getValue()) << i;
452 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
455 NewBits[i] =
getBit(Bits[i]);
461 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
469 std::string Result =
"{ ";
470 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
471 if (i) Result +=
", ";
473 Result += Bit->getAsString();
477 return Result +
" }";
483 bool Changed =
false;
486 Init *CachedBitVarRef =
nullptr;
487 Init *CachedBitVarResolved =
nullptr;
489 for (
unsigned i = 0, e =
getNumBits(); i != e; ++i) {
491 Init *NewBit = CurBit;
493 if (
VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
494 if (CurBitVar->getBitVar() != CachedBitVarRef) {
495 CachedBitVarRef = CurBitVar->getBitVar();
498 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
499 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
505 if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
508 Changed |= CurBit != NewBit;
514 return const_cast<BitsInit *
>(
this);
525 return itostr(
Value);
530 return (NumBits >=
sizeof(
Value) * 8) ||
531 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
535 if (isa<IntRecTy>(Ty))
536 return const_cast<IntInit *
>(
this);
538 if (isa<BitRecTy>(Ty)) {
540 if (Val != 0 && Val != 1)
return nullptr;
544 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
551 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
565 for (
unsigned i = 0, e = Bits.size(); i != e; ++i) {
584 return "anonymous_" + utostr(
Value);
588 auto *Old =
const_cast<Init *
>(
static_cast<const Init *
>(
this));
589 auto *New = R.resolve(Old);
590 New = New ? New : Old;
592 if (
auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
593 return Anonymous->getNameInit();
601 auto &Entry = *InitMap.insert(std::make_pair(V,
nullptr)).first;
608 if (isa<StringRecTy>(Ty))
617 ID.AddInteger(Range.size());
618 ID.AddPointer(EltTy);
620 for (
Init *
I : Range)
633 assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
634 cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
639 std::uninitialized_copy(Range.begin(), Range.end(),
640 I->getTrailingObjects<
Init *>());
646 RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
655 if (
auto *LRT = dyn_cast<ListRecTy>(Ty)) {
661 bool Changed =
false;
662 RecTy *ElementType = LRT->getElementType();
664 if (
Init *CI =
I->convertInitializerTo(ElementType)) {
665 Elements.push_back(CI);
680 if (Elements.size() == 1) {
681 if (Elements[0] >=
size())
688 for (
unsigned Element : Elements) {
689 if (Element >=
size())
697 assert(i < NumValues &&
"List element index out of range!");
706 Resolved.reserve(
size());
707 bool Changed =
false;
710 Init *
E = CurElt->resolveReferences(R);
711 Changed |=
E != CurElt;
712 Resolved.push_back(
E);
717 return const_cast<ListInit *
>(
this);
721 for (
Init *Element : *
this) {
729 for (
Init *Element : *
this) {
737 std::string Result =
"[";
738 const char *sep =
"";
739 for (
Init *Element : *
this) {
749 return const_cast<OpInit*
>(
this);
755 ID.AddInteger(Opcode);
782 if (isa<StringRecTy>(
getType())) {
783 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
786 if (
DefInit *LHSd = dyn_cast<DefInit>(LHS))
789 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
793 }
else if (isa<RecordRecTy>(
getType())) {
795 if (!CurRec && !IsFinal)
797 assert(CurRec &&
"NULL pointer");
802 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
804 (Anonymous &&
Name == Anonymous->getNameInit())) {
813 Twine(
"Undefined reference to record: '") +
814 Name->getValue() +
"'\n");
822 Twine(
"Expected type '") +
836 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
842 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
843 assert(!LHSl->empty() &&
"Empty list in head");
844 return LHSl->getElement(0);
849 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
850 assert(!LHSl->empty() &&
"Empty list in tail");
853 return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
858 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
860 if (
DagInit *LHSd = dyn_cast<DagInit>(LHS))
862 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
867 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
869 if (
DagInit *LHSd = dyn_cast<DagInit>(LHS))
871 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
876 if (
DagInit *Dag = dyn_cast<DagInit>(LHS)) {
880 Twine(
"Expected type '") +
891 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
893 int64_t LHSv = LHSi->getValue();
896 "Illegal operation: logtwo is undefined "
897 "on arguments less than or equal to 0");
901 "Log of an int64_t must be smaller than INT64_MAX");
907 return const_cast<UnOpInit *
>(
this);
915 ->Fold(R.getCurrentRecord(), R.isFinal());
916 return const_cast<UnOpInit *
>(
this);
923 case NOT: Result =
"!not";
break;
924 case HEAD: Result =
"!head";
break;
925 case TAIL: Result =
"!tail";
break;
926 case SIZE: Result =
"!size";
break;
927 case EMPTY: Result =
"!empty";
break;
928 case GETDAGOP: Result =
"!getdagop";
break;
929 case LOG2 : Result =
"!logtwo";
break;
937 ID.AddInteger(Opcode);
964 Concat.append(I1->getValue());
972 if (
List->size() == 0)
980 for (
unsigned I = 1,
E =
List->size();
I <
E; ++
I) {
994 if (
List->size() == 0)
996 IntInit *Element = dyn_cast_or_null<IntInit>(
1002 for (
unsigned I = 1,
E =
List->size();
I <
E; ++
I) {
1004 IntInit *Element = dyn_cast_or_null<IntInit>(
1015 if (
const StringInit *I0s = dyn_cast<StringInit>(I0))
1016 if (
const StringInit *I1s = dyn_cast<StringInit>(I1))
1034 if (
const ListInit *LHSList = dyn_cast<ListInit>(
LHS))
1035 if (
const ListInit *RHSList = dyn_cast<ListInit>(
RHS))
1042 IntInit *LHSi = dyn_cast_or_null<IntInit>(
1044 IntInit *RHSi = dyn_cast_or_null<IntInit>(
1110 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1113 return std::nullopt;
1119 DagInit *LHSs = dyn_cast<DagInit>(LHS);
1120 DagInit *RHSs = dyn_cast<DagInit>(RHS);
1124 if ((!LOp && !isa<UnsetInit>(LHSs->
getOperator())) ||
1132 Init *Op = LOp ? LOp : ROp;
1138 for (
unsigned i = 0, e = LHSs->
getNumArgs(); i != e; ++i) {
1139 Args.push_back(LHSs->
getArg(i));
1142 for (
unsigned i = 0, e = RHSs->
getNumArgs(); i != e; ++i) {
1143 Args.push_back(RHSs->
getArg(i));
1151 ListInit *LHSs = dyn_cast<ListInit>(LHS);
1152 ListInit *RHSs = dyn_cast<ListInit>(RHS);
1171 ListInit *LHSs = dyn_cast<ListInit>(LHS);
1172 ListInit *RHSs = dyn_cast<ListInit>(RHS);
1175 for (
Init *EltLHS : *LHSs) {
1177 for (
Init *EltRHS : *RHSs) {
1178 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1186 Args.push_back(EltLHS);
1193 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1194 StringInit *RHSs = dyn_cast<StringInit>(RHS);
1201 StringInit *Delim = dyn_cast<StringInit>(RHS);
1202 if (
List && Delim) {
1204 if (isa<StringRecTy>(
List->getElementType()))
1224 DagInit *Dag = dyn_cast<DagInit>(LHS);
1225 DefInit *Op = dyn_cast<DefInit>(RHS);
1229 for (
unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
1230 Args.push_back(Dag->getArg(i));
1247 IntInit *LHSi = dyn_cast_or_null<IntInit>(
1249 IntInit *RHSi = dyn_cast_or_null<IntInit>(
1256 case ADD: Result = LHSv + RHSv;
break;
1257 case SUB: Result = LHSv - RHSv;
break;
1258 case MUL: Result = LHSv * RHSv;
break;
1262 "Illegal operation: division by zero");
1263 else if (LHSv ==
INT64_MIN && RHSv == -1)
1265 "Illegal operation: INT64_MIN / -1");
1267 Result = LHSv / RHSv;
1269 case AND: Result = LHSv & RHSv;
break;
1270 case OR: Result = LHSv | RHSv;
break;
1271 case XOR: Result = LHSv ^ RHSv;
break;
1273 case SRA: Result = LHSv >> RHSv;
break;
1288 if (LHS != lhs || RHS != rhs)
1290 ->Fold(R.getCurrentRecord());
1297 case CONCAT: Result =
"!con";
break;
1298 case ADD: Result =
"!add";
break;
1299 case SUB: Result =
"!sub";
break;
1300 case MUL: Result =
"!mul";
break;
1301 case DIV: Result =
"!div";
break;
1302 case AND: Result =
"!and";
break;
1303 case OR: Result =
"!or";
break;
1304 case XOR: Result =
"!xor";
break;
1305 case SHL: Result =
"!shl";
break;
1306 case SRA: Result =
"!sra";
break;
1307 case SRL: Result =
"!srl";
break;
1308 case EQ: Result =
"!eq";
break;
1309 case NE: Result =
"!ne";
break;
1310 case LE: Result =
"!le";
break;
1311 case LT: Result =
"!lt";
break;
1312 case GE: Result =
"!ge";
break;
1313 case GT: Result =
"!gt";
break;
1314 case LISTCONCAT: Result =
"!listconcat";
break;
1315 case LISTSPLAT: Result =
"!listsplat";
break;
1316 case LISTREMOVE: Result =
"!listremove";
break;
1317 case STRCONCAT: Result =
"!strconcat";
break;
1318 case INTERLEAVE: Result =
"!interleave";
break;
1319 case SETDAGOP: Result =
"!setdagop";
break;
1327 ID.AddInteger(Opcode);
1356 return RHS->resolveReferences(R);
1361 bool Change =
false;
1367 for (
unsigned int i = 0; i < MHSd->
getNumArgs(); ++i) {
1377 NewArgs.
push_back(std::make_pair(NewArg, ArgName));
1390 if (
DagInit *MHSd = dyn_cast<DagInit>(MHS))
1393 if (
ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1396 for (
Init *&Item : NewList) {
1398 if (NewItem != Item)
1411 if (
ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1414 for (
Init *Item : MHSl->getValues()) {
1419 dyn_cast_or_null<IntInit>(
Include->convertInitializerTo(
1421 if (IncludeInt->getValue())
1437 DefInit *LHSd = dyn_cast<DefInit>(LHS);
1438 VarInit *LHSv = dyn_cast<VarInit>(LHS);
1439 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1441 DefInit *MHSd = dyn_cast<DefInit>(MHS);
1442 VarInit *MHSv = dyn_cast<VarInit>(MHS);
1443 StringInit *MHSs = dyn_cast<StringInit>(MHS);
1445 DefInit *RHSd = dyn_cast<DefInit>(RHS);
1446 VarInit *RHSv = dyn_cast<VarInit>(RHS);
1447 StringInit *RHSs = dyn_cast<StringInit>(RHS);
1449 if (LHSd && MHSd && RHSd) {
1455 if (LHSv && MHSv && RHSv) {
1456 std::string Val = std::string(RHSv->
getName());
1458 Val = std::string(MHSv->
getName());
1461 if (LHSs && MHSs && RHSs) {
1462 std::string Val = std::string(RHSs->
getValue());
1464 std::string::size_type found;
1465 std::string::size_type idx = 0;
1467 found = Val.find(std::string(LHSs->
getValue()), idx);
1468 if (found == std::string::npos)
1493 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
1495 if (LHSi->getValue())
1503 ListInit *MHSl = dyn_cast<ListInit>(MHS);
1504 ListInit *RHSl = dyn_cast<ListInit>(RHS);
1505 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1506 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1508 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1511 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->
size() == RHSl->
size())) {
1514 for (
unsigned i = 0; i !=
Size; ++i) {
1517 if (!isa<StringInit>(
Name) && !isa<UnsetInit>(
Name))
1519 Children.emplace_back(
Node, dyn_cast<StringInit>(
Name));
1527 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1528 IntInit *MHSi = dyn_cast<IntInit>(MHS);
1529 IntInit *RHSi = dyn_cast<IntInit>(RHS);
1530 if (LHSs && MHSi && RHSi) {
1534 if (Start < 0 || Start > StringSize)
1536 Twine(
"!substr start position is out of range 0...") +
1537 std::to_string(StringSize) +
": " +
1538 std::to_string(Start));
1548 StringInit *LHSs = dyn_cast<StringInit>(LHS);
1549 StringInit *MHSs = dyn_cast<StringInit>(MHS);
1550 IntInit *RHSi = dyn_cast<IntInit>(RHS);
1551 if (LHSs && MHSs && RHSi) {
1554 if (Start < 0 || Start > SourceSize)
1556 Twine(
"!find start position is out of range 0...") +
1557 std::to_string(SourceSize) +
": " +
1558 std::to_string(Start));
1560 if (
I == std::string::npos)
1578 if (
Value->getValue())
1595 if (LHS != lhs || MHS != mhs || RHS != rhs)
1597 ->Fold(R.getCurrentRecord());
1603 bool UnquotedLHS =
false;
1605 case DAG: Result =
"!dag";
break;
1606 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
1607 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
1608 case IF: Result =
"!if";
break;
1609 case SUBST: Result =
"!subst";
break;
1610 case SUBSTR: Result =
"!substr";
break;
1611 case FIND: Result =
"!find";
break;
1613 return (Result +
"(" +
1620 ID.AddPointer(Start);
1624 ID.AddPointer(Expr);
1648 if (
ListInit *LI = dyn_cast<ListInit>(List)) {
1649 Init *Accum = Start;
1650 for (
Init *Elt : *LI) {
1669 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
1673 ->
Fold(R.getCurrentRecord());
1690 ID.AddPointer(Expr);
1713 if (
TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
1715 if (TI->getType()->typeIsConvertibleTo(CheckType))
1718 if (isa<RecordRecTy>(CheckType)) {
1752 ID.AddPointer(Expr);
1775 if (!CurRec && !IsFinal)
1780 auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->
getNameInit());
1782 (Anonymous &&
Name == Anonymous->getNameInit())) {
1809 if (Expr !=
NewExpr || R.isFinal())
1810 return get(CheckType,
NewExpr)->
Fold(R.getCurrentRecord(), R.isFinal());
1828 return Field->getType();
1839 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
1840 cast<BitsRecTy>(Ty)->getNumBits() == 1)
1848 if (!
T)
return nullptr;
1849 unsigned NumBits =
T->getNumBits();
1853 for (
unsigned Bit : Bits) {
1868 assert(!isa<TypedInit>(Converted) ||
1869 cast<TypedInit>(Converted)->
getType()->typeIsA(Ty));
1873 if (!
getType()->typeIsConvertibleTo(Ty))
1882 if (!
T)
return nullptr;
1884 if (Elements.size() == 1)
1888 ListInits.
reserve(Elements.size());
1889 for (
unsigned Element : Elements)
1916 return const_cast<VarInit*
>(
this);
1921 if (
Init *Val = R.resolve(VarName))
1923 return const_cast<VarInit *
>(
this);
1935 return TI->
getAsString() +
"{" + utostr(Bit) +
"}";
1955 return TI->
getAsString() +
"[" + utostr(Element) +
"]";
1966 if (NewTI != TI && isa<TypedInit>(NewTI))
1981 return R->getDefInit();
1985 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
1986 if (
getType()->typeIsConvertibleTo(RRT))
1987 return const_cast<DefInit *
>(
this);
1993 return RV->getType();
2002 ID.AddInteger(Args.size());
2003 ID.AddPointer(Class);
2005 for (
Init *
I : Args)
2009VarDefInit::VarDefInit(
Record *Class,
unsigned N)
2025 std::uninitialized_copy(Args.begin(), Args.end(),
2026 I->getTrailingObjects<
Init *>());
2035DefInit *VarDefInit::instantiate() {
2039 Class->
getLoc(), Records,
2041 Record *NewRec = NewRecOwner.get();
2054 for (
unsigned i = 0, e = TArgs.
size(); i != e; ++i) {
2056 R.set(TArgs[i],
getArg(i));
2067 for (
const auto &SCPair : SCs)
2072 Class->
getLoc().back()));
2076 Records.
addDef(std::move(NewRecOwner));
2089 bool Changed =
false;
2094 Init *NewArg =
Arg->resolveReferences(UR);
2096 Changed |= NewArg !=
Arg;
2102 return New->instantiate();
2114 Arg->resolveReferences(R);
2116 if (!R.foundUnresolved())
2117 return const_cast<VarDefInit *
>(
this)->instantiate();
2123 const char *sep =
"";
2127 Result +=
Arg->getAsString();
2129 return Result +
">";
2154 if (
DefInit *DI = dyn_cast<DefInit>(Rec)) {
2155 Record *Def = DI->getDef();
2158 Twine(
"Attempting to access field '") +
2160 Rec->
getAsString() +
"' is a forbidden self-reference");
2161 Init *FieldVal = Def->getValue(FieldName)->getValue();
2169 if (
DefInit *DI = dyn_cast<DefInit>(Rec)) {
2170 Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2179 const RecTy *ValType) {
2181 "Number of conditions and values must match!");
2182 ID.AddPointer(ValType);
2186 while (Case != CondRange.
end()) {
2187 ID.AddPointer(*Case++);
2188 ID.AddPointer(*Val++);
2194 ArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds),
2201 "Number of conditions and values must match!");
2212 totalSizeToAlloc<Init *>(2 * CondRange.
size()),
alignof(
BitsInit));
2215 std::uninitialized_copy(CondRange.
begin(), CondRange.
end(),
2216 I->getTrailingObjects<
Init *>());
2217 std::uninitialized_copy(ValRange.
begin(), ValRange.
end(),
2218 I->getTrailingObjects<
Init *>()+CondRange.
size());
2225 bool Changed =
false;
2229 Changed |= NewCase != Case;
2236 Changed |= NewVal != Val;
2248 for (
unsigned i = 0; i < NumConds; ++i) {
2252 if (
IntInit *CondI = dyn_cast_or_null<IntInit>(
2254 if (CondI->getValue())
2263 " does not have any true condition in:" +
2264 this->getAsString());
2270 if (!Case->isConcrete())
2274 if (!Val->isConcrete())
2282 if (!Case->isComplete())
2286 if (!Val->isConcrete())
2293 std::string Result =
"!cond(";
2300 return Result +
")";
2315 while (
Arg != ArgRange.
end()) {
2317 ID.AddPointer(*
Arg++);
2335 totalSizeToAlloc<Init *, StringInit *>(ArgRange.
size(), NameRange.
size()),
2338 std::uninitialized_copy(ArgRange.
begin(), ArgRange.
end(),
2339 I->getTrailingObjects<
Init *>());
2340 std::uninitialized_copy(NameRange.
begin(), NameRange.
end(),
2352 for (
const auto &
Arg :
args) {
2353 Args.push_back(
Arg.first);
2362 ArrayRef(getTrailingObjects<Init *>(), NumArgs),
2363 ArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
2367 if (
DefInit *DefI = dyn_cast<DefInit>(Val))
2368 return DefI->getDef();
2376 bool ArgsChanged =
false;
2378 Init *NewArg =
Arg->resolveReferences(R);
2380 ArgsChanged |= NewArg !=
Arg;
2384 if (Op != Val || ArgsChanged)
2387 return const_cast<DagInit *
>(
this);
2394 if (!Elt->isConcrete())
2407 for (
unsigned i = 1, e =
getNumArgs(); i != e; ++i) {
2412 return Result +
")";
2420 :
Name(
N), TyAndKind(
T, K) {
2422 assert(
Value &&
"Cannot create unset value for current type!");
2428 :
Name(
N), Loc(Loc), TyAndKind(
T, K) {
2430 assert(
Value &&
"Cannot create unset value for current type!");
2434 return cast<StringInit>(
getNameInit())->getValue();
2439 if (
auto *StrInit = dyn_cast<StringInit>(
Value)) {
2440 if (StrInit->hasCodeFormat())
2448 return TyAndKind.getPointer()->getAsString();
2459 if (!isa<BitsInit>(
Value)) {
2461 Bits.reserve(BTy->getNumBits());
2462 for (
unsigned I = 0,
E = BTy->getNumBits();
I <
E; ++
I)
2463 Bits.push_back(
Value->getBit(
I));
2468 return Value ==
nullptr;
2484 if (!isa<BitsInit>(
Value)) {
2486 Bits.reserve(BTy->getNumBits());
2487 for (
unsigned I = 0,
E = BTy->getNumBits();
I <
E; ++
I)
2488 Bits.push_back(
Value->getBit(
I));
2493 return Value ==
nullptr;
2499#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2511 if (PrintSem) OS <<
";\n";
2515 assert(Locs.size() == 1);
2516 ForwardDeclarationLocs.push_back(Locs.front());
2519 Locs.push_back(Loc);
2522void Record::checkName() {
2524 const TypedInit *TypedName = cast<const TypedInit>(Name);
2525 if (!isa<StringRecTy>(TypedName->
getType()))
2527 "' is not a string!");
2537 if (!CorrespondingDefInit) {
2538 CorrespondingDefInit =
2541 return CorrespondingDefInit;
2572 for (
int I = SCs.
size() - 1;
I >= 0; --
I) {
2573 const Record *SC = SCs[
I].first;
2574 if (SC == Superclass)
2576 I -= SC->getSuperClasses().size();
2585 while (!SCs.
empty()) {
2587 SCs = SCs.
drop_back(1 + SC->getSuperClasses().size());
2595 if (NewName != OldName) {
2602 if (SkipVal == &
Value)
2606 if (
Value.setValue(VR)) {
2608 if (
TypedInit *VRT = dyn_cast<TypedInit>(VR))
2610 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
2613 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
2614 Value.getNameInitAsString() +
"' of type '" +
2623 for (
auto &Assertion : Assertions) {
2624 Init *
Value = Assertion.Condition->resolveReferences(R);
2625 Assertion.Condition =
Value;
2626 Value = Assertion.Message->resolveReferences(R);
2627 Assertion.Message =
Value;
2638#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2643 OS << R.getNameInitAsString();
2646 if (!TArgs.
empty()) {
2648 bool NeedComma =
false;
2649 for (
const Init *TA : TArgs) {
2650 if (NeedComma) OS <<
", ";
2653 assert(RV &&
"Template argument record not found??");
2654 RV->
print(OS,
false);
2663 for (
const auto &SuperPair : SC)
2664 OS <<
" " << SuperPair.first->getNameInitAsString();
2668 for (
const RecordVal &Val : R.getValues())
2669 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
2671 for (
const RecordVal &Val : R.getValues())
2672 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
2682 "' does not have a field named `" + FieldName +
"'!\n");
2688 if (!R || !R->getValue())
2690 "' does not have a field named `" + FieldName +
"'!\n");
2691 return R->getValue();
2698 "' does not have a field named `" + FieldName +
"'!\n");
2702std::optional<StringRef>
2705 if (!R || !R->getValue())
2706 return std::nullopt;
2707 if (isa<UnsetInit>(R->getValue()))
2708 return std::nullopt;
2710 if (
StringInit *
SI = dyn_cast<StringInit>(R->getValue()))
2711 return SI->getValue();
2714 "Record `" +
getName() +
"', ` field `" + FieldName +
2715 "' exists but does not have a string initializer!");
2720 if (!R || !R->getValue())
2722 "' does not have a field named `" + FieldName +
"'!\n");
2724 if (
BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
2727 "' exists but does not have a bits value");
2732 if (!R || !R->getValue())
2734 "' does not have a field named `" + FieldName +
"'!\n");
2736 if (
ListInit *LI = dyn_cast<ListInit>(R->getValue()))
2739 "' exists but does not have a list value");
2745 std::vector<Record*> Defs;
2747 if (
DefInit *DI = dyn_cast<DefInit>(
I))
2748 Defs.push_back(DI->getDef());
2751 FieldName +
"' list is not entirely DefInit!");
2758 if (!R || !R->getValue())
2760 "' does not have a field named `" + FieldName +
"'!\n");
2762 if (
IntInit *II = dyn_cast<IntInit>(R->getValue()))
2763 return II->getValue();
2766 "' exists but does not have an int value: " +
2767 R->getValue()->getAsString());
2773 std::vector<int64_t> Ints;
2775 if (
IntInit *II = dyn_cast<IntInit>(
I))
2776 Ints.push_back(II->getValue());
2779 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2780 "' exists but does not have a list of ints value: " +
2786std::vector<StringRef>
2789 std::vector<StringRef> Strings;
2792 Strings.push_back(
SI->getValue());
2795 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2796 "' exists but does not have a list of strings value: " +
2804 if (!R || !R->getValue())
2806 "' does not have a field named `" + FieldName +
"'!\n");
2808 if (
DefInit *DI = dyn_cast<DefInit>(R->getValue()))
2809 return DI->getDef();
2811 FieldName +
"' does not have a def initializer!");
2816 if (!R || !R->getValue())
2818 "' does not have a field named `" + FieldName +
"'!\n");
2820 if (
DefInit *DI = dyn_cast<DefInit>(R->getValue()))
2821 return DI->getDef();
2822 if (isa<UnsetInit>(R->getValue()))
2825 FieldName +
"' does not have either a def initializer or '?'!");
2831 if (!R || !R->getValue())
2833 "' does not have a field named `" + FieldName +
"'!\n");
2835 if (
BitInit *BI = dyn_cast<BitInit>(R->getValue()))
2836 return BI->getValue();
2838 FieldName +
"' does not have a bit initializer!");
2843 if (!R || !R->getValue())
2845 "' does not have a field named `" + FieldName.
str() +
"'!\n");
2847 if (isa<UnsetInit>(R->getValue())) {
2852 if (
BitInit *BI = dyn_cast<BitInit>(R->getValue()))
2853 return BI->getValue();
2855 FieldName +
"' does not have a bit initializer!");
2860 if (!R || !R->getValue())
2862 "' does not have a field named `" + FieldName +
"'!\n");
2864 if (
DagInit *DI = dyn_cast<DagInit>(R->getValue()))
2867 FieldName +
"' does not have a dag initializer!");
2891 "unused template argument: " +
Twine(
Arg->getName()));
2896 : Impl(
std::make_unique<detail::RecordKeeperImpl>(*this)) {}
2899#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2904 OS <<
"------------- Classes -----------------\n";
2906 OS <<
"class " << *
C.second;
2908 OS <<
"------------- Defs -----------------\n";
2910 OS <<
"def " << *
D.second;
2925 if (LastTimer && LastTimer->
isRunning()) {
2929 BackendTimer =
false;
2933 LastTimer =
new Timer(
"",
Name, *TimingGroup);
2940 assert(LastTimer &&
"No phase timer was started");
2948 BackendTimer =
true;
2956 BackendTimer =
false;
2961std::vector<Record *>
2965 auto Pair = ClassRecordsMap.try_emplace(ClassName);
2969 return Pair.first->second;
2975 std::vector<Record *> Defs;
2977 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
2978 for (
const auto &ClassName : ClassNames) {
2985 for (
const auto &OneDef :
getDefs()) {
2987 return OneDef.second->isSubClassOf(Class);
2989 Defs.push_back(OneDef.second.get());
2995std::vector<Record *>
2998 : std::vector<Record *>();
3002 auto It = Map.find(VarName);
3003 if (It == Map.end())
3006 Init *
I = It->second.V;
3008 if (!It->second.Resolved && Map.size() > 1) {
3012 I =
I->resolveReferences(*
this);
3013 Map[VarName] = {
I,
true};
3020 Init *Val = Cache.lookup(VarName);
3028 if (!isa<UnsetInit>(RV->getValue())) {
3029 Val = RV->getValue();
3030 Stack.push_back(VarName);
3035 Stack.push_back(VarName);
3040 Cache[VarName] = Val;
3049 if (
I && !FoundUnresolved) {
3054 I->resolveReferences(Sub);
3055 FoundUnresolved |= Sub.FoundUnresolved;
3060 FoundUnresolved =
true;
3066 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.
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 M68kRelType getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel)
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 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 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.
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
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
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 *)
!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?
virtual Init * getCastTo(RecTy *Ty) const =0
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
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.
Init * convertInitListSlice(ArrayRef< unsigned > Elements) const override
This function is used to implement the list slice selection operator.
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.
Init * convertInitListSlice(ArrayRef< unsigned > Elements) const override
This function is used to implement the list slice selection operator.
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.
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)
List[4] - Represent access to one element of a var or field.
static VarListElementInit * get(TypedInit *T, unsigned E)
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.
unsigned getElementNum() const
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)
Wrapper function around std::find to detect if an element exists in a container.
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
DenseMap< std::pair< TypedInit *, unsigned >, VarListElementInit * > TheVarListElementInitPool