22#include "llvm/Config/llvm-config.h"
43#define DEBUG_TYPE "tblgen-records"
123 OS <<
"Total allocator memory = " <<
Allocator.getTotalMemory() <<
"\n\n";
125 OS <<
"Number of records instantiated = " <<
LastRecordID <<
'\n';
126 OS <<
"Number of anonymous records = " <<
AnonCounter <<
'\n';
133#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
139 ListTy =
new (RK.getImpl().Allocator)
ListRecTy(
this);
144 assert(RHS &&
"NULL pointer");
145 return Kind == RHS->getRecTyKind();
151 return &RK.getImpl().SharedBitRecTy;
158 return BitsTy->getNumBits() == 1;
168 Ty =
new (RKImpl.
Allocator) BitsRecTy(RK, Sz);
173 return "bits<" +
utostr(Size) +
">";
184 return &RK.getImpl().SharedIntRecTy;
193 return &RK.getImpl().SharedStringRecTy;
206 return "list<" + ElementTy->getAsString() +
">";
211 return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
222 return &RK.getImpl().SharedDagRecTy;
231 ID.AddInteger(Classes.
size());
232 for (
const Record *R : Classes)
237 : RecTy(RecordRecTyKind, RK), NumClasses(Classes.
size()) {
244 if (UnsortedClasses.
empty())
251 return LHS->getNameInitAsString() < RHS->getNameInitAsString();
258 if (RecordRecTy *Ty = ThePool.
lookup(ID, Token))
263 for (
unsigned i = 0; i < Classes.
size(); ++i) {
264 for (
unsigned j = 0; j < Classes.
size(); ++j) {
267 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
273 RecordRecTy *Ty =
new (Mem) RecordRecTy(RK, Classes);
274 ThePool.
insert(Ty, Token);
279 assert(Class &&
"unexpected null class");
280 return get(Class->getRecords(), {Class});
289 return getClasses()[0]->getNameInitAsString();
291 std::string Str =
"{";
295 Str += R->getNameInitAsString();
303 return MySuperClass == Class || MySuperClass->
isSubClassOf(Class);
316 return isSubClassOf(TargetClass);
329 while (!Stack.empty()) {
330 const Record *R = Stack.pop_back_val();
332 if (T2->isSubClassOf(R))
350 assert(T1 !=
nullptr &&
"Invalid record type");
351 if (T1->typeIsConvertibleTo(T2))
354 assert(T2 !=
nullptr &&
"Invalid record type");
355 if (T2->typeIsConvertibleTo(T1))
360 const RecTy *NewType =
361 resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());
374void Init::anchor() {}
376#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
382 return TyInit->getType()->getRecordKeeper();
384 return ArgInit->getRecordKeeper();
389 return &RK.getImpl().TheUnsetInit;
400 auto I = Aux.index();
403 ID.AddInteger(std::get<ArgumentInit::Positional>(Aux));
405 ID.AddPointer(std::get<ArgumentInit::Named>(Aux));
406 ID.AddPointer(
Value);
429 const Init *NewValue = Value->resolveReferences(R);
430 if (NewValue != Value)
449 if (BRT->getNumBits() == 1)
458 ID.AddInteger(
Range.size());
481 BitsInit *
I =
new (Mem) BitsInit(RK, Bits);
499 if (
getNumBits() != BRT->getNumBits())
return nullptr;
516 Result |=
static_cast<int64_t
>(Bit->getValue()) << Idx;
526 Result |=
static_cast<int64_t
>(Bit->getValue()) << Idx;
534 for (
auto [Bit, NewBit] :
zip_equal(Bits, NewBits)) {
553 std::string Result =
"{ ";
558 Result += Bit->getAsString();
562 return Result +
" }";
571 const Init *CachedBitVarRef =
nullptr;
572 const Init *CachedBitVarResolved =
nullptr;
578 if (CurBitVar->getBitVar() != CachedBitVarRef) {
579 CachedBitVarRef = CurBitVar->getBitVar();
582 assert(CachedBitVarResolved &&
"Unresolved bitvar reference");
583 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
586 NewBit = CurBit->resolveReferences(R)->getBit(0);
603 I =
new (RK.
getImpl().Allocator) IntInit(RK, V);
613 return (NumBits >=
sizeof(
Value) * 8) ||
614 (
Value >> NumBits == 0) || (
Value >> (NumBits-1) == -1);
623 if (Val != 0 && Val != 1)
return nullptr;
634 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
647 for (
auto [Bit, NewBit] :
zip_equal(Bits, NewBits)) {
657 return new (RK.
getImpl().Allocator) AnonymousNameInit(RK, V);
665 return "anonymous_" +
utostr(Value);
670 auto *New = R.resolve(Old);
671 New = New ? New : Old;
674 return Anonymous->getNameInit();
683 auto &Entry = *InitMap.
try_emplace(V,
nullptr).first;
685 Entry.second =
new (RKImpl.
Allocator) StringInit(RK, Entry.getKey(), Fmt);
698 NumElements(Elements.
size()) {
703 const RecTy *EltTy) {
714 ListInit *
I =
new (Mem) ListInit(Elements, EltTy);
725 Elements.reserve(
size());
730 const RecTy *ElementType = LRT->getElementType();
732 if (
const Init *CI =
I->convertInitializerTo(ElementType)) {
733 Elements.push_back(CI);
758 Resolved.reserve(
size());
764 Resolved.push_back(E);
783 std::string Result =
"[";
785 for (
const Init *Element : *
this) {
813 if (LHS->isConcrete()) {
818 OS << *Def->getDef();
858 (Anonymous && Name == Anonymous->getNameInit())) {
865 auto PrintFatalErrorHelper = [CurRec](
const Twine &
T) {
874 PrintFatalErrorHelper(
Twine(
"Undefined reference to record: '") +
875 Name->getValue() +
"'\n");
882 PrintFatalErrorHelper(
Twine(
"Expected type '") +
898 if (LHS->isConcrete())
910 assert(!LHSl->empty() &&
"Empty list in head");
911 return LHSl->getElement(0);
917 assert(!LHSl->empty() &&
"Empty list in tail");
921 LHSl->getElementType());
948 if (!TI->getType()->typeIsA(
getType())) {
954 return Dag->getOperator();
961 return Dag->getName();
968 int64_t LHSv = LHSi->getValue();
971 "Illegal operation: logtwo is undefined "
972 "on arguments less than or equal to 0");
976 "Log of an int64_t must be smaller than INT64_MAX");
990 [](
const ListInit *
List) -> std::optional<std::vector<const Init *>> {
991 std::vector<const Init *> Flattened;
993 for (
const Init *InnerInit :
List->getElements()) {
1002 auto Flattened = Flatten(LHSList);
1004 return ListInit::get(*Flattened, InnerListTy->getElementType());
1016 ->Fold(R.getCurrentRecord(), R.isFinal());
1024 case NOT: Result =
"!not";
break;
1025 case HEAD: Result =
"!head";
break;
1026 case TAIL: Result =
"!tail";
break;
1027 case SIZE: Result =
"!size";
break;
1028 case EMPTY: Result =
"!empty";
break;
1029 case GETDAGOP: Result =
"!getdagop";
break;
1031 Result =
"!getdagopname";
1033 case LOG2 : Result =
"!logtwo";
break;
1035 Result =
"!listflatten";
1041 Result =
"!tolower";
1044 Result =
"!toupper";
1047 Result =
"!initialized";
1050 return Result +
"(" + LHS->getAsString() +
")";
1057 if (
const BinOpInit *
I =
1069 Concat.append(I1->getValue());
1077 if (List->size() == 0)
1085 for (
const Init *Elem : List->getElements().drop_front()) {
1090 Result.append(Element->getValue());
1099 if (List->size() == 0)
1102 List->getElement(0)->convertInitializerTo(
IntRecTy::get(RK)));
1107 for (
const Init *Elem : List->getElements().drop_front()) {
1113 Result.append(Element->getAsString());
1146 const Init *RHS)
const {
1157 Result = LHSi->getValue() == RHSi->getValue();
1160 Result = LHSi->getValue() != RHSi->getValue();
1163 Result = LHSi->getValue() <= RHSi->getValue();
1166 Result = LHSi->getValue() < RHSi->getValue();
1169 Result = LHSi->getValue() >= RHSi->getValue();
1172 Result = LHSi->getValue() > RHSi->getValue();
1188 Result = LHSs->getValue() == RHSs->getValue();
1191 Result = LHSs->getValue() != RHSs->getValue();
1194 Result = LHSs->getValue() <= RHSs->getValue();
1197 Result = LHSs->getValue() < RHSs->getValue();
1200 Result = LHSs->getValue() >= RHSs->getValue();
1203 Result = LHSs->getValue() > RHSs->getValue();
1216 return (
Opc ==
EQ) ? LHSd == RHSd : LHSd != RHSd;
1219 return std::nullopt;
1222static std::optional<unsigned>
1226 int64_t Pos = Idx->getValue();
1230 (
Twine(
"index ") + std::to_string(Pos) +
Twine(
" is negative")).str();
1231 return std::nullopt;
1233 if (Pos >= Dag->getNumArgs()) {
1235 Error = (
Twine(
"index ") + std::to_string(Pos) +
1236 " is out of range (dag has " +
1237 std::to_string(Dag->getNumArgs()) +
" arguments)")
1239 return std::nullopt;
1246 auto ArgNo = Dag->getArgNo(Name->getValue());
1249 Error = (
Twine(
"key '") + Name->getValue() +
Twine(
"' is not found")).str();
1250 return std::nullopt;
1266 if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1268 LHSs->getAsString() +
"' vs. '" + RHSs->getAsString() +
1271 const Init *
Op = LOp ? LOp : ROp;
1279 const auto *NameInit = LHSs->getName();
1281 NameInit = RHSs->getName();
1295 StringRef RegexStr = RegexInit->getValue();
1297 if (!Matcher.isValid())
1301 Matcher.match(StrInit->getValue()));
1318 if (
Count->getValue() < 0)
1331 for (
const Init *EltLHS : *LHSs) {
1333 for (
const Init *EltRHS : *RHSs) {
1334 if (std::optional<bool> Result =
CompareInit(
EQ, EltLHS, EltRHS)) {
1342 Args.push_back(EltLHS);
1351 if (!TheList || !Idx)
1353 auto i = Idx->getValue();
1354 if (i < 0 || i >= (ssize_t)TheList->size())
1356 return TheList->getElement(i);
1361 if (!TheList || !SliceIdxs)
1364 Args.reserve(SliceIdxs->size());
1365 for (
auto *
I : *SliceIdxs) {
1369 auto i =
II->getValue();
1370 if (i < 0 || i >= (ssize_t)TheList->size())
1372 Args.push_back(TheList->getElement(i));
1382 int64_t Start = LHSi->getValue();
1383 int64_t End = RHSi->getValue();
1389 Args.reserve(End - Start + 1);
1390 for (
auto i = Start; i <= End; ++i)
1394 Args.reserve(Start - End + 1);
1395 for (
auto i = Start; i >= End; --i)
1398 }
else if (Start < End) {
1400 Args.reserve(End - Start);
1401 for (
auto i = Start; i < End; ++i)
1418 if (
List && Delim) {
1447 assert(*ArgNo < Dag->getNumArgs());
1449 const Init *Arg = Dag->getArg(*ArgNo);
1451 if (!TI->getType()->typeIsConvertibleTo(
getType()))
1461 int64_t Pos = Idx->getValue();
1462 if (Pos < 0 || Pos >= Dag->getNumArgs()) {
1465 Twine(
"!getdagname index is out of range 0...") +
1466 std::to_string(Dag->getNumArgs() - 1) +
": " +
1467 std::to_string(Pos));
1469 const Init *ArgName = Dag->getArgName(Pos);
1488 Dag->getArgNames());
1506 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
1510 case ADD: Result = LHSv + RHSv;
break;
1511 case SUB: Result = LHSv - RHSv;
break;
1512 case MUL: Result = LHSv * RHSv;
break;
1516 "Illegal operation: division by zero");
1517 else if (LHSv ==
INT64_MIN && RHSv == -1)
1519 "Illegal operation: INT64_MIN / -1");
1521 Result = LHSv / RHSv;
1523 case AND: Result = LHSv & RHSv;
break;
1524 case OR: Result = LHSv | RHSv;
break;
1525 case XOR: Result = LHSv ^ RHSv;
break;
1527 if (RHSv < 0 || RHSv >= 64)
1529 "Illegal operation: out of bounds shift");
1530 Result = (uint64_t)LHSv << (uint64_t)RHSv;
1533 if (RHSv < 0 || RHSv >= 64)
1535 "Illegal operation: out of bounds shift");
1536 Result = LHSv >> (uint64_t)RHSv;
1539 if (RHSv < 0 || RHSv >= 64)
1541 "Illegal operation: out of bounds shift");
1542 Result = (uint64_t)LHSv >> (uint64_t)RHSv;
1568 if ((
Opc ==
AND && !LHSi->getValue()) ||
1569 (
Opc ==
OR && LHSi->getValue() == -1))
1576 if (LHS != NewLHS || RHS != NewRHS)
1578 ->Fold(R.getCurrentRecord());
1587 return LHS->getAsString() +
"[" + RHS->getAsString() +
"]";
1589 return LHS->getAsString() +
"..." + RHS->getAsString();
1590 case CONCAT: Result =
"!con";
break;
1594 case ADD: Result =
"!add";
break;
1595 case SUB: Result =
"!sub";
break;
1596 case MUL: Result =
"!mul";
break;
1597 case DIV: Result =
"!div";
break;
1598 case AND: Result =
"!and";
break;
1599 case OR: Result =
"!or";
break;
1600 case XOR: Result =
"!xor";
break;
1601 case SHL: Result =
"!shl";
break;
1602 case SRA: Result =
"!sra";
break;
1603 case SRL: Result =
"!srl";
break;
1604 case EQ: Result =
"!eq";
break;
1605 case NE: Result =
"!ne";
break;
1606 case LE: Result =
"!le";
break;
1607 case LT: Result =
"!lt";
break;
1608 case GE: Result =
"!ge";
break;
1609 case GT: Result =
"!gt";
break;
1610 case LISTCONCAT: Result =
"!listconcat";
break;
1611 case LISTSPLAT: Result =
"!listsplat";
break;
1613 Result =
"!listremove";
1615 case STRCONCAT: Result =
"!strconcat";
break;
1616 case INTERLEAVE: Result =
"!interleave";
break;
1617 case SETDAGOP: Result =
"!setdagop";
break;
1619 Result =
"!setdagopname";
1625 Result =
"!getdagname";
1628 return Result +
"(" + LHS->getAsString() +
", " + RHS->getAsString() +
")";
1649 return RHS->resolveReferences(R);
1654 bool Change =
false;
1688 for (
const Init *&Item : NewList) {
1690 if (NewItem != Item)
1707 for (
const Init *Item : MHSl->getElements()) {
1711 if (
const auto *IncludeInt =
1714 if (IncludeInt->getValue())
1733 using KV = std::pair<const Init *, const Init *>;
1736 for (
const Init *Item : MHSl->getElements()) {
1743 if (KeyedList.
empty())
1750 for (
auto &[
Key, Item] : KeyedList) {
1772 for (
auto &[
Key, Item] : KeyedList)
1773 Result.push_back(Item);
1793 if (LHSd && MHSd && RHSd) {
1794 const Record *Val = RHSd->getDef();
1795 if (LHSd->getAsString() == RHSd->getAsString())
1796 Val = MHSd->getDef();
1799 if (LHSv && MHSv && RHSv) {
1800 std::string Val = RHSv->getName().str();
1801 if (LHSv->getAsString() == RHSv->getAsString())
1802 Val = MHSv->getName().str();
1805 if (LHSs && MHSs && RHSs) {
1806 std::string Val = RHSs->getValue().str();
1808 std::string::size_type Idx = 0;
1810 std::string::size_type Found = Val.find(LHSs->getValue(), Idx);
1811 if (Found == std::string::npos)
1813 Val.replace(Found, LHSs->getValue().size(), MHSs->getValue().str());
1814 Idx = Found + MHSs->getValue().size();
1843 if (LHSi->getValue())
1859 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
1861 unsigned Size = MHSl ? MHSl->size() : RHSl->size();
1862 for (
unsigned i = 0; i !=
Size; ++i) {
1878 if (!LHSi || !MHSi || !RHSi)
1881 auto Start = LHSi->getValue();
1882 auto End = MHSi->getValue();
1883 auto Step = RHSi->getValue();
1888 if (Start < End && Step > 0) {
1889 Args.reserve((End - Start) / Step);
1890 for (
auto I = Start;
I < End;
I += Step)
1892 }
else if (Start > End && Step < 0) {
1893 Args.reserve((Start - End) / -Step);
1894 for (
auto I = Start;
I > End;
I += Step)
1906 if (LHSs && MHSi && RHSi) {
1907 int64_t StringSize = LHSs->getValue().size();
1908 int64_t Start = MHSi->getValue();
1909 int64_t
Length = RHSi->getValue();
1910 if (Start < 0 || Start > StringSize)
1912 Twine(
"!substr start position is out of range 0...") +
1913 std::to_string(StringSize) +
": " +
1914 std::to_string(Start));
1927 if (LHSs && MHSs && RHSi) {
1928 int64_t SourceSize = LHSs->getValue().size();
1929 int64_t Start = RHSi->getValue();
1930 if (Start < 0 || Start > SourceSize)
1932 Twine(
"!find start position is out of range 0...") +
1933 std::to_string(SourceSize) +
": " +
1934 std::to_string(Start));
1935 auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1936 if (
I == std::string::npos)
1951 assert(*ArgNo < Dag->getNumArgs());
1955 return DagInit::get(Dag->getOperator(), Dag->getName(), Args,
1956 Dag->getArgNames());
1969 assert(*ArgNo < Dag->getNumArgs());
1973 return DagInit::get(Dag->getOperator(), Dag->getName(), Dag->getArgs(),
1990 if (
Value->getValue())
1991 return MHS->resolveReferences(R);
1992 return RHS->resolveReferences(R);
2007 if (LHS != lhs || MHS != mhs || RHS != rhs)
2009 ->Fold(R.getCurrentRecord());
2015 bool UnquotedLHS =
false;
2017 case DAG: Result =
"!dag";
break;
2018 case FILTER: Result =
"!filter"; UnquotedLHS =
true;
break;
2019 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
2024 case IF: Result =
"!if";
break;
2028 case SUBST: Result =
"!subst";
break;
2029 case SUBSTR: Result =
"!substr";
break;
2030 case FIND: Result =
"!find";
break;
2032 Result =
"!setdagarg";
2035 Result =
"!setdagname";
2038 return (Result +
"(" +
2039 (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
2040 ", " + MHS->getAsString() +
", " + RHS->getAsString() +
")");
2046 ID.AddPointer(Start);
2047 ID.AddPointer(List);
2050 ID.AddPointer(Expr);
2051 ID.AddPointer(
Type);
2065 FoldOpInit *
I =
new (RK.
Allocator) FoldOpInit(Start, List, A, B, Expr,
Type);
2076 const Init *Accum = Start;
2077 for (
const Init *Elt : *LI) {
2094 const Init *
NewExpr = Expr->resolveReferences(SR);
2096 if (Start == NewStart && List == NewList && Expr ==
NewExpr)
2100 ->
Fold(R.getCurrentRecord());
2110 return (
Twine(
"!foldl(") + Start->getAsString() +
", " + List->getAsString() +
2111 ", " + A->getAsUnquotedString() +
", " + B->getAsUnquotedString() +
2112 ", " + Expr->getAsString() +
")")
2119 ID.AddPointer(Expr);
2132 IsAOpInit *
I =
new (RK.
Allocator) IsAOpInit(CheckType, Expr);
2144 if (TI->getType()->typeIsConvertibleTo(CheckType))
2151 if ((!CheckType->typeIsConvertibleTo(TI->getType()) &&
2152 Expr->isConcrete()) ||
2175 return (
Twine(
"!isa<") + CheckType->getAsString() +
">(" +
2176 Expr->getAsString() +
")")
2183 ID.AddPointer(Expr);
2196 ExistsOpInit *
I =
new (RK.
Allocator) ExistsOpInit(CheckType, Expr);
2208 const Record *
D = CheckType->getRecordKeeper().getDef(Name->getValue());
2212 D->getDefInit()->getType()->typeIsA(CheckType));
2220 (Anonymous && Name == Anonymous->getNameInit())) {
2239 if (Expr !=
NewExpr || R.isFinal())
2240 return get(CheckType,
NewExpr)->
Fold(R.getCurrentRecord(), R.isFinal());
2249 return (
Twine(
"!exists<") + CheckType->getAsString() +
">(" +
2250 Expr->getAsString() +
")")
2256 ID.AddPointer(
Type);
2257 ID.AddPointer(
Regex);
2261 const Init *Regex) {
2270 InstancesOpInit *
I =
new (RK.
Allocator) InstancesOpInit(Type, Regex);
2280 if (CurRec && !IsFinal)
2287 StringRef RegexStr = RegexInit->getValue();
2289 if (!Matcher.isValid())
2295 if (Matcher.match(Def->getName()))
2303 if (Regex != NewRegex || R.isFinal())
2304 return get(Type, NewRegex)->
Fold(R.getCurrentRecord(), R.isFinal());
2309 return "!instances<" + Type->
getAsString() +
">(" + Regex->getAsString() +
2317 return Field->getType();
2337 if (!
T)
return nullptr;
2338 unsigned NumBits =
T->getNumBits();
2342 for (
unsigned Bit : Bits) {
2362 if (!
getType()->typeIsConvertibleTo(Ty))
2383 return NameString->getValue();
2393 if (
const Init *Val = R.resolve(VarName))
2407 return TI->getAsString() +
"{" +
utostr(Bit) +
"}";
2411 const Init *
I = TI->resolveReferences(R);
2418DefInit::DefInit(
const Record *
D)
2423 if (
getType()->typeIsConvertibleTo(RRT))
2430 return RV->getType();
2438 ID.AddInteger(Args.size());
2439 ID.AddPointer(Class);
2441 for (
const Init *
I : Args)
2464 VarDefInit *
I =
new (Mem) VarDefInit(Loc, Class, Args);
2473const DefInit *VarDefInit::instantiate() {
2478 auto NewRecOwner = std::make_unique<Record>(
2480 Record *NewRec = NewRecOwner.get();
2483 for (
const RecordVal &Val : Class->getValues())
2496 for (
const Init *Arg : TArgs) {
2501 for (
auto *Arg :
args()) {
2502 if (Arg->isPositional())
2503 R.set(TArgs[Arg->getIndex()], Arg->getValue());
2505 R.set(Arg->getName(), Arg->getValue());
2512 Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
2516 Records.addDef(std::move(NewRecOwner));
2542 return const_cast<VarDefInit *
>(New)->instantiate();
2554 Arg->resolveReferences(R);
2556 if (!R.foundUnresolved())
2557 return const_cast<VarDefInit *
>(
this)->instantiate();
2562 std::string Result = Class->getNameInitAsString() +
"<";
2566 Result += Arg->getAsString();
2568 return Result +
">";
2594 const Record *Def = DI->getDef();
2597 Twine(
"Attempting to access field '") +
2598 FieldName->getAsUnquotedString() +
"' of '" +
2599 Rec->getAsString() +
"' is a forbidden self-reference");
2600 const Init *FieldVal = Def->getValue(FieldName)->getValue();
2609 const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
2618 const RecTy *ValType) {
2620 "Number of conditions and values must match!");
2621 ID.AddPointer(ValType);
2623 for (
const auto &[
Cond, Val] :
zip(Conds, Vals)) {
2624 ID.AddPointer(
Cond);
2645 "Number of conditions and values must match!");
2657 CondOpInit *
I =
new (Mem) CondOpInit(Conds,
Values, Ty);
2668 const Init *NewCond =
Cond->resolveReferences(R);
2679 if (NewCondVal->getValue()) {
2699 if (CondI->getValue())
2700 return Val->convertInitializerTo(
getValType());
2708 " does not have any true condition in:" +
2709 this->getAsString());
2715 return std::get<0>(Pair)->isConcrete() && std::get<1>(Pair)->isConcrete();
2721 return std::get<0>(Pair)->isComplete() && std::get<1>(Pair)->isComplete();
2726 std::string Result =
"!cond(";
2730 Result +=
Cond->getAsString() +
": ";
2731 Result += Val->getAsString();
2733 return Result +
")";
2748 for (
auto [Arg, Name] :
zip_equal(Args, ArgNames)) {
2750 ID.AddPointer(Name);
2758 ValName(VN), NumArgs(
Args.
size()) {
2767 "Number of DAG args and arg names must match!");
2779 Args.size(), ArgNames.
size()),
2781 DagInit *
I =
new (Mem) DagInit(V, VN, Args, ArgNames);
2788 ArrayRef<std::pair<const Init *, const StringInit *>> ArgAndNames) {
2800 return DefI->getDef();
2808 return ArgName && ArgName->
getValue() == Name;
2810 if (It == ArgNames.
end())
2811 return std::nullopt;
2812 return std::distance(ArgNames.
begin(), It);
2818 bool ArgsChanged =
false;
2822 ArgsChanged |= NewArg != Arg;
2825 const Init *
Op = Val->resolveReferences(R);
2826 if (
Op != Val || ArgsChanged)
2833 if (!Val->isConcrete())
2839 std::string Result =
"(" + Val->getAsString();
2841 Result +=
":$" + ValName->getAsUnquotedString();
2847 Result += Arg->getAsString();
2849 Result +=
":$" + Name->getAsUnquotedString();
2852 return Result +
")";
2860 : Name(
N), TyAndKind(
T, K) {
2862 assert(Value &&
"Cannot create unset value for current type!");
2868 : Name(
N), Loc(Loc), TyAndKind(
T, K) {
2870 assert(Value &&
"Cannot create unset value for current type!");
2880 if (StrInit->hasCodeFormat())
2888 return TyAndKind.getPointer()->getAsString();
2909 for (
unsigned I = 0, E = BTy->getNumBits();
I < E; ++
I)
2910 Bits[
I] = Value->getBit(
I);
2924#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2935 if (PrintSem) OS <<
";\n";
2939 assert(Locs.size() == 1);
2940 ForwardDeclarationLocs.push_back(Locs.front());
2943 Locs.push_back(
Loc);
2946void Record::checkName() {
2951 "' is not a string!");
2961 if (!CorrespondingDefInit) {
2962 CorrespondingDefInit =
2963 new (TrackedRecords.getImpl().Allocator)
DefInit(
this);
2965 return CorrespondingDefInit;
2991 if (NewName != OldName) {
2998 if (SkipVal == &
Value)
3002 if (
Value.setValue(VR)) {
3006 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
3009 Twine(
"Invalid value ") +
Type +
"found when setting field '" +
3010 Value.getNameInitAsString() +
"' of type '" +
3020 const Init *
Value = Assertion.Condition->resolveReferences(R);
3021 Assertion.Condition =
Value;
3022 Value = Assertion.Message->resolveReferences(R);
3023 Assertion.Message =
Value;
3027 const Init *
Value = Dump.Message->resolveReferences(R);
3028 Dump.Message =
Value;
3039#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3044 OS << R.getNameInitAsString();
3047 if (!TArgs.
empty()) {
3050 for (
const Init *TA : TArgs) {
3052 assert(RV &&
"Template argument record not found??");
3054 RV->
print(OS,
false);
3060 std::vector<const Record *> SCs = R.getSuperClasses();
3063 for (
const Record *SC : SCs)
3064 OS <<
" " << SC->getNameInitAsString();
3068 for (
const RecordVal &Val : R.getValues())
3069 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3071 for (
const RecordVal &Val : R.getValues())
3072 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
3082 "' does not have a field named `" + FieldName +
"'!\n");
3088 if (!R || !R->getValue())
3090 "' does not have a field named `" + FieldName +
"'!\n");
3091 return R->getValue();
3097 return SI->getValue();
3099 "' exists but does not have a string value");
3102std::optional<StringRef>
3105 if (!R || !R->getValue())
3106 return std::nullopt;
3108 return std::nullopt;
3111 return SI->getValue();
3114 "Record `" +
getName() +
"', ` field `" + FieldName +
3115 "' exists but does not have a string initializer!");
3123 "' exists but does not have a bits value");
3131 "' exists but does not have a list value");
3134std::vector<const Record *>
3137 std::vector<const Record *> Defs;
3138 for (
const Init *
I :
List->getElements()) {
3140 Defs.push_back(DI->getDef());
3144 "' list is not entirely DefInit!");
3152 return II->getValue();
3155 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3156 "' exists but does not have an int value: " +
I->getAsString());
3162 std::vector<int64_t> Ints;
3163 for (
const Init *
I :
List->getElements()) {
3165 Ints.push_back(
II->getValue());
3168 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3169 "' exists but does not have a list of ints value: " +
3175std::vector<StringRef>
3178 std::vector<StringRef> Strings;
3179 for (
const Init *
I :
List->getElements()) {
3181 Strings.push_back(
SI->getValue());
3184 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
3185 "' exists but does not have a list of strings value: " +
3194 return DI->getDef();
3196 FieldName +
"' does not have a def initializer!");
3202 return DI->getDef();
3206 FieldName +
"' does not have either a def initializer or '?'!");
3212 return BI->getValue();
3214 FieldName +
"' does not have a bit initializer!");
3225 return BI->getValue();
3227 FieldName +
"' does not have a bit initializer!");
3235 FieldName +
"' does not have a dag initializer!");
3246 bool AnyFailed =
false;
3250 AnyFailed |=
CheckAssert(Assertion.Loc, Condition, Message);
3258 PrintError(
this,
"assertion failed in this record");
3266 const Init *Message = Dump.Message->resolveReferences(R);
3282 : Impl(
std::make_unique<
detail::RecordKeeperImpl>(*this)),
3287#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3292 OS <<
"------------- Classes -----------------\n";
3294 OS <<
"class " << *
C;
3296 OS <<
"------------- Defs -----------------\n";
3312 auto [Iter, Inserted] = Cache.try_emplace(ClassName.
str());
3315 return Iter->second;
3318std::vector<const Record *>
3321 std::vector<const Record *> Defs;
3323 assert(ClassNames.
size() > 0 &&
"At least one class must be passed.");
3324 for (
StringRef ClassName : ClassNames) {
3331 for (
const auto &OneDef :
getDefs()) {
3333 return OneDef.second->isSubClassOf(Class);
3335 Defs.push_back(OneDef.second.get());
3349 Impl->dumpAllocationStats(OS);
3353 auto It = Map.find(VarName);
3354 if (It == Map.end())
3357 const Init *
I = It->second.V;
3359 if (!It->second.Resolved && Map.size() > 1) {
3363 I =
I->resolveReferences(*
this);
3364 Map[VarName] = {
I,
true};
3371 const Init *Val = Cache.lookup(VarName);
3380 Val = RV->getValue();
3381 Stack.push_back(VarName);
3386 Stack.push_back(VarName);
3391 Cache[VarName] = Val;
3396 const Init *
I =
nullptr;
3399 I = R->resolve(VarName);
3400 if (
I && !FoundUnresolved) {
3405 I->resolveReferences(
Sub);
3406 FoundUnresolved |=
Sub.FoundUnresolved;
3411 FoundUnresolved =
true;
3416 if (VarName == VarNameToTrack)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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< OcamlGC > B("ocaml", "ocaml 3.10-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 constexpr Value * getValue(Ty &ValueOrUse)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
const SmallVectorImpl< MachineOperand > & Cond
static const Init * SortHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)
static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Range)
static bool canFitInBitfield(int64_t Value, unsigned NumBits)
static void ProfileCondOpInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Conds, ArrayRef< const Init * > Vals, const RecTy *ValType)
static std::optional< unsigned > getDagArgNoByKey(const DagInit *Dag, const Init *Key, std::string &Error)
static const StringInit * ConcatStringInits(const StringInit *I0, const StringInit *I1)
static void ProfileExistsOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)
static const ListInit * ConcatListInits(const ListInit *LHS, const ListInit *RHS)
static const StringInit * interleaveStringList(const ListInit *List, const StringInit *Delim)
static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
static void ProfileFoldOpInit(FoldingSetNodeID &ID, const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
static void ProfileInstancesOpInit(FoldingSetNodeID &ID, const RecTy *Type, const Init *Regex)
static void ProfileArgumentInit(FoldingSetNodeID &ID, const Init *Value, ArgAuxType Aux)
static const Init * ForeachDagApply(const Init *LHS, const DagInit *MHSd, const Init *RHS, const Record *CurRec)
static const Init * FilterHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)
static const Init * ItemApply(const Init *LHS, const Init *MHSe, const Init *RHS, const Record *CurRec)
static const RecordRecTy * resolveRecordTypes(const RecordRecTy *T1, const RecordRecTy *T2)
static void ProfileRecordRecTy(FoldingSetNodeID &ID, ArrayRef< const Record * > Classes)
static const Init * ForeachHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)
static void ProfileVarDefInit(FoldingSetNodeID &ID, const Record *Class, ArrayRef< const ArgumentInit * > Args)
static void ProfileIsAOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)
static const StringInit * interleaveIntList(const ListInit *List, const StringInit *Delim)
This file defines the SmallString class.
This file defines the SmallVector class.
FunctionLoweringInfo::StatepointRelocationRecord RecordType
static SymbolRef::Type getType(const Symbol *Sym)
static constexpr int Concat[]
static AnonymousNameInit * get(RecordKeeper &RK, unsigned)
const StringInit * getNameInit() const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const ArgumentInit * cloneWithValue(const Init *Value) const
void Profile(FoldingSetNodeID &ID) const
static const ArgumentInit * get(const Init *Value, ArgAuxType Aux)
ArgumentInit(const Init *Value, ArgAuxType Aux)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
static const BinOpInit * get(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
static const Init * getStrConcat(const Init *lhs, const Init *rhs)
std::string getAsString() const override
Convert this value to a literal form.
BinaryOp getOpcode() const
std::optional< bool > CompareInit(unsigned Opc, const Init *LHS, const Init *RHS) const
static const Init * getListConcat(const TypedInit *lhs, const Init *rhs)
const Init * Fold(const Record *CurRec) const
'true'/'false' - Represent a concrete initializer for a bit.
static BitInit * get(RecordKeeper &RK, bool V)
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
'bit' - Represent a single bit
static const BitRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
'{ a, b, c }' - Represents an initializer for a BitsRecTy value.
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
unsigned getNumBits() const
std::optional< int64_t > convertInitializerToInt() const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
ArrayRef< const Init * > getBits() const
uint64_t convertKnownBitsToInt() const
bool allInComplete() const
static BitsInit * get(RecordKeeper &RK, ArrayRef< const Init * > Range)
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?
'bits<n>' - Represent a fixed number of bits
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
static const BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
std::string getAsString() const override
const Init * Fold(const Record *CurRec) const
auto getCondAndVals() const
ArrayRef< const Init * > getVals() const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
static const CondOpInit * get(ArrayRef< const Init * > Conds, ArrayRef< const Init * > Values, const RecTy *Type)
const RecTy * getValType() const
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
ArrayRef< const Init * > getConds() const
(v a, b) - Represent a DAG tree value.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?
std::optional< unsigned > getArgNo(StringRef Name) const
This method looks up the specified argument name and returns its argument number or std::nullopt if t...
const StringInit * getName() const
void Profile(FoldingSetNodeID &ID) const
const Init * getOperator() const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
ArrayRef< const StringInit * > getArgNames() const
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
const Record * getOperatorAsDef(ArrayRef< SMLoc > Loc) const
auto getArgAndNames() const
ArrayRef< const Init * > getArgs() const
std::string getAsString() const override
Convert this value to a literal form.
'dag' - Represent a dag fragment
std::string getAsString() const override
static const DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
std::string getAsString() const override
Convert this value to a literal form.
const RecTy * getFieldType(const StringInit *FieldName) const override
This function is used to implement the FieldInit class.
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
Lightweight error class with error context and mandatory checking.
void Profile(FoldingSetNodeID &ID) const
static const ExistsOpInit * get(const RecTy *CheckType, const Init *Expr)
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
X.Y - Represent a reference to a subfield of a variable.
const Init * Fold(const Record *CurRec) const
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
static const FieldInit * get(const Init *R, const StringInit *FN)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?
const Init * Fold(const Record *CurRec) const
std::string getAsString() const override
Convert this value to a literal form.
static const FoldOpInit * get(const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
void Profile(FoldingSetNodeID &ID) const
void insert(T *N, FoldingSetInsertToken Token)
Insert the specified node into the folding set, knowing that it is not already in the folding set.
T * lookup(const FoldingSetNodeID &ID, FoldingSetInsertToken &Token)
Look up the node specified by ID.
Insertion token: a failed lookup fills it in, the matching insert consumes it.
This class is used to gather all the unique data bits of a node.
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
virtual const Init * resolveReferences(Resolver &R) const
This function is used by classes that refer to other variables which may not be defined at the time t...
virtual std::string getAsUnquotedString() const
Convert this value to a literal form, without adding quotes around a string.
void dump() const
Debugging method that may be called through a debugger; just invokes print on stderr.
void print(raw_ostream &OS) const
Print this value.
virtual std::string getAsString() const =0
Convert this value to a literal form.
virtual bool isConcrete() const
Is this a concrete and fully resolved value without any references or stuck operations?
virtual bool isComplete() const
Is this a complete value with no unset (uninitialized) subvalues?
virtual const Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual const Init * convertInitializerTo(const RecTy *Ty) const =0
Convert to a value whose type is Ty, or return null if this is not possible.
virtual const Init * getCastTo(const 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.
Init(InitKind K, uint8_t Opc=0)
void Profile(FoldingSetNodeID &ID) const
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
static const InstancesOpInit * get(const RecTy *Type, const Init *Regex)
static IntInit * get(RecordKeeper &RK, int64_t V)
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
std::string getAsString() const override
Convert this value to a literal form.
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
'int' - Represent an integer value of no particular size
static const IntRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
static const IsAOpInit * get(const RecTy *CheckType, const Init *Expr)
void Profile(FoldingSetNodeID &ID) const
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
const Init * Fold() const
[AL, AH, CL] - Represent a list of defs
std::string getAsString() const override
Convert this value to a literal form.
const RecTy * getElementType() const
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations?
bool isComplete() const override
Is this a complete value with no unset (uninitialized) subvalues?
const Init * resolveReferences(Resolver &R) const override
This method is used by classes that refer to other variables which may not be defined at the time the...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
const Record * getElementAsRecord(unsigned Idx) const
ArrayRef< const Init * > getElements() const
const Init * getElement(unsigned Idx) const
'list<Ty>' - Represent a list of element values, all of which must be of the specified type.
const RecTy * getElementType() const
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
std::string getAsString() const override
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
A helper class to return the specified delimiter string after the first invocation of operator String...
Resolve arbitrary mappings.
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
const Init * getBit(unsigned Bit) const final
Get the Init value of the specified bit.
RecordKeeper & getRecordKeeper() const
Return the RecordKeeper that uniqued this Type.
virtual bool typeIsA(const RecTy *RHS) const
Return true if 'this' type is equal to or a subtype of RHS.
virtual bool typeIsConvertibleTo(const RecTy *RHS) const
Return true if all values of 'this' type can be converted to the specified type.
RecTyKind
Subclass discriminator (for dyn_cast<> et al.)
RecTy(RecTyKind K, RecordKeeper &RK)
virtual std::string getAsString() const =0
const ListRecTy * getListTy() const
Returns the type representing list<thistype>.
const Record * getClass(StringRef Name) const
Get the class with the specified name.
const RecordMap & getClasses() const
Get the map of classes.
const Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
const RecordMap & getDefs() const
Get the map of records (defs).
detail::RecordKeeperImpl & getImpl()
Return the internal implementation of the RecordKeeper.
void dumpAllocationStats(raw_ostream &OS) const
ArrayRef< const Record * > getAllDerivedDefinitionsIfDefined(StringRef ClassName) const
Get all the concrete records that inherit from specified class, if the class is defined.
const Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
ArrayRef< const Record * > getAllDerivedDefinitions(StringRef ClassName) const
Get all the concrete records that inherit from the one specified class.
'[classname]' - Type of record values that have zero or more superclasses.
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
bool isSubClassOf(const Record *Class) const
ArrayRef< const Record * > getClasses() const
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
static const RecordRecTy * get(RecordKeeper &RK, ArrayRef< const Record * > Classes)
Get the record type with the given non-redundant list of superclasses.
Resolve all variables from a record except for unset variables.
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
This class represents a field in a record, including its name, type, value, and source location.
std::string getNameInitAsString() const
Get the name of the field as a std::string.
bool isNonconcreteOK() const
Is this a field where nonconcrete values are okay?
bool setValue(const Init *V)
Set the value of the field from an Init.
SMLoc getLoc() const
Get the source location of the point where the field was defined.
const Init * getValue() const
Get the value of the field as an Init.
StringRef getName() const
Get the name of the field as a StringRef.
void print(raw_ostream &OS, bool PrintSem=true) const
Print the value to an output stream, possibly with a semicolon.
RecordVal(const Init *N, const RecTy *T, FieldKind K)
const Init * getNameInit() const
Get the name of the field as an Init.
std::string getPrintType() const
Get the type of the field for printing purposes.
const RecTy * getType() const
Get the type of the field value as a RecTy.
std::vector< int64_t > getValueAsListOfInts(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of integers,...
const RecordRecTy * getType() const
const Init * getValueInit(StringRef FieldName) const
Return the initializer for a value with the specified name, or throw an exception if the field does n...
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const
This method looks up the specified field and returns its value as a bit.
bool getValueAsBit(StringRef FieldName) const
This method looks up the specified field and returns its value as a bit, throwing an exception if the...
static unsigned getNewUID(RecordKeeper &RK)
ArrayRef< SMLoc > getLoc() const
void checkUnusedTemplateArgs()
ArrayRef< DumpInfo > getDumps() const
std::vector< const Record * > getValueAsListOfDefs(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of records,...
ArrayRef< AssertionInfo > getAssertions() const
std::string getNameInitAsString() const
const Record * getValueAsDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, throwing an exception if ...
const DagInit * getValueAsDag(StringRef FieldName) const
This method looks up the specified field and returns its value as an Dag, throwing an exception if th...
std::vector< StringRef > getValueAsListOfStrings(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of strings,...
const RecordVal * getValue(const Init *Name) const
void addValue(const RecordVal &RV)
const Record * getValueAsOptionalDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, returning null if the fie...
ArrayRef< std::pair< const Record *, SMRange > > getDirectSuperClasses() const
Return the direct superclasses of this record.
StringRef getName() const
Record(const Init *N, ArrayRef< SMLoc > locs, RecordKeeper &records, RecordKind Kind=RK_Def)
void setName(const Init *Name)
const ListInit * getValueAsListInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a ListInit, throwing an exception i...
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
DefInit * getDefInit() const
get the corresponding DefInit.
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void resolveReferences(const Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
std::optional< StringRef > getValueAsOptionalString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
void removeValue(const Init *Name)
ArrayRef< const Init * > getTemplateArgs() const
void updateClassLoc(SMLoc Loc)
const BitsInit * getValueAsBitsInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a BitsInit, throwing an exception i...
void addDirectSuperClass(const Record *R, SMRange Range)
void appendAssertions(const Record *Rec)
const Init * getNameInit() const
int64_t getValueAsInt(StringRef FieldName) const
This method looks up the specified field and returns its value as an int64_t, throwing an exception i...
void checkRecordAssertions()
StringRef getValueAsString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
const Record * getCurrentRecord() const
Represents a location in source code.
Delegate resolving to a sub-resolver, but shadow some variable names.
void addShadow(const Init *Key)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
"foo" - Represent an initialization by a string value.
static const StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
StringFormat getFormat() const
StringRef getValue() const
static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2)
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
'string' - Represent an string value
std::string getAsString() const override
static const StringRecTy * get(RecordKeeper &RK)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
const Init * Fold(const Record *CurRec) const
static const TernOpInit * get(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs, const RecTy *Type)
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
TernaryOp getOpcode() const
(Optionally) delegate resolving to a sub-resolver, and keep track whether there were unresolved refer...
const Init * resolve(const Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit),...
bool foundUnresolved() const
TrackUnresolvedResolver(Resolver *R=nullptr)
See the file comment for details on the usage of the TrailingObjects type.
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This is the common superclass of types that have a specific, explicit type, stored in ValueTy.
const RecTy * getFieldType(const StringInit *FieldName) const override
This method is used to implement the FieldInit class.
TypedInit(InitKind K, const RecTy *T, uint8_t Opc=0)
const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This function is used to implement the bit range selection operator.
RecordKeeper & getRecordKeeper() const
Get the record keeper that initialized this Init.
const Init * getCastTo(const RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
const RecTy * getType() const
Get the type of the Init as a RecTy.
UnaryOp getOpcode() const
static const UnOpInit * get(UnaryOp opc, const Init *lhs, const RecTy *Type)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
std::string getAsString() const override
Convert this value to a literal form.
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
A uniquing set that compares nodes against a typed key rather than a serialized FoldingSetNodeID.
T * lookup(const KeyTy &Key, FoldingSetInsertToken &Token)
Look up Key.
void insert(T *N, FoldingSetInsertToken Token)
Insert N, which must key identically to the lookup that produced Token.
'?' - Represents an uninitialized value.
const Init * getCastTo(const RecTy *Ty) const override
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
const Init * convertInitializerTo(const RecTy *Ty) const override
Convert to a value whose type is Ty, or return null if this is not possible.
static UnsetInit * get(RecordKeeper &RK)
Get the singleton unset Init.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
Opcode{0} - Represent access to one bit of a variable or field.
static const VarBitInit * get(const TypedInit *T, unsigned B)
unsigned getBitNum() const
std::string getAsString() const override
Convert this value to a literal form.
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
ArrayRef< const ArgumentInit * > args() const
static const VarDefInit * get(SMLoc Loc, const Record *Class, ArrayRef< const ArgumentInit * > Args)
const Init * resolveReferences(Resolver &R) const override
This function is used by classes that refer to other variables which may not be defined at the time t...
const Init * Fold() const
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a literal form.
'Opcode' - Represent a reference to an entire variable object.
static const VarInit * get(StringRef VN, const RecTy *T)
const Init * getBit(unsigned Bit) const override
Get the Init value of the specified bit.
StringRef getName() const
const Init * getNameInit() const
const Init * resolveReferences(Resolver &R) const override
This method is used by classes that refer to other variables which may not be defined at the time the...
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
void stable_sort(R &&Range)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
RelativeUniformCounterPtr Values
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void PrintFatalError(const Twine &Msg)
LLVM_ABI void PrintError(const Twine &Msg)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
std::string utostr(uint64_t X, bool isNeg=false)
auto uninitialized_copy(R &&Src, IterTy Dst)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void PrintWarning(const Twine &Msg)
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
LLVM_ABI void dumpMessage(SMLoc Loc, const Init *Message)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
std::variant< unsigned, const Init * > ArgAuxType
std::string itostr(int64_t X)
FoldingSetImpl< T, Trait > FoldingSet
This template class is used to instantiate a specialized implementation of the folding set to the nod...
Implement std::hash so that hash_code can be used in STL containers.
This class represents the internal implementation of the RecordKeeper.
StringMap< const StringInit *, BumpPtrAllocator & > StringInitCodePool
StringRecTy SharedStringRecTy
FoldingSet< BitsInit > TheBitsInitPool
BumpPtrAllocator Allocator
std::map< int64_t, IntInit * > TheIntInitPool
FoldingSet< ArgumentInit > TheArgumentInitPool
UniquingSet< UnOpInit > TheUnOpInitPool
DenseMap< std::pair< const Init *, const StringInit * >, FieldInit * > TheFieldInitPool
std::vector< BitsRecTy * > SharedBitsRecTys
UniquingSet< ListInit > TheListInitPool
FoldingSet< RecordRecTy > RecordTypePool
FoldingSet< VarDefInit > TheVarDefInitPool
RecordKeeperImpl(RecordKeeper &RK)
StringMap< const StringInit *, BumpPtrAllocator & > StringInitStringPool
UniquingSet< TernOpInit > TheTernOpInitPool
UniquingSet< BinOpInit > TheBinOpInitPool
FoldingSet< InstancesOpInit > TheInstancesOpInitPool
void dumpAllocationStats(raw_ostream &OS) const
FoldingSet< ExistsOpInit > TheExistsOpInitPool
DenseMap< std::pair< const RecTy *, const Init * >, VarInit * > TheVarInitPool
FoldingSet< IsAOpInit > TheIsAOpInitPool
FoldingSet< DagInit > TheDagInitPool
DenseMap< std::pair< const TypedInit *, unsigned >, VarBitInit * > TheVarBitInitPool
FoldingSet< CondOpInit > TheCondOpInitPool
FoldingSet< FoldOpInit > TheFoldOpInitPool
Sorting predicate to sort record pointers by name.