22 #include "llvm/Config/llvm-config.h" 52 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 63 assert(RHS &&
"NULL pointer");
72 if (
const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS))
73 return BitsTy->getNumBits() == 1;
78 static std::vector<BitsRecTy*> Shared;
79 if (Sz >= Shared.size())
80 Shared.resize(Sz + 1);
93 return cast<BitsRecTy>(RHS)->
Size ==
Size;
99 if (
const BitsRecTy *RHSb = dyn_cast<BitsRecTy>(RHS))
100 return RHSb->Size ==
Size;
124 return "list<" + Ty->getAsString() +
">";
128 if (
const auto *ListTy = dyn_cast<ListRecTy>(RHS))
134 if (
const ListRecTy *RHSl = dyn_cast<ListRecTy>(RHS))
135 return getElementType()->typeIsA(RHSl->getElementType());
151 if (UnsortedClasses.
empty()) {
157 UnsortedClasses[0]->getRecords().RecordTypePool;
160 UnsortedClasses.
end());
174 for (
unsigned i = 0; i < Classes.size(); ++i) {
175 for (
unsigned j = 0; j < Classes.size(); ++j) {
176 assert(i == j || !Classes[i]->isSubClassOf(Classes[j]));
178 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
182 void *Mem = Allocator.
Allocate(totalSizeToAlloc<Record *>(Classes.size()),
185 std::uninitialized_copy(Classes.begin(), Classes.end(),
197 return getClasses()[0]->getNameInitAsString();
199 std::string Str =
"{";
201 for (
Record *R : getClasses()) {
205 Str += R->getNameInitAsString();
213 return MySuperClass == Class ||
227 return isSubClassOf(TargetClass);
241 while (!Stack.
empty()) {
259 if (
RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
260 if (
RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
269 if (
ListRecTy *ListTy1 = dyn_cast<ListRecTy>(T1)) {
270 if (
ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
272 ListTy2->getElementType());
285 void Init::anchor() {}
287 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 308 return V ? &True : &False;
312 if (isa<BitRecTy>(Ty))
313 return const_cast<BitInit *
>(
this);
315 if (isa<IntRecTy>(Ty))
318 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
320 if (BRT->getNumBits() == 1)
331 for (
Init *
I : Range)
345 void *Mem = Allocator.
Allocate(totalSizeToAlloc<Init *>(Range.
size()),
348 std::uninitialized_copy(Range.
begin(), Range.
end(),
359 if (isa<BitRecTy>(Ty)) {
360 if (getNumBits() != 1)
return nullptr;
364 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
367 if (getNumBits() != BRT->getNumBits())
return nullptr;
368 return const_cast<BitsInit *
>(
this);
371 if (isa<IntRecTy>(Ty)) {
373 for (
unsigned i = 0, e = getNumBits(); i != e; ++i)
374 if (
auto *
Bit = dyn_cast<BitInit>(getBit(i)))
375 Result |=
static_cast<int64_t
>(
Bit->getValue()) << i;
388 for (
unsigned i = 0, e = Bits.
size(); i != e; ++i) {
389 if (Bits[i] >= getNumBits())
391 NewBits[i] = getBit(Bits[i]);
397 for (
unsigned i = 0, e = getNumBits(); i != e; ++i) {
398 if (!getBit(i)->isConcrete())
405 std::string Result =
"{ ";
406 for (
unsigned i = 0, e = getNumBits(); i != e; ++i) {
407 if (i) Result +=
", ";
409 Result +=
Bit->getAsString();
413 return Result +
" }";
419 bool Changed =
false;
422 Init *CachedBitVarRef =
nullptr;
423 Init *CachedBitVarResolved =
nullptr;
425 for (
unsigned i = 0, e = getNumBits(); i != e; ++i) {
426 Init *CurBit = getBit(i);
427 Init *NewBit = CurBit;
429 if (
VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
430 if (CurBitVar->getBitVar() != CachedBitVarRef) {
431 CachedBitVarRef = CurBitVar->getBitVar();
435 NewBit = CachedBitVarResolved->
getBit(CurBitVar->getBitNum());
444 Changed |= CurBit != NewBit;
450 return const_cast<BitsInit *
>(
this);
467 return (NumBits >=
sizeof(Value) * 8) ||
468 (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
472 if (isa<IntRecTy>(Ty))
473 return const_cast<IntInit *
>(
this);
475 if (isa<BitRecTy>(Ty)) {
476 int64_t Val = getValue();
477 if (Val != 0 && Val != 1)
return nullptr;
481 if (
auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
482 int64_t
Value = getValue();
488 for (
unsigned i = 0; i != BRT->getNumBits(); ++i)
489 NewBits[i] =
BitInit::get(Value & ((i < 64) ? (1LL << i) : 0));
501 for (
unsigned i = 0, e = Bits.
size(); i != e; ++i) {
513 auto &Entry = *ThePool.
insert(std::make_pair(V,
nullptr)).first;
522 auto &Entry = *ThePool.
insert(std::make_pair(V,
nullptr)).first;
529 if (isa<StringRecTy>(Ty))
531 if (isa<CodeRecTy>(Ty))
538 if (isa<CodeRecTy>(Ty))
539 return const_cast<CodeInit *
>(
this);
540 if (isa<StringRecTy>(Ty))
552 for (
Init *
I : Range)
566 assert(Range.
empty() || !isa<TypedInit>(Range[0]) ||
567 cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
569 void *Mem = Allocator.
Allocate(totalSizeToAlloc<Init *>(Range.
size()),
572 std::uninitialized_copy(Range.
begin(), Range.
end(),
579 RecTy *EltTy = cast<ListRecTy>(
getType())->getElementType();
588 if (
auto *LRT = dyn_cast<ListRecTy>(Ty)) {
594 bool Changed =
false;
595 RecTy *ElementType = LRT->getElementType();
596 for (
Init *
I : getValues())
597 if (
Init *CI =
I->convertInitializerTo(ElementType)) {
615 for (
unsigned Element : Elements) {
616 if (Element >=
size())
624 assert(i < NumValues &&
"List element index out of range!");
634 bool Changed =
false;
636 for (
Init *CurElt : getValues()) {
637 Init *
E = CurElt->resolveReferences(R);
638 Changed |= E != CurElt;
644 return const_cast<ListInit *
>(
this);
648 for (
Init *Element : *
this) {
656 std::string Result =
"[";
657 const char *sep =
"";
658 for (
Init *Element : *
this) {
668 return const_cast<OpInit*
>(
this);
701 if (isa<StringRecTy>(
getType())) {
702 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
705 if (
DefInit *LHSd = dyn_cast<DefInit>(LHS))
708 if (
IntInit *LHSi = dyn_cast<IntInit>(LHS))
710 }
else if (isa<RecordRecTy>(
getType())) {
712 if (!CurRec && !IsFinal)
714 assert(CurRec &&
"NULL pointer");
728 Twine(
"Undefined reference to record: '") +
729 Name->getValue() +
"'\n");
737 Twine(
"Expected type '") +
738 getType()->getAsString() +
"', got '" +
751 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
752 assert(!LHSl->empty() &&
"Empty list in head");
753 return LHSl->getElement(0);
758 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
759 assert(!LHSl->empty() &&
"Empty list in tail");
762 return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
767 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
772 if (
ListInit *LHSl = dyn_cast<ListInit>(LHS))
774 if (
StringInit *LHSs = dyn_cast<StringInit>(LHS))
778 return const_cast<UnOpInit *
>(
this);
787 return const_cast<UnOpInit *
>(
this);
793 case CAST: Result =
"!cast<" +
getType()->getAsString() +
">";
break;
794 case HEAD: Result =
"!head";
break;
795 case TAIL: Result =
"!tail";
break;
796 case SIZE: Result =
"!size";
break;
797 case EMPTY: Result =
"!empty";
break;
799 return Result +
"(" + LHS->getAsString() +
")";
840 if (
const StringInit *I0s = dyn_cast<StringInit>(I0))
841 if (
const StringInit *I1s = dyn_cast<StringInit>(I1))
856 if (LOp->
getDef() != ROp->getDef()) {
858 LHSs->
getAsString() +
"' vs. '" + RHSs->getAsString() +
863 for (
unsigned i = 0, e = LHSs->
getNumArgs(); i != e; ++i) {
867 for (
unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
868 Args.push_back(RHSs->getArg(i));
881 Args.
insert(Args.
end(), RHSs->begin(), RHSs->end());
902 dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(
IntRecTy::get()));
904 dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(
IntRecTy::get()));
909 case EQ: Result = L->
getValue() == R->getValue();
break;
910 case NE: Result = L->
getValue() != R->getValue();
break;
911 case LE: Result = L->
getValue() <= R->getValue();
break;
912 case LT: Result = L->
getValue() < R->getValue();
break;
913 case GE: Result = L->
getValue() >= R->getValue();
break;
914 case GT: Result = L->
getValue() > R->getValue();
break;
940 dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(
IntRecTy::get()));
942 dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(
IntRecTy::get()));
944 int64_t LHSv = LHSi->
getValue(), RHSv = RHSi->getValue();
948 case ADD: Result = LHSv + RHSv;
break;
949 case AND: Result = LHSv & RHSv;
break;
950 case OR: Result = LHSv | RHSv;
break;
951 case SHL: Result = LHSv << RHSv;
break;
952 case SRA: Result = LHSv >> RHSv;
break;
953 case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv;
break;
967 if (LHS != lhs || RHS != rhs)
976 case CONCAT: Result =
"!con";
break;
977 case ADD: Result =
"!add";
break;
978 case AND: Result =
"!and";
break;
979 case OR: Result =
"!or";
break;
980 case SHL: Result =
"!shl";
break;
981 case SRA: Result =
"!sra";
break;
982 case SRL: Result =
"!srl";
break;
983 case EQ: Result =
"!eq";
break;
984 case NE: Result =
"!ne";
break;
985 case LE: Result =
"!le";
break;
986 case LT: Result =
"!lt";
break;
987 case GE: Result =
"!ge";
break;
988 case GT: Result =
"!gt";
break;
989 case LISTCONCAT: Result =
"!listconcat";
break;
990 case STRCONCAT: Result =
"!strconcat";
break;
992 return Result +
"(" + LHS->getAsString() +
", " + RHS->getAsString() +
")";
1033 bool Change =
false;
1039 for (
unsigned int i = 0; i < MHSd->
getNumArgs(); ++i) {
1044 if (
DagInit *Argd = dyn_cast<DagInit>(Arg))
1049 NewArgs.
push_back(std::make_pair(NewArg, ArgName));
1062 if (
DagInit *MHSd = dyn_cast<DagInit>(MHS))
1065 if (
ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
1068 for (
Init *&Item : NewList) {
1070 if (NewItem != Item)
1073 return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
1094 if (LHSd && MHSd && RHSd) {
1095 Record *Val = RHSd->getDef();
1097 Val = MHSd->getDef();
1100 if (LHSv && MHSv && RHSv) {
1101 std::string Val = RHSv->getName();
1102 if (LHSv->getAsString() == RHSv->getAsString())
1103 Val = MHSv->getName();
1106 if (LHSs && MHSs && RHSs) {
1107 std::string Val = RHSs->getValue();
1109 std::string::size_type found;
1110 std::string::size_type idx = 0;
1112 found = Val.find(LHSs->getValue(), idx);
1113 if (found == std::string::npos)
1115 Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
1116 idx = found + MHSs->getValue().size();
1131 if (
IntInit *LHSi = dyn_cast_or_null<IntInit>(
1133 if (LHSi->getValue())
1143 bool MHSok = MHSl || isa<UnsetInit>(MHS);
1144 bool RHSok = RHSl || isa<UnsetInit>(RHS);
1146 if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
1149 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->
size() == RHSl->size())) {
1151 unsigned Size = MHSl ? MHSl->
size() : RHSl->size();
1152 for (
unsigned i = 0; i !=
Size; ++i) {
1155 if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
1157 Children.
emplace_back(Node, dyn_cast<StringInit>(Name));
1175 if (
Value->getValue())
1192 if (LHS != lhs || MHS != mhs || RHS != rhs)
1200 bool UnquotedLHS =
false;
1202 case SUBST: Result =
"!subst";
break;
1203 case FOREACH: Result =
"!foreach"; UnquotedLHS =
true;
break;
1204 case IF: Result =
"!if";
break;
1205 case DAG: Result =
"!dag";
break;
1207 return (Result +
"(" +
1208 (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
1209 ", " + MHS->getAsString() +
", " + RHS->getAsString() +
")");
1245 Init *Accum = Start;
1246 for (
Init *Elt : *LI) {
1258 Init *NewStart = Start->resolveReferences(R);
1259 Init *NewList =
List->resolveReferences(R);
1265 if (Start == NewStart &&
List == NewList && Expr == NewExpr)
1268 return get(NewStart, NewList, A,
B, NewExpr,
getType())
1277 return (
Twine(
"!foldl(") + Start->getAsString() +
", " +
List->getAsString() +
1278 ", " + A->getAsUnquotedString() +
", " +
B->getAsUnquotedString() +
1279 ", " + Expr->getAsString() +
")")
1309 if (
TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
1311 if (TI->getType()->typeIsConvertibleTo(
CheckType))
1318 if (!
CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr))
1330 if (Expr != NewExpr)
1341 Expr->getAsString() +
")")
1347 for (
Record *Rec : RecordType->getClasses()) {
1349 return Field->getType();
1360 if (isa<BitRecTy>(
getType()) && isa<BitsRecTy>(Ty) &&
1361 cast<BitsRecTy>(Ty)->getNumBits() == 1)
1369 if (!T)
return nullptr;
1374 for (
unsigned Bit : Bits) {
1388 if (
Init *Converted = convertInitializerTo(Ty)) {
1389 assert(!isa<TypedInit>(Converted) ||
1403 if (!T)
return nullptr;
1405 if (Elements.
size() == 1)
1410 for (
unsigned Element : Elements)
1423 using Key = std::pair<RecTy *, Init *>;
1426 Key TheKey(std::make_pair(T, VN));
1435 StringInit *NameString = cast<StringInit>(getNameInit());
1441 return const_cast<VarInit*
>(
this);
1448 return const_cast<VarInit *
>(
this);
1452 using Key = std::pair<TypedInit *, unsigned>;
1455 Key TheKey(std::make_pair(T, B));
1464 return TI->getAsString() +
"{" +
utostr(
Bit) +
"}";
1468 Init *
I = TI->resolveReferences(R);
1470 return I->
getBit(getBitNum());
1477 using Key = std::pair<TypedInit *, unsigned>;
1480 Key TheKey(std::make_pair(T, E));
1488 return TI->getAsString() +
"[" +
utostr(Element) +
"]";
1496 if (getElementNum() <
List->size())
1497 return List->getElement(getElementNum());
1499 if (NewTI != TI && isa<TypedInit>(NewTI))
1518 if (
auto *RRT = dyn_cast<RecordRecTy>(Ty))
1520 return const_cast<DefInit *
>(
this);
1526 return RV->getType();
1531 return Def->getName();
1540 for (
Init *
I : Args)
1554 void *Mem = Allocator.
Allocate(totalSizeToAlloc<Init *>(Args.
size()),
1557 std::uninitialized_copy(Args.
begin(), Args.
end(),
1567 DefInit *VarDefInit::instantiate() {
1571 Class->getLoc(), Records,
1573 Record *NewRec = NewRecOwner.get();
1576 for (
const RecordVal &Val : Class->getValues())
1583 for (
unsigned i = 0, e = TArgs.
size(); i != e; ++i) {
1584 if (i < args_size())
1585 R.
set(TArgs[i], getArg(i));
1587 R.
set(TArgs[i], NewRec->getValue(TArgs[i])->getValue());
1589 NewRec->removeValue(TArgs[i]);
1592 NewRec->resolveReferences(R);
1596 for (
const auto &SCPair : SCs)
1597 NewRec->addSuperClass(SCPair.first, SCPair.second);
1599 NewRec->addSuperClass(Class,
1600 SMRange(Class->getLoc().back(),
1601 Class->getLoc().back()));
1604 NewRec->resolveReferences();
1605 Records.
addDef(std::move(NewRecOwner));
1615 bool Changed =
false;
1620 Init *NewArg =
Arg->resolveReferences(UR);
1622 Changed |= NewArg !=
Arg;
1628 return New->instantiate();
1640 Arg->resolveReferences(R);
1643 return const_cast<VarDefInit *>(
this)->instantiate();
1648 std::string Result = Class->getNameInitAsString() +
"<";
1649 const char *sep =
"";
1653 Result +=
Arg->getAsString();
1655 return Result +
">";
1659 using Key = std::pair<Init *, StringInit *>;
1662 Key TheKey(std::make_pair(R, FN));
1683 if (
DefInit *DI = dyn_cast<DefInit>(Rec)) {
1687 Twine(
"Attempting to access field '") +
1688 FieldName->getAsUnquotedString() +
"' of '" +
1689 Rec->getAsString() +
"' is a forbidden self-reference");
1691 if (FieldVal->isComplete())
1705 while (Arg != ArgRange.
end()) {
1706 assert(Name != NameRange.
end() &&
"Arg name underflow!");
1710 assert(Name == NameRange.
end() &&
"Arg name overflow!");
1725 void *Mem = Allocator.
Allocate(totalSizeToAlloc<Init *, StringInit *>(ArgRange.
size(), NameRange.
size()),
alignof(
BitsInit));
1727 std::uninitialized_copy(ArgRange.
begin(), ArgRange.
end(),
1729 std::uninitialized_copy(NameRange.
begin(), NameRange.
end(),
1737 ArrayRef<std::pair<Init*, StringInit*>> args) {
1741 for (
const auto &
Arg : args) {
1756 bool ArgsChanged =
false;
1757 for (
const Init *
Arg : getArgs()) {
1758 Init *NewArg =
Arg->resolveReferences(R);
1760 ArgsChanged |= NewArg !=
Arg;
1763 Init *
Op = Val->resolveReferences(R);
1764 if (Op != Val || ArgsChanged)
1765 return DagInit::get(Op, ValName, NewArgs, getArgNames());
1767 return const_cast<DagInit *
>(
this);
1771 if (!Val->isConcrete())
1773 for (
const Init *Elt : getArgs()) {
1774 if (!Elt->isConcrete())
1781 std::string Result =
"(" + Val->getAsString();
1783 Result +=
":" + ValName->getAsUnquotedString();
1785 Result +=
" " + getArg(0)->getAsString();
1786 if (getArgName(0)) Result +=
":$" + getArgName(0)->getAsUnquotedString();
1787 for (
unsigned i = 1, e = getNumArgs(); i != e; ++i) {
1788 Result +=
", " + getArg(i)->getAsString();
1789 if (getArgName(i)) Result +=
":$" + getArgName(i)->getAsUnquotedString();
1792 return Result +
")";
1800 :
Name(N), TyAndPrefix(T, P) {
1802 assert(
Value &&
"Cannot create unset value for current type!");
1816 if (!isa<BitsInit>(
Value)) {
1818 Bits.
reserve(BTy->getNumBits());
1819 for (
unsigned i = 0, e = BTy->getNumBits(); i < e; ++i)
1825 return Value ==
nullptr;
1831 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1842 if (PrintSem) OS <<
";\n";
1845 unsigned Record::LastID = 0;
1847 void Record::checkName() {
1849 const TypedInit *TypedName = cast<const TypedInit>(Name);
1850 if (!isa<StringRecTy>(TypedName->
getType()))
1852 "' is not a string!");
1857 getDirectSuperClasses(DirectSCs);
1885 while (!SCs.
empty()) {
1896 if (SkipVal == &
Value)
1900 if (
Value.setValue(VR)) {
1902 if (
TypedInit *VRT = dyn_cast<TypedInit>(VR))
1904 (
Twine(
"of type '") + VRT->getType()->getAsString() +
"' ").str();
1906 "is found when setting '" +
1907 Value.getNameInitAsString() +
1910 "' after resolving references: " +
1917 if (NewName != OldName) {
1926 resolveReferences(R);
1931 resolveReferences(R, RV);
1934 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1942 if (!TArgs.
empty()) {
1944 bool NeedComma =
false;
1945 for (
const Init *
TA : TArgs) {
1946 if (NeedComma) OS <<
", ";
1949 assert(RV &&
"Template argument record not found??");
1950 RV->
print(OS,
false);
1959 for (
const auto &SuperPair : SC)
1960 OS <<
" " << SuperPair.first->getNameInitAsString();
1968 if (!Val.getPrefix() && !R.
isTemplateArg(Val.getNameInit()))
1978 "' does not have a field named `" + FieldName +
"'!\n");
1986 "' does not have a field named `" + FieldName +
"'!\n");
1989 return SI->getValue();
1991 return CI->getValue();
1994 FieldName +
"' does not have a string initializer!");
2001 "' does not have a field named `" + FieldName +
"'!\n");
2006 FieldName +
"' does not have a BitsInit initializer!");
2013 "' does not have a field named `" + FieldName +
"'!\n");
2018 FieldName +
"' does not have a list initializer!");
2021 std::vector<Record*>
2024 std::vector<Record*> Defs;
2026 if (
DefInit *DI = dyn_cast<DefInit>(
I))
2027 Defs.push_back(DI->getDef());
2030 FieldName +
"' list is not entirely DefInit!");
2039 "' does not have a field named `" + FieldName +
"'!\n");
2042 return II->getValue();
2045 "' does not have an int initializer: " +
2049 std::vector<int64_t>
2052 std::vector<int64_t> Ints;
2054 if (
IntInit *II = dyn_cast<IntInit>(
I))
2055 Ints.push_back(II->getValue());
2058 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2059 "' does not have a list of ints initializer: " +
2065 std::vector<StringRef>
2068 std::vector<StringRef> Strings;
2071 Strings.push_back(
SI->getValue());
2074 Twine(
"Record `") +
getName() +
"', field `" + FieldName +
2075 "' does not have a list of strings initializer: " +
2085 "' does not have a field named `" + FieldName +
"'!\n");
2088 return DI->getDef();
2090 FieldName +
"' does not have a def initializer!");
2097 "' does not have a field named `" + FieldName +
"'!\n");
2100 return BI->getValue();
2102 FieldName +
"' does not have a bit initializer!");
2109 "' does not have a field named `" + FieldName.
str() +
"'!\n");
2111 if (isa<UnsetInit>(R->
getValue())) {
2117 return BI->getValue();
2119 FieldName +
"' does not have a bit initializer!");
2126 "' does not have a field named `" + FieldName +
"'!\n");
2131 FieldName +
"' does not have a dag initializer!");
2134 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 2139 OS <<
"------------- Classes -----------------\n";
2141 OS <<
"class " << *
C.second;
2143 OS <<
"------------- Defs -----------------\n";
2145 OS <<
"def " << *D.second;
2155 std::vector<Record *>
2157 Record *Class = getClass(ClassName);
2159 PrintFatalError(
"ERROR: Couldn't find the `" + ClassName +
"' class!\n");
2161 std::vector<Record*> Defs;
2162 for (
const auto &D : getDefs())
2164 Defs.push_back(D.second.get());
2170 auto It = Map.find(VarName);
2171 if (It == Map.end())
2174 Init *
I = It->second.V;
2176 if (!It->second.Resolved && Map.size() > 1) {
2188 Init *Val = Cache.lookup(VarName);
2192 for (
Init *S : Stack) {
2198 if (!isa<UnsetInit>(RV->getValue())) {
2199 Val = RV->getValue();
2200 Stack.push_back(VarName);
2214 I = R->resolve(VarName);
2215 if (I && !FoundUnresolved) {
2221 FoundUnresolved |= Sub.FoundUnresolved;
2226 FoundUnresolved =
true;
2232 if (VarName == VarNameToTrack)
static BinOpInit * get(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type)
Represents a range in source code.
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
StringRef getName() 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...
RecTyKind
Subclass discriminator (for dyn_cast<> et al.)
void print(raw_ostream &OS) const
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified bit.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
StringRef getName() const
Record * getValueAsDef(StringRef FieldName) const
This method looks up the specified field and returns its value as a Record, throwing an exception if ...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
BitsInit * getValueAsBitsInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a BitsInit, throwing an exception i...
const T & back() const
back - Get the last element.
This class represents lattice values for constants.
X.Y - Represent a reference to a subfield of a variable.
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This method is used to implement the bitrange selection operator.
virtual std::string getAsUnquotedString() const
Convert this value to a string form, without adding quote markers.
Record * getCurrentRecord() const
bool foundUnresolved() const
[AL, AH, CL] - Represent a list of defs
'7' - Represent an initialization by a literal integer value.
static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *A, Init *B, Init *Start, Init *List, Init *Expr, RecTy *Type)
'list<Ty>' - Represent a list of values, all of which must be of the specified type.
void getDirectSuperClasses(SmallVectorImpl< Record *> &Classes) const
Append the direct super classes of this record to Classes.
!op (X, Y) - Combine two inits.
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified bit.
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
void Profile(FoldingSetNodeID &ID) 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::string getAsString() const override
Convert this value to a string form.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
void push_back(const T &Elt)
AL - Represent a reference to a 'def' in the description.
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 * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit), or nullptr if the name could not be resolved.
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified bit.
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
static UnOpInit * get(UnaryOp opc, Init *lhs, RecTy *Type)
void addDef(std::unique_ptr< Record > R)
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This method is used to implement the bitrange selection operator.
RecTy * getFieldType(StringInit *FieldName) const override
This method is used to implement the FieldInit class.
Init * getCastTo(RecTy *Ty) const override
If this initializer is convertible to Ty, return an initializer whose type is-a Ty, generating a !cast operation if required.
Init * Fold(Record *CurRec, bool IsFinal=false) const
std::string getAsString() const override
Convert this value to a string form.
static Init * getStrConcat(Init *lhs, Init *rhs)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
static VarInit * get(StringRef VN, RecTy *T)
ListInit * getValueAsListInit(StringRef FieldName) const
This method looks up the specified field and returns its value as a ListInit, throwing an exception i...
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...
Resolve all references to a specific RecordVal.
const_record_iterator classes_begin() const
static BumpPtrAllocator Allocator
void reserve(size_type N)
virtual Init * getCastTo(RecTy *Ty) const =0
If this initializer is convertible to Ty, return an initializer whose type is-a Ty, generating a !cast operation if required.
Resolve all variables from a record except for unset variables.
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
'{ a, b, c }' - Represents an initializer for a BitsRecTy value.
Record * getElementAsRecord(unsigned i) const
std::string getAsString() const override
std::string getNameInitAsString() const
void dump() const
Debugging method that may be called through a debugger, just invokes print on stderr.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
static IntInit * get(int64_t V)
static BitsInit * get(ArrayRef< Init *> Range)
(Optionally) delegate resolving to a sub-resolver, and keep track whether there were unresolved refer...
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const
This method looks up the specified field and returns its value as a bit.
Init * getArg(unsigned Num) const
ArrayRef< std::pair< Record *, SMRange > > getSuperClasses() const
'?' - Represents an uninitialized value
'true'/'false' - Represent a concrete initializer for a bit.
Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override
This method is used to implement the bitrange selection operator.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static Init * ForeachApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec)
static BitsRecTy * get(unsigned Sz)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This is the common super-class of types that have a specific, explicit, type.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static RecordRecTy * resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2)
Shift and rotation operations.
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
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified bit.
RecTy * getElementType() const
static StringRecTy * get()
void Profile(FoldingSetNodeID &ID) const
static Optional< unsigned > getOpcode(ArrayRef< VPValue *> Values)
Returns the opcode of Values or ~0 if they do not all agree.
ArrayRef< Init * > getTemplateArgs() const
std::string getAsString() const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
std::string getAsString() const override
List[4] - Represent access to one element of a var or field.
'[classname]' - Type of record values that have zero or more superclasses.
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
std::string getAsString() const override
Convert this value to a string form.
std::vector< Record * > getValueAsListOfDefs(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of records, throwing an exception if the field does not exist or if the value is not the right type.
void AddInteger(signed I)
!foldl (a, b, expr, start, lst) - Fold over a list.
Init * getValueInit(StringRef FieldName) const
Return the initializer for a value with the specified name, or throw an exception if the field does n...
void print(raw_ostream &OS, bool PrintSem=true) const
std::string getAsString() const override
Convert this value to a string form.
const_iterator end() const
virtual Init * resolve(Init *VarName)=0
Return the initializer for the given variable name (should normally be a StringInit), or nullptr if the name could not be resolved.
StringInit * getArgName(unsigned Num) 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...
ArrayRef< SMLoc > getLoc() const
Type * getType() const
All values are typed, get the type of this value.
'bits<n>' - Represent a fixed number of bits
ArrayRef< Record * > getClasses() const
std::string itostr(int64_t X)
void Profile(FoldingSetNodeID &ID) const
bool isTemplateArg(Init *Name) 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...
Simple integer binary arithmetic operators.
bool isSubClassOf(const Record *R) const
ArrayRef< Init * > getValues() const
std::string getAsString() const override
Convert this value to a string form.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
unsigned getNumBits() 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...
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
Init * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit), or nullptr if the name could not be resolved.
virtual Init * getBit(unsigned Bit) const =0
This method is used to return the initializer for the specified bit.
ArrayRef< RecordVal > getValues() const
const_record_iterator classes_end() const
Init * convertInitListSlice(ArrayRef< unsigned > Elements) const override
This method is used to implement the list slice selection operator.
'code' - Represent a code fragment
void resolveReferencesTo(const RecordVal *RV)
If anything in this record refers to RV, replace the reference to RV with the RHS of RV...
bool isSubClassOf(Record *Class) const
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
virtual Init * convertInitializerTo(RecTy *Ty) const =0
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
void addShadow(Init *Key)
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Base class for operators.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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...
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
Init * getElement(unsigned i) const
Resolve arbitrary mappings.
Init * getNameInit() const
The instances of the Type class are immutable: once they are created, they are never changed...
Allocate memory in an ever growing pool, as if by bump-pointer.
virtual bool isConcrete() const
Is this a concrete and fully resolved value without any references or stuck operations? Unset values are concrete.
void resolveReferences()
If there are any field references that refer to fields that have been filled in, we can propagate the...
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void set(Init *Key, Init *Value)
"foo" - Represent an initialization by a string value.
RecTy * getFieldType(StringInit *FieldName) const override
This method is used to implement the FieldInit class.
static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS, Init *RHS, RecTy *Type)
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type)
static ManagedStatic< OptionRegistry > OR
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
!op (X) - Transform an init.
Init * getCastTo(RecTy *Ty) const override
If this initializer is convertible to Ty, return an initializer whose type is-a Ty, generating a !cast operation if required.
const std::string getNameInitAsString() const
static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN, ArrayRef< Init *> ArgRange, ArrayRef< StringInit *> NameRange)
static DagInit * get(Init *V, StringInit *VN, ArrayRef< Init *> ArgRange, ArrayRef< StringInit *> NameRange)
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
StringRef getValueAsString(StringRef FieldName) const
This method looks up the specified field and returns its value as a string, throwing an exception if ...
'string' - Represent an string value
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...
static BitInit * get(bool V)
static bool canFitInBitfield(int64_t Value, unsigned NumBits)
std::string getAsString() const override
Convert this value to a string form.
static CodeInit * get(StringRef)
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...
static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS, RecTy *Type)
DefInit * getDefInit()
get the corresponding DefInit.
static wasm::ValType getType(const TargetRegisterClass *RC)
static Init * ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Record *CurRec)
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
std::string getAsString() const override
Convert this value to a string form.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::vector< int64_t > getValueAsListOfInts(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of integers, throwing an exception if the field does not exist or if the value is not the right type.
static RecordRecTy * get(ArrayRef< Record *> Classes)
Get the record type with the given non-redundant list of superclasses.
void sort(IteratorTy Start, IteratorTy End)
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
std::vector< Record * > getAllDerivedDefinitions(StringRef ClassName) const
This method returns all concrete definitions that derive from the specified class name...
Delegate resolving to a sub-resolver, but shadow some variable names.
void setFinal(bool Final)
std::vector< StringRef > getValueAsListOfStrings(StringRef FieldName) const
This method looks up the specified field and returns its value as a vector of strings, throwing an exception if the field does not exist or if the value is not the right type.
static FieldInit * get(Init *R, StringInit *FN)
virtual Init * resolveReferences(Resolver &R) const
This method is used by classes that refer to other variables which may not be defined at the time the...
Init * Fold(Record *CurRec) const
std::string getAsString() const override
Init * convertInitListSlice(ArrayRef< unsigned > Elements) const override
This method is used to implement the list slice selection operator.
static StringInit * ConcatStringInits(const StringInit *I0, const StringInit *I1)
bool typeIsA(const RecTy *RHS) const override
Return true if 'this' type is equal to or a subtype of RHS.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
virtual bool typeIsA(const RecTy *RHS) const
Return true if 'this' type is equal to or a subtype of RHS.
Init * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit), or nullptr if the name could not be resolved.
const RecordVal * getValue(const Init *Name) const
const RecordMap & getClasses() const
Init * getOperator() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static VarBitInit * get(TypedInit *T, unsigned B)
static StringInit * get(StringRef)
RecordKeeper & getRecords() const
std::string getAsString() const override
Convert this value to a string form.
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...
CHAIN = SC CHAIN, Imm128 - System call.
Init * Fold(Record *CurRec) const
unsigned getNumArgs() const
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
RecTy * getElementType() const
static DefInit * get(Record *)
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
classname<targs...> - Represent an uninstantiated anonymous class instantiation.
std::string utostr(uint64_t X, bool isNeg=false)
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
static VarDefInit * get(Record *Class, ArrayRef< Init *> Args)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
static IsAOpInit * get(RecTy *CheckType, Init *Expr)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
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 * resolve(Init *VarName) override
Return the initializer for the given variable name (should normally be a StringInit), or nullptr if the name could not be resolved.
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...
LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg)
void Profile(FoldingSetNodeID &ID) const
void Profile(FoldingSetNodeID &ID) const
!isa<type>(expr) - Dynamically determine the type of an expression.
iterator insert(iterator I, T &&Elt)
static FoldOpInit * get(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type)
static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType, Init *Expr)
'int' - Represent an integer value of no particular size
amdgpu Simplify well known AMD library false Value Value * Arg
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified 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...
std::string getAsString() const override
Convert this value to a string form.
void Profile(FoldingSetNodeID &ID) const
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Bitwise operators - logical and, logical or, logical xor.
Init * getNameInit() const
void emplace_back(ArgTypes &&... Args)
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations? Unset values are concrete.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations? Unset values are concrete.
static Init * ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS, Record *CurRec)
LLVM_NODISCARD bool empty() const
Init * Fold(Record *CurRec) const
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
void addValue(const RecordVal &RV)
static TernOpInit * get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type)
const_iterator begin() const
static VarListElementInit * get(TypedInit *T, unsigned E)
RecTy * resolveTypes(RecTy *T1, RecTy *T2)
Find a common type that T1 and T2 convert to.
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...
static void ProfileVarDefInit(FoldingSetNodeID &ID, Record *Class, ArrayRef< Init *> Args)
void Profile(FoldingSetNodeID &ID) const
Opcode{0} - Represent access to one bit of a variable or field.
'Opcode' - Represent a reference to an entire variable object.
void Profile(FoldingSetNodeID &ID) const
std::string getAsString() const override
Convert this value to a string form.
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...
std::string getAsString() const override
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
'bit' - Represent a single bit
!op (X, Y, Z) - Combine two inits.
static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef< Init *> Range)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
static ListInit * get(ArrayRef< Init *> Range, RecTy *EltTy)
virtual bool keepUnsetBits() const
RecTyKind getRecTyKind() const
virtual bool typeIsConvertibleTo(const RecTy *RHS) const
Return true if all values of 'this' type can be converted to the specified type.
StringRef getValue() const
'dag' - Represent a dag fragment
Record * getDef(StringRef Name) const
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const TargetLowering *TLI, const DataLayout &DL)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Init * getBit(unsigned Bit) const override
This method is used to return the initializer for the specified bit.
LLVM Value Representation.
(v a, b) - Represent a DAG tree value.
virtual std::string getAsString() const =0
Convert this value to a string form.
bool isConcrete() const override
Is this a concrete and fully resolved value without any references or stuck operations? Unset values are concrete.
static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef< Init *> Range, RecTy *EltTy)
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
void Profile(FoldingSetNodeID &ID) const
static void ProfileRecordRecTy(FoldingSetNodeID &ID, ArrayRef< Record *> Classes)
std::string getAsString() const override
Convert this value to a string form.
virtual std::string getAsString() const =0
Init * convertInitializerTo(RecTy *Ty) const override
Convert to an initializer whose type is-a Ty, or return nullptr if this is not possible (this can hap...
ListRecTy * getListTy()
Returns the type representing list<this>.
Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
const RecordMap & getDefs() const
std::string getAsString() const override
Convert this value to a string form.
Init * Fold(Record *CurRec) const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::string getAsString() const override
Convert this value to a string form.
bool empty() const
empty - Check if the array is empty.
RecordVal(Init *N, RecTy *T, bool P)