LLVM: lib/TableGen/Record.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

22#include "llvm/Config/llvm-config.h"

33#include

34#include

35#include

36#include

37#include

38#include

39#include

40

41using namespace llvm;

42

43#define DEBUG_TYPE "tblgen-records"

44

45

46

47

48

49

50

51

52

101

129

130

131

132

133

134#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

136#endif

137

139 if (!ListTy)

140 ListTy = new (RK.getImpl().Allocator) ListRecTy(this);

141 return ListTy;

142}

143

145 assert(RHS && "NULL pointer");

146 return Kind == RHS->getRecTyKind();

147}

148

150

152 return &RK.getImpl().SharedBitRecTy;

153}

154

157 return true;

159 return BitsTy->getNumBits() == 1;

160 return false;

161}

162

168 if (!Ty)

169 Ty = new (RKImpl.Allocator) BitsRecTy(RK, Sz);

170 return Ty;

171}

172

174 return "bits<" + utostr(Size) + ">";

175}

176

180 RecTyKind kind = RHS->getRecTyKind();

182}

183

185 return &RK.getImpl().SharedIntRecTy;

186}

187

189 RecTyKind kind = RHS->getRecTyKind();

191}

192

194 return &RK.getImpl().SharedStringRecTy;

195}

196

198 return "string";

199}

200

202 RecTyKind Kind = RHS->getRecTyKind();

204}

205

207 return "list<" + ElementTy->getAsString() + ">";

208}

209

212 return ElementTy->typeIsConvertibleTo(ListTy->getElementType());

213 return false;

214}

215

218 return getElementType()->typeIsA(RHSl->getElementType());

219 return false;

220}

221

223 return &RK.getImpl().SharedDagRecTy;

224}

225

229

232 ID.AddInteger(Classes.size());

233 for (const Record *R : Classes)

234 ID.AddPointer(R);

235}

236

238 : RecTy(RecordRecTyKind, RK), NumClasses(Classes.size()) {

240}

241

245 if (UnsortedClasses.empty())

247

249

252 return LHS->getNameInitAsString() < RHS->getNameInitAsString();

253 });

254

257

258 void *IP = nullptr;

260 return Ty;

261

262#ifndef NDEBUG

263

264 for (unsigned i = 0; i < Classes.size(); ++i) {

265 for (unsigned j = 0; j < Classes.size(); ++j) {

267 }

268 assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());

269 }

270#endif

271

272 void *Mem = RKImpl.Allocator.Allocate(

274 RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes);

276 return Ty;

277}

278

280 assert(Class && "unexpected null class");

281 return get(Class->getRecords(), {Class});

282}

283

287

289 if (NumClasses == 1)

290 return getClasses()[0]->getNameInitAsString();

291

292 std::string Str = "{";

295 Str += LS;

296 Str += R->getNameInitAsString();

297 }

298 Str += "}";

299 return Str;

300}

301

304 return MySuperClass == Class || MySuperClass->isSubClassOf(Class);

305 });

306}

307

309 if (this == RHS)

310 return true;

311

313 if (!RTy)

314 return false;

315

316 return llvm::all_of(RTy->getClasses(), [this](const Record *TargetClass) {

317 return isSubClassOf(TargetClass);

318 });

319}

320

324

329

330 while (!Stack.empty()) {

331 const Record *R = Stack.pop_back_val();

332

333 if (T2->isSubClassOf(R))

335 else

337 }

338

340}

341

343 if (T1 == T2)

344 return T1;

345

349 }

350

351 assert(T1 != nullptr && "Invalid record type");

352 if (T1->typeIsConvertibleTo(T2))

353 return T2;

354

355 assert(T2 != nullptr && "Invalid record type");

356 if (T2->typeIsConvertibleTo(T1))

357 return T1;

358

361 const RecTy *NewType =

362 resolveTypes(ListTy1->getElementType(), ListTy2->getElementType());

363 if (NewType)

365 }

366 }

367

368 return nullptr;

369}

370

371

372

373

374

375void Init::anchor() {}

376

377#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

379#endif

380

383 return TyInit->getType()->getRecordKeeper();

385 return ArgInit->getRecordKeeper();

387}

388

390 return &RK.getImpl().TheUnsetInit;

391}

392

394

398

401 auto I = Aux.index();

402 ID.AddInteger(I);

404 ID.AddInteger(std::getArgumentInit::Positional(Aux));

406 ID.AddPointer(std::getArgumentInit::Named(Aux));

408}

409

413

417

420 void *IP = nullptr;

423 return I;

424

427 return I;

428}

429

431 const Init *NewValue = Value->resolveReferences(R);

432 if (NewValue != Value)

434

435 return this;

436}

437

441

444 return this;

445

448

450

451 if (BRT->getNumBits() == 1)

453 }

454

455 return nullptr;

456}

457

460 ID.AddInteger(Range.size());

461

463 ID.AddPointer(I);

464}

465

470}

471

475

477 void *IP = nullptr;

479 return I;

480

481 void *Mem = RKImpl.Allocator.Allocate(

483 BitsInit *I = new (Mem) BitsInit(RK, Bits);

485 return I;

486}

487

491

494 if (getNumBits() != 1) return nullptr;

496 }

497

499

500

501 if (getNumBits() != BRT->getNumBits()) return nullptr;

502 return this;

503 }

504

507 if (Result)

509 }

510

511 return nullptr;

512}

513

515 int64_t Result = 0;

518 Result |= static_cast<int64_t>(Bit->getValue()) << Idx;

519 else

520 return std::nullopt;

521 return Result;

522}

523

528 Result |= static_cast<int64_t>(Bit->getValue()) << Idx;

529 return Result;

530}

531

535

536 for (auto [Bit, NewBit] : zip_equal(Bits, NewBits)) {

538 return nullptr;

539 NewBit = getBit(Bit);

540 }

542}

543

545 return all_of(getBits(), [](const Init *Bit) { return Bit->isComplete(); });

546}

548 return all_of(getBits(), [](const Init *Bit) { return !Bit->isComplete(); });

549}

551 return all_of(getBits(), [](const Init *Bit) { return Bit->isConcrete(); });

552}

553

555 std::string Result = "{ ";

558 Result += LS;

559 if (Bit)

560 Result += Bit->getAsString();

561 else

562 Result += "*";

563 }

564 return Result + " }";

565}

566

567

568

572

573 const Init *CachedBitVarRef = nullptr;

574 const Init *CachedBitVarResolved = nullptr;

575

576 for (auto [CurBit, NewBit] : zip_equal(getBits(), NewBits)) {

577 NewBit = CurBit;

578

580 if (CurBitVar->getBitVar() != CachedBitVarRef) {

581 CachedBitVarRef = CurBitVar->getBitVar();

583 }

584 assert(CachedBitVarResolved && "Unresolved bitvar reference");

585 NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum());

586 } else {

587

588 NewBit = CurBit->resolveReferences(R)->getBit(0);

589 }

590

592 NewBit = CurBit;

593 Changed |= CurBit != NewBit;

594 }

595

598

599 return this;

600}

601

604 if (I)

605 I = new (RK.getImpl().Allocator) IntInit(RK, V);

606 return I;

607}

608

610 return itostr(Value);

611}

612

614

615 return (NumBits >= sizeof(Value) * 8) ||

616 (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);

617}

618

621 return this;

622

625 if (Val != 0 && Val != 1) return nullptr;

627 }

628

631

633 return nullptr;

634

636 for (unsigned i = 0; i != BRT->getNumBits(); ++i)

637 NewBits[i] =

639

641 }

642

643 return nullptr;

644}

645

648

649 for (auto [Bit, NewBit] : zip_equal(Bits, NewBits)) {

650 if (Bit >= 64)

651 return nullptr;

652

654 }

656}

657

659 return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V);

660}

661

665

667 return "anonymous_" + utostr(Value);

668}

669

671 auto *Old = this;

672 auto *New = R.resolve(Old);

673 New = New ? New : Old;

674 if (R.isFinal())

676 return Anonymous->getNameInit();

677 return New;

678}

679

685 auto &Entry = *InitMap.try_emplace(V, nullptr).first;

686 if (!Entry.second)

687 Entry.second = new (RKImpl.Allocator) StringInit(RK, Entry.getKey(), Fmt);

688 return Entry.second;

689}

690

693 return this;

694

695 return nullptr;

696}

697

700 const RecTy *EltTy) {

701 ID.AddInteger(Elements.size());

702 ID.AddPointer(EltTy);

703

704 for (const Init *E : Elements)

705 ID.AddPointer(E);

706}

707

712}

713

715 const RecTy *EltTy) {

718

720 void *IP = nullptr;

722 return I;

723

725 cast(Elements[0])->getType()->typeIsConvertibleTo(EltTy));

726

727 void *Mem = RK.Allocator.Allocate(

729 ListInit *I = new (Mem) ListInit(Elements, EltTy);

731 return I;

732}

733

738

741 return this;

742

745 Elements.reserve(size());

746

747

748

750 const RecTy *ElementType = LRT->getElementType();

752 if (const Init *CI = I->convertInitializerTo(ElementType)) {

753 Elements.push_back(CI);

754 if (CI != I)

756 } else {

757 return nullptr;

758 }

759

761 return this;

763 }

764

765 return nullptr;

766}

767

770 if (!DI)

772 return DI->getDef();

773}

774

777 Resolved.reserve(size());

779

783 Resolved.push_back(E);

784 }

785

788 return this;

789}

790

795

800

802 std::string Result = "[";

804 for (const Init *Element : *this) {

805 Result += LS;

807 }

808 return Result + "]";

809}

810

816

819 ID.AddInteger(Opcode);

820 ID.AddPointer(Op);

822}

823

827

829 void *IP = nullptr;

831 return I;

832

835 return I;

836}

837

841

846 if (LHS->isConcrete()) {

847

849 std::string S;

851 OS << *Def->getDef();

853 } else {

854

855

856

857

858

860 }

861 }

862 break;

866 break;

870 break;

874 return LHSs;

875

878

882

886 if (D && CurRec) {

887

888

891 (Anonymous && Name == Anonymous->getNameInit())) {

892 if (!IsFinal)

893 break;

894 D = CurRec;

895 }

896 }

897

898 auto PrintFatalErrorHelper = [CurRec](const Twine &T) {

899 if (CurRec)

901 else

903 };

904

905 if (D) {

906 if (IsFinal) {

907 PrintFatalErrorHelper(Twine("Undefined reference to record: '") +

908 Name->getValue() + "'\n");

909 }

910 break;

911 }

912

913 DefInit *DI = D->getDefInit();

915 PrintFatalErrorHelper(Twine("Expected type '") +

919 }

920 return DI;

921 }

922 }

923

925 return NewInit;

926 break;

927

931 if (LHS->isConcrete())

933 break;

934

935 case NOT:

938 return IntInit::get(RK, LHSi->getValue() ? 0 : 1);

939 break;

940

943 assert(!LHSl->empty() && "Empty list in head");

944 return LHSl->getElement(0);

945 }

946 break;

947

950 assert(!LHSl->empty() && "Empty list in tail");

951

952

953 return ListInit::get(LHSl->getElements().slice(1),

954 LHSl->getElementType());

955 }

956 break;

957

964 return IntInit::get(RK, LHSs->getValue().size());

965 break;

966

973 return IntInit::get(RK, LHSs->getValue().empty());

974 break;

975

978

979

981 if (!TI->getType()->typeIsA(getType())) {

984 "', got '" + TI->getType()->getAsString() +

986 } else {

987 return Dag->getOperator();

988 }

989 }

990 break;

991

994 return Dag->getName();

995 }

996 break;

997

1000 LHS->convertInitializerTo(IntRecTy::get(RK)))) {

1001 int64_t LHSv = LHSi->getValue();

1002 if (LHSv <= 0) {

1004 "Illegal operation: logtwo is undefined "

1005 "on arguments less than or equal to 0");

1006 } else {

1009 "Log of an int64_t must be smaller than INT64_MAX");

1010 return IntInit::get(RK, static_cast<int64_t>(Log));

1011 }

1012 }

1013 break;

1014

1017 const auto *InnerListTy = dyn_cast(LHSList->getElementType());

1018

1019 if (!InnerListTy)

1020 return LHS;

1021

1022 auto Flatten =

1023 [](const ListInit *List) -> std::optional<std::vector<const Init *>> {

1024 std::vector<const Init *> Flattened;

1025

1026 for (const Init *InnerInit : List->getElements()) {

1028 if (!InnerList)

1029 return std::nullopt;

1031 };

1032 return Flattened;

1033 };

1034

1035 auto Flattened = Flatten(LHSList);

1036 if (Flattened)

1037 return ListInit::get(*Flattened, InnerListTy->getElementType());

1038 }

1039 break;

1040 }

1041 return this;

1042}

1043

1046

1047 if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))

1049 ->Fold(R.getCurrentRecord(), R.isFinal());

1050 return this;

1051}

1052

1054 std::string Result;

1057 case NOT: Result = "!not"; break;

1058 case HEAD: Result = "!head"; break;

1059 case TAIL: Result = "!tail"; break;

1060 case SIZE: Result = "!size"; break;

1061 case EMPTY: Result = "!empty"; break;

1062 case GETDAGOP: Result = "!getdagop"; break;

1064 Result = "!getdagopname";

1065 break;

1066 case LOG2 : Result = "!logtwo"; break;

1068 Result = "!listflatten";

1069 break;

1071 Result = "!repr";

1072 break;

1074 Result = "!tolower";

1075 break;

1077 Result = "!toupper";

1078 break;

1080 Result = "!initialized";

1081 break;

1082 }

1083 return Result + "(" + LHS->getAsString() + ")";

1084}

1085

1089 ID.AddInteger(Opcode);

1090 ID.AddPointer(LHS);

1091 ID.AddPointer(RHS);

1092 ID.AddPointer(Type);

1093}

1094

1099

1101 void *IP = nullptr;

1103 return I;

1104

1105 BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);

1107 return I;

1108}

1109

1113

1117 Concat.append(I1->getValue());

1121}

1122

1125 if (List->size() == 0)

1128 if (!Element)

1129 return nullptr;

1132

1133 for (const Init *Elem : List->getElements().drop_front()) {

1134 Result.append(Delim->getValue());

1136 if (!Element)

1137 return nullptr;

1138 Result.append(Element->getValue());

1140 }

1141 return StringInit::get(List->getRecordKeeper(), Result, Fmt);

1142}

1143

1147 if (List->size() == 0)

1150 List->getElement(0)->convertInitializerTo(IntRecTy::get(RK)));

1151 if (!Element)

1152 return nullptr;

1154

1155 for (const Init *Elem : List->getElements().drop_front()) {

1156 Result.append(Delim->getValue());

1159 if (!Element)

1160 return nullptr;

1161 Result.append(Element->getAsString());

1162 }

1164}

1165

1174

1182

1192

1194 const Init *RHS) const {

1195

1200

1201 if (LHSi && RHSi) {

1202 bool Result;

1203 switch (Opc) {

1204 case EQ:

1205 Result = LHSi->getValue() == RHSi->getValue();

1206 break;

1207 case NE:

1208 Result = LHSi->getValue() != RHSi->getValue();

1209 break;

1210 case LE:

1211 Result = LHSi->getValue() <= RHSi->getValue();

1212 break;

1213 case LT:

1214 Result = LHSi->getValue() < RHSi->getValue();

1215 break;

1216 case GE:

1217 Result = LHSi->getValue() >= RHSi->getValue();

1218 break;

1219 case GT:

1220 Result = LHSi->getValue() > RHSi->getValue();

1221 break;

1222 default:

1224 }

1225 return Result;

1226 }

1227

1228

1231

1232 if (LHSs && RHSs) {

1233 bool Result;

1234 switch (Opc) {

1235 case EQ:

1236 Result = LHSs->getValue() == RHSs->getValue();

1237 break;

1238 case NE:

1239 Result = LHSs->getValue() != RHSs->getValue();

1240 break;

1241 case LE:

1242 Result = LHSs->getValue() <= RHSs->getValue();

1243 break;

1244 case LT:

1245 Result = LHSs->getValue() < RHSs->getValue();

1246 break;

1247 case GE:

1248 Result = LHSs->getValue() >= RHSs->getValue();

1249 break;

1250 case GT:

1251 Result = LHSs->getValue() > RHSs->getValue();

1252 break;

1253 default:

1255 }

1256 return Result;

1257 }

1258

1259

1263 if (LHSd && RHSd)

1264 return (Opc == EQ) ? LHSd == RHSd : LHSd != RHSd;

1265 }

1266

1267 return std::nullopt;

1268}

1269

1270static std::optional

1272

1274 int64_t Pos = Idx->getValue();

1275 if (Pos < 0) {

1276

1278 (Twine("index ") + std::to_string(Pos) + Twine(" is negative")).str();

1279 return std::nullopt;

1280 }

1281 if (Pos >= Dag->getNumArgs()) {

1282

1283 Error = (Twine("index ") + std::to_string(Pos) +

1284 " is out of range (dag has " +

1285 std::to_string(Dag->getNumArgs()) + " arguments)")

1286 .str();

1287 return std::nullopt;

1288 }

1289 return Pos;

1290 }

1292

1294 auto ArgNo = Dag->getArgNo(Name->getValue());

1295 if (!ArgNo) {

1296

1297 Error = (Twine("key '") + Name->getValue() + Twine("' is not found")).str();

1298 return std::nullopt;

1299 }

1300 return *ArgNo;

1301}

1302

1308 if (LHSs && RHSs) {

1311 if ((!LOp && isa<UnsetInit>(LHSs->getOperator())) ||

1313 break;

1314 if (LOp && ROp && LOp->getDef() != ROp->getDef()) {

1316 LHSs->getAsString() + "' vs. '" + RHSs->getAsString() +

1317 "'");

1318 }

1319 const Init *Op = LOp ? LOp : ROp;

1320 if (Op)

1322

1326

1327 const auto *NameInit = LHSs->getName();

1328 if (!NameInit)

1329 NameInit = RHSs->getName();

1331 }

1332 break;

1333 }

1336 if (!StrInit)

1337 return this;

1338

1340 if (!RegexInit)

1341 return this;

1342

1343 StringRef RegexStr = RegexInit->getValue();

1345 if (!Matcher.isValid())

1347

1349 Matcher.match(StrInit->getValue()));

1350 }

1354 if (LHSs && RHSs) {

1358 return ListInit::get(Args, LHSs->getElementType());

1359 }

1360 break;

1361 }

1366 if (Count->getValue() < 0)

1368 " is negative");

1371 }

1372 break;

1373 }

1377 if (LHSs && RHSs) {

1379 for (const Init *EltLHS : *LHSs) {

1380 bool Found = false;

1381 for (const Init *EltRHS : *RHSs) {

1382 if (std::optional Result = CompareInit(EQ, EltLHS, EltRHS)) {

1383 if (*Result) {

1384 Found = true;

1385 break;

1386 }

1387 }

1388 }

1389 if (!Found)

1390 Args.push_back(EltLHS);

1391 }

1392 return ListInit::get(Args, LHSs->getElementType());

1393 }

1394 break;

1395 }

1399 if (!TheList || !Idx)

1400 break;

1401 auto i = Idx->getValue();

1402 if (i < 0 || i >= (ssize_t)TheList->size())

1403 break;

1404 return TheList->getElement(i);

1405 }

1409 if (!TheList || !SliceIdxs)

1410 break;

1412 Args.reserve(SliceIdxs->size());

1413 for (auto *I : *SliceIdxs) {

1415 if (II)

1416 goto unresolved;

1417 auto i = II->getValue();

1418 if (i < 0 || i >= (ssize_t)TheList->size())

1419 goto unresolved;

1420 Args.push_back(TheList->getElement(i));

1421 }

1422 return ListInit::get(Args, TheList->getElementType());

1423 }

1427 if (!LHSi || !RHSi)

1428 break;

1429

1430 int64_t Start = LHSi->getValue();

1431 int64_t End = RHSi->getValue();

1434

1435 if (Start <= End) {

1436

1437 Args.reserve(End - Start + 1);

1438 for (auto i = Start; i <= End; ++i)

1440 } else {

1441

1442 Args.reserve(Start - End + 1);

1443 for (auto i = Start; i >= End; --i)

1445 }

1446 } else if (Start < End) {

1447

1448 Args.reserve(End - Start);

1449 for (auto i = Start; i < End; ++i)

1451 } else {

1452

1453 }

1455 }

1459 if (LHSs && RHSs)

1461 break;

1462 }

1466 if (List && Delim) {

1470 else

1472 if (Result)

1473 return Result;

1474 }

1475 break;

1476 }

1477 case EQ:

1478 case NE:

1479 case LE:

1480 case LT:

1481 case GE:

1482 case GT: {

1485 break;

1486 }

1490 std::string Error;

1492 if (!ArgNo)

1494

1495 assert(*ArgNo < Dag->getNumArgs());

1496

1497 const Init *Arg = Dag->getArg(*ArgNo);

1499 if (!TI->getType()->typeIsConvertibleTo(getType()))

1501 return Arg;

1502 }

1503 break;

1504 }

1508 if (Dag && Idx) {

1509 int64_t Pos = Idx->getValue();

1510 if (Pos < 0 || Pos >= Dag->getNumArgs()) {

1511

1513 Twine("!getdagname index is out of range 0...") +

1514 std::to_string(Dag->getNumArgs() - 1) + ": " +

1515 std::to_string(Pos));

1516 }

1517 const Init *ArgName = Dag->getArgName(Pos);

1518 if (!ArgName)

1520 return ArgName;

1521 }

1522 break;

1523 }

1527 if (Dag && Op)

1528 return DagInit::get(Op, Dag->getArgs(), Dag->getArgNames());

1529 break;

1530 }

1534 if (Dag && Op)

1535 return DagInit::get(Dag->getOperator(), Op, Dag->getArgs(),

1536 Dag->getArgNames());

1537 break;

1538 }

1539 case ADD:

1540 case SUB:

1541 case MUL:

1542 case DIV:

1543 case AND:

1544 case OR:

1545 case XOR:

1546 case SHL:

1547 case SRA:

1548 case SRL: {

1553 if (LHSi && RHSi) {

1554 int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();

1555 int64_t Result;

1558 case ADD: Result = LHSv + RHSv; break;

1559 case SUB: Result = LHSv - RHSv; break;

1560 case MUL: Result = LHSv * RHSv; break;

1561 case DIV:

1562 if (RHSv == 0)

1564 "Illegal operation: division by zero");

1565 else if (LHSv == INT64_MIN && RHSv == -1)

1567 "Illegal operation: INT64_MIN / -1");

1568 else

1569 Result = LHSv / RHSv;

1570 break;

1571 case AND: Result = LHSv & RHSv; break;

1572 case OR: Result = LHSv | RHSv; break;

1573 case XOR: Result = LHSv ^ RHSv; break;

1574 case SHL:

1575 if (RHSv < 0 || RHSv >= 64)

1577 "Illegal operation: out of bounds shift");

1579 break;

1580 case SRA:

1581 if (RHSv < 0 || RHSv >= 64)

1583 "Illegal operation: out of bounds shift");

1584 Result = LHSv >> (uint64_t)RHSv;

1585 break;

1586 case SRL:

1587 if (RHSv < 0 || RHSv >= 64)

1589 "Illegal operation: out of bounds shift");

1591 break;

1592 }

1594 }

1595 break;

1596 }

1597 }

1598unresolved:

1599 return this;

1600}

1601

1604

1607

1608

1609

1610

1611

1612

1613

1616 if ((Opc == AND && !LHSi->getValue()) ||

1617 (Opc == OR && LHSi->getValue() == -1))

1618 return LHSi;

1619 }

1620 }

1621

1623

1624 if (LHS != NewLHS || RHS != NewRHS)

1626 ->Fold(R.getCurrentRecord());

1627 return this;

1628}

1629

1631 std::string Result;

1635 return LHS->getAsString() + "[" + RHS->getAsString() + "]";

1637 return LHS->getAsString() + "..." + RHS->getAsString();

1638 case CONCAT: Result = "!con"; break;

1640 Result = "!match";

1641 break;

1642 case ADD: Result = "!add"; break;

1643 case SUB: Result = "!sub"; break;

1644 case MUL: Result = "!mul"; break;

1645 case DIV: Result = "!div"; break;

1646 case AND: Result = "!and"; break;

1647 case OR: Result = "!or"; break;

1648 case XOR: Result = "!xor"; break;

1649 case SHL: Result = "!shl"; break;

1650 case SRA: Result = "!sra"; break;

1651 case SRL: Result = "!srl"; break;

1652 case EQ: Result = "!eq"; break;

1653 case NE: Result = "!ne"; break;

1654 case LE: Result = "!le"; break;

1655 case LT: Result = "!lt"; break;

1656 case GE: Result = "!ge"; break;

1657 case GT: Result = "!gt"; break;

1658 case LISTCONCAT: Result = "!listconcat"; break;

1659 case LISTSPLAT: Result = "!listsplat"; break;

1661 Result = "!listremove";

1662 break;

1663 case STRCONCAT: Result = "!strconcat"; break;

1664 case INTERLEAVE: Result = "!interleave"; break;

1665 case SETDAGOP: Result = "!setdagop"; break;

1667 Result = "!setdagopname";

1668 break;

1671 break;

1673 Result = "!getdagname";

1674 break;

1675 }

1676 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";

1677}

1678

1682 ID.AddInteger(Opcode);

1683 ID.AddPointer(LHS);

1684 ID.AddPointer(MHS);

1685 ID.AddPointer(RHS);

1686 ID.AddPointer(Type);

1687}

1688

1690 const Init *MHS, const Init *RHS,

1694

1696 void *IP = nullptr;

1698 return I;

1699

1700 TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);

1702 return I;

1703}

1704

1708

1710 const Record *CurRec) {

1712 R.set(LHS, MHSe);

1713 return RHS->resolveReferences(R);

1714}

1715

1718 bool Change = false;

1721 Change = true;

1722

1724 for (auto [Arg, ArgName] : MHSd->getArgAndNames()) {

1725 const Init *NewArg;

1726

1729 else

1731

1733 if (Arg != NewArg)

1734 Change = true;

1735 }

1736

1737 if (Change)

1739 return MHSd;

1740}

1741

1742

1745 const Record *CurRec) {

1748

1751

1752 for (const Init *&Item : NewList) {

1754 if (NewItem != Item)

1755 Item = NewItem;

1756 }

1758 }

1759

1760 return nullptr;

1761}

1762

1763

1764

1767 const Record *CurRec) {

1770

1771 for (const Init *Item : MHSl->getElements()) {

1774 return nullptr;

1775 if (const auto *IncludeInt =

1778 if (IncludeInt->getValue())

1780 } else {

1781 return nullptr;

1782 }

1783 }

1785 }

1786

1787 return nullptr;

1788}

1789

1797

1801

1805

1806 if (LHSd && MHSd && RHSd) {

1807 const Record *Val = RHSd->getDef();

1808 if (LHSd->getAsString() == RHSd->getAsString())

1809 Val = MHSd->getDef();

1811 }

1812 if (LHSv && MHSv && RHSv) {

1813 std::string Val = RHSv->getName().str();

1814 if (LHSv->getAsString() == RHSv->getAsString())

1815 Val = MHSv->getName().str();

1817 }

1818 if (LHSs && MHSs && RHSs) {

1819 std::string Val = RHSs->getValue().str();

1820

1821 std:🧵:size_type Idx = 0;

1822 while (true) {

1823 std:🧵:size_type Found = Val.find(LHSs->getValue(), Idx);

1824 if (Found == std:🧵:npos)

1825 break;

1826 Val.replace(Found, LHSs->getValue().size(), MHSs->getValue().str());

1827 Idx = Found + MHSs->getValue().size();

1828 }

1829

1831 }

1832 break;

1833 }

1834

1837 return Result;

1838 break;

1839 }

1840

1843 return Result;

1844 break;

1845 }

1846

1847 case IF: {

1849 LHS->convertInitializerTo(IntRecTy::get(RK)))) {

1850 if (LHSi->getValue())

1851 return MHS;

1852 return RHS;

1853 }

1854 break;

1855 }

1856

1857 case DAG: {

1862

1864 break;

1865

1866 if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {

1868 unsigned Size = MHSl ? MHSl->size() : RHSl->size();

1869 for (unsigned i = 0; i != Size; ++i) {

1873 return this;

1875 }

1877 }

1878 break;

1879 }

1880

1885 if (!LHSi || !MHSi || !RHSi)

1886 break;

1887

1888 auto Start = LHSi->getValue();

1889 auto End = MHSi->getValue();

1890 auto Step = RHSi->getValue();

1891 if (Step == 0)

1893

1895 if (Start < End && Step > 0) {

1896 Args.reserve((End - Start) / Step);

1897 for (auto I = Start; I < End; I += Step)

1899 } else if (Start > End && Step < 0) {

1900 Args.reserve((Start - End) / -Step);

1901 for (auto I = Start; I > End; I += Step)

1903 } else {

1904

1905 }

1907 }

1908

1913 if (LHSs && MHSi && RHSi) {

1914 int64_t StringSize = LHSs->getValue().size();

1915 int64_t Start = MHSi->getValue();

1916 int64_t Length = RHSi->getValue();

1917 if (Start < 0 || Start > StringSize)

1919 Twine("!substr start position is out of range 0...") +

1920 std::to_string(StringSize) + ": " +

1921 std::to_string(Start));

1923 PrintError(CurRec->getLoc(), "!substr length must be nonnegative");

1925 LHSs->getFormat());

1926 }

1927 break;

1928 }

1929

1930 case FIND: {

1934 if (LHSs && MHSs && RHSi) {

1935 int64_t SourceSize = LHSs->getValue().size();

1936 int64_t Start = RHSi->getValue();

1937 if (Start < 0 || Start > SourceSize)

1939 Twine("!find start position is out of range 0...") +

1940 std::to_string(SourceSize) + ": " +

1941 std::to_string(Start));

1942 auto I = LHSs->getValue().find(MHSs->getValue(), Start);

1943 if (I == std:🧵:npos)

1946 }

1947 break;

1948 }

1949

1953 std::string Error;

1955 if (!ArgNo)

1957

1958 assert(*ArgNo < Dag->getNumArgs());

1959

1961 Args[*ArgNo] = RHS;

1962 return DagInit::get(Dag->getOperator(), Dag->getName(), Args,

1963 Dag->getArgNames());

1964 }

1965 break;

1966 }

1967

1971 std::string Error;

1973 if (!ArgNo)

1975

1976 assert(*ArgNo < Dag->getNumArgs());

1977

1980 return DagInit::get(Dag->getOperator(), Dag->getName(), Dag->getArgs(),

1981 Names);

1982 }

1983 break;

1984 }

1985 }

1986

1987 return this;

1988}

1989

1992

1996

1997 if (Value->getValue())

1998 return MHS->resolveReferences(R);

1999 return RHS->resolveReferences(R);

2000 }

2001 }

2002

2004 const Init *rhs;

2005

2010 } else {

2012 }

2013

2014 if (LHS != lhs || MHS != mhs || RHS != rhs)

2016 ->Fold(R.getCurrentRecord());

2017 return this;

2018}

2019

2021 std::string Result;

2022 bool UnquotedLHS = false;

2024 case DAG: Result = "!dag"; break;

2025 case FILTER: Result = "!filter"; UnquotedLHS = true; break;

2026 case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;

2027 case IF: Result = "!if"; break;

2029 Result = "!range";

2030 break;

2031 case SUBST: Result = "!subst"; break;

2032 case SUBSTR: Result = "!substr"; break;

2033 case FIND: Result = "!find"; break;

2035 Result = "!setdagarg";

2036 break;

2038 Result = "!setdagname";

2039 break;

2040 }

2041 return (Result + "(" +

2042 (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +

2043 ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")");

2044}

2045

2049 ID.AddPointer(Start);

2050 ID.AddPointer(List);

2051 ID.AddPointer(A);

2052 ID.AddPointer(B);

2053 ID.AddPointer(Expr);

2054 ID.AddPointer(Type);

2055}

2056

2058 const Init *A, const Init *B,

2062

2064 void *IP = nullptr;

2066 return I;

2067

2068 FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);

2070 return I;

2071}

2072

2076

2079 const Init *Accum = Start;

2080 for (const Init *Elt : *LI) {

2082 R.set(A, Accum);

2083 R.set(B, Elt);

2085 }

2086 return Accum;

2087 }

2088 return this;

2089}

2090

2097 const Init *NewExpr = Expr->resolveReferences(SR);

2098

2099 if (Start == NewStart && List == NewList && Expr == NewExpr)

2100 return this;

2101

2103 ->Fold(R.getCurrentRecord());

2104}

2105

2109

2111 return (Twine("!foldl(") + Start->getAsString() + ", " + List->getAsString() +

2112 ", " + A->getAsUnquotedString() + ", " + B->getAsUnquotedString() +

2113 ", " + Expr->getAsString() + ")")

2114 .str();

2115}

2116

2118 const Init *Expr) {

2120 ID.AddPointer(Expr);

2121}

2122

2124

2127

2129 void *IP = nullptr;

2131 return I;

2132

2133 IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);

2135 return I;

2136}

2137

2141

2144

2145 if (TI->getType()->typeIsConvertibleTo(CheckType))

2147

2149

2150

2151

2152 if ((!CheckType->typeIsConvertibleTo(TI->getType()) &&

2153 Expr->isConcrete()) ||

2156 } else {

2157

2159 }

2160 }

2161 return this;

2162}

2163

2165 const Init *NewExpr = Expr->resolveReferences(R);

2168 return this;

2169}

2170

2174

2176 return (Twine("!isa<") + CheckType->getAsString() + ">(" +

2177 Expr->getAsString() + ")")

2178 .str();

2179}

2180

2182 const Init *Expr) {

2184 ID.AddPointer(Expr);

2185}

2186

2188 const Init *Expr) {

2191

2193 void *IP = nullptr;

2194 if (const ExistsOpInit *I =

2196 return I;

2197

2198 ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);

2200 return I;

2201}

2202

2206

2209

2210 const Record *D = CheckType->getRecordKeeper().getDef(Name->getValue());

2211 if (D) {

2212

2214 D->getDefInit()->getType()->typeIsA(CheckType));

2215 }

2216

2217 if (CurRec) {

2218

2219

2222 (Anonymous && Name == Anonymous->getNameInit())) {

2223 if (!IsFinal)

2224 return this;

2225

2226

2227

2230 }

2231 }

2232

2233 if (IsFinal)

2235 }

2236 return this;

2237}

2238

2240 const Init *NewExpr = Expr->resolveReferences(R);

2241 if (Expr != NewExpr || R.isFinal())

2242 return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal());

2243 return this;

2244}

2245

2249

2251 return (Twine("!exists<") + CheckType->getAsString() + ">(" +

2252 Expr->getAsString() + ")")

2253 .str();

2254}

2255

2258 ID.AddPointer(Type);

2260}

2261

2263 const Init *Regex) {

2266

2268 void *IP = nullptr;

2269 if (const InstancesOpInit *I =

2271 return I;

2272

2273 InstancesOpInit *I = new (RK.Allocator) InstancesOpInit(Type, Regex);

2275 return I;

2276}

2277

2281

2283 if (CurRec && !IsFinal)

2284 return this;

2285

2287 if (!RegexInit)

2288 return this;

2289

2290 StringRef RegexStr = RegexInit->getValue();

2292 if (!Matcher.isValid())

2294

2295 const RecordKeeper &RK = Type->getRecordKeeper();

2298 if (Matcher.match(Def->getName()))

2299 Selected.push_back(Def->getDefInit());

2300

2302}

2303

2306 if (Regex != NewRegex || R.isFinal())

2307 return get(Type, NewRegex)->Fold(R.getCurrentRecord(), R.isFinal());

2308 return this;

2309}

2310

2314

2316 return "!instances<" + Type->getAsString() + ">(" + Regex->getAsString() +

2317 ")";

2318}

2319

2323 if (const RecordVal *Field = Rec->getValue(FieldName))

2324 return Field->getType();

2325 }

2326 }

2327 return nullptr;

2328}

2329

2332 return this;

2333

2337

2338 return nullptr;

2339}

2340

2344 if (T) return nullptr;

2345 unsigned NumBits = T->getNumBits();

2346

2348 NewBits.reserve(Bits.size());

2349 for (unsigned Bit : Bits) {

2350 if (Bit >= NumBits)

2351 return nullptr;

2352

2354 }

2356}

2357

2359

2361 return this;

2362

2366 return Converted;

2367 }

2368

2369 if (getType()->typeIsConvertibleTo(Ty))

2370 return nullptr;

2371

2373}

2374

2379

2383 if (I)

2385 return I;

2386}

2387

2390 return NameString->getValue();

2391}

2392

2398

2400 if (const Init *Val = R.resolve(VarName))

2401 return Val;

2402 return this;

2403}

2404

2408 if (I)

2410 return I;

2411}

2412

2414 return TI->getAsString() + "{" + utostr(Bit) + "}";

2415}

2416

2418 const Init *I = TI->resolveReferences(R);

2419 if (TI != I)

2421

2422 return this;

2423}

2424

2425DefInit::DefInit(const Record *D)

2427

2430 if (getType()->typeIsConvertibleTo(RRT))

2431 return this;

2432 return nullptr;

2433}

2434

2437 return RV->getType();

2438 return nullptr;

2439}

2440

2442

2445 ID.AddInteger(Args.size());

2446 ID.AddPointer(Class);

2447

2448 for (const Init *I : Args)

2449 ID.AddPointer(I);

2450}

2451

2452VarDefInit::VarDefInit(SMLoc Loc, const Record *Class,

2457}

2458

2463

2465 void *IP = nullptr;

2467 return I;

2468

2469 void *Mem = RK.Allocator.Allocate(

2471 VarDefInit *I = new (Mem) VarDefInit(Loc, Class, Args);

2473 return I;

2474}

2475

2479

2480const DefInit *VarDefInit::instantiate() {

2481 if (Def)

2482 return Def;

2483

2484 RecordKeeper &Records = Class->getRecords();

2485 auto NewRecOwner = std::make_unique(

2487 Record *NewRec = NewRecOwner.get();

2488

2489

2490 for (const RecordVal &Val : Class->getValues())

2492

2493

2495

2496

2498

2499

2502

2503 for (const Init *Arg : TArgs) {

2506 }

2507

2508 for (auto *Arg : args()) {

2509 if (Arg->isPositional())

2510 R.set(TArgs[Arg->getIndex()], Arg->getValue());

2511 if (Arg->isNamed())

2512 R.set(Arg->getName(), Arg->getValue());

2513 }

2514

2516

2517

2519 Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));

2520

2521

2523 Records.addDef(std::move(NewRecOwner));

2524

2525

2527

2528

2530

2532}

2533

2539

2541 const auto *NewArg = cast(Arg->resolveReferences(UR));

2543 Changed |= NewArg != Arg;

2544 }

2545

2549 return const_cast<VarDefInit *>(New)->instantiate();

2550 return New;

2551 }

2552 return this;

2553}

2554

2556 if (Def)

2557 return Def;

2558

2560 for (const Init *Arg : args())

2561 Arg->resolveReferences(R);

2562

2563 if (!R.foundUnresolved())

2564 return const_cast<VarDefInit *>(this)->instantiate();

2565 return this;

2566}

2567

2569 std::string Result = Class->getNameInitAsString() + "<";

2571 for (const Init *Arg : args()) {

2572 Result += LS;

2573 Result += Arg->getAsString();

2574 }

2575 return Result + ">";

2576}

2577

2581 if (I)

2582 I = new (RK.Allocator) FieldInit(R, FN);

2583 return I;

2584}

2585

2591

2594 if (NewRec != Rec)

2595 return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());

2596 return this;

2597}

2598

2601 const Record *Def = DI->getDef();

2602 if (Def == CurRec)

2604 Twine("Attempting to access field '") +

2605 FieldName->getAsUnquotedString() + "' of '" +

2606 Rec->getAsString() + "' is a forbidden self-reference");

2607 const Init *FieldVal = Def->getValue(FieldName)->getValue();

2609 return FieldVal;

2610 }

2611 return this;

2612}

2613

2616 const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();

2618 }

2619 return false;

2620}

2621

2625 const RecTy *ValType) {

2627 "Number of conditions and values must match!");

2628 ID.AddPointer(ValType);

2629

2630 for (const auto &[Cond, Val] : zip(Conds, Vals)) {

2631 ID.AddPointer(Cond);

2632 ID.AddPointer(Val);

2633 }

2634}

2635

2642}

2643

2647

2650 const RecTy *Ty) {

2652 "Number of conditions and values must match!");

2653

2656

2658 void *IP = nullptr;

2660 return I;

2661

2662 void *Mem = RK.Allocator.Allocate(

2664 CondOpInit *I = new (Mem) CondOpInit(Conds, Values, Ty);

2666 return I;

2667}

2668

2672

2675 const Init *NewCond = Cond->resolveReferences(R);

2678

2681 Changed |= NewVal != Val;

2682 }

2683

2686 getValType()))->Fold(R.getCurrentRecord());

2687

2688 return this;

2689}

2690

2696 if (CondI->getValue())

2697 return Val->convertInitializerTo(getValType());

2698 } else {

2699 return this;

2700 }

2701 }

2702

2705 " does not have any true condition in:" +

2706 this->getAsString());

2707 return nullptr;

2708}

2709

2712 return std::get<0>(Pair)->isConcrete() && std::get<1>(Pair)->isConcrete();

2713 });

2714}

2715

2718 return std::get<0>(Pair)->isComplete() && std::get<1>(Pair)->isComplete();

2719 });

2720}

2721

2723 std::string Result = "!cond(";

2726 Result += LS;

2727 Result += Cond->getAsString() + ": ";

2728 Result += Val->getAsString();

2729 }

2730 return Result + ")";

2731}

2732

2736

2740 ID.AddPointer(V);

2741 ID.AddPointer(VN);

2742

2743 for (auto [Arg, Name] : zip_equal(Args, ArgNames)) {

2744 ID.AddPointer(Arg);

2745 ID.AddPointer(Name);

2746 }

2747}

2748

2749DagInit::DagInit(const Init *V, const StringInit *VN,

2753 ValName(VN), NumArgs(Args.size()) {

2756}

2757

2761 assert(Args.size() == ArgNames.size() &&

2762 "Number of DAG args and arg names must match!");

2763

2766

2768 void *IP = nullptr;

2770 return I;

2771

2772 void *Mem =

2774 Args.size(), ArgNames.size()),

2775 alignof(DagInit));

2776 DagInit *I = new (Mem) DagInit(V, VN, Args, ArgNames);

2778 return I;

2779}

2780

2783 ArrayRef<std::pair<const Init *, const StringInit *>> ArgAndNames) {

2787}

2788

2792

2795 return DefI->getDef();

2797 return nullptr;

2798}

2799

2803 return ArgName && ArgName->getValue() == Name;

2804 });

2805 if (It == ArgNames.end())

2806 return std::nullopt;

2807 return std::distance(ArgNames.begin(), It);

2808}

2809

2813 bool ArgsChanged = false;

2817 ArgsChanged |= NewArg != Arg;

2818 }

2819

2820 const Init *Op = Val->resolveReferences(R);

2821 if (Op != Val || ArgsChanged)

2823

2824 return this;

2825}

2826

2828 if (!Val->isConcrete())

2829 return false;

2831}

2832

2834 std::string Result = "(" + Val->getAsString();

2835 if (ValName)

2836 Result += ":$" + ValName->getAsUnquotedString();

2838 Result += " ";

2841 Result += LS;

2842 Result += Arg->getAsString();

2843 if (Name)

2844 Result += ":$" + Name->getAsUnquotedString();

2845 }

2846 }

2847 return Result + ")";

2848}

2849

2850

2851

2852

2853

2855 : Name(N), TyAndKind(T, K) {

2857 assert(Value && "Cannot create unset value for current type!");

2858}

2859

2860

2861

2863 : Name(N), Loc(Loc), TyAndKind(T, K) {

2865 assert(Value && "Cannot create unset value for current type!");

2866}

2867

2871

2875 if (StrInit->hasCodeFormat())

2876 return "code";

2877 else

2878 return "string";

2879 } else {

2880 return "string";

2881 }

2882 } else {

2883 return TyAndKind.getPointer()->getAsString();

2884 }

2885}

2886

2888 if (!V) {

2889 Value = nullptr;

2890 return false;

2891 }

2892

2893 Value = V->getCastTo(getType());

2894 if (!Value)

2895 return true;

2896

2901 return false;

2903 for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)

2904 Bits[I] = Value->getBit(I);

2905 Value = BitsInit::get(V->getRecordKeeper(), Bits);

2906 }

2907

2908 return false;

2909}

2910

2911

2912

2917

2918#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

2920#endif

2921

2925

2928

2929 if (PrintSem) OS << ";\n";

2930}

2931

2933 assert(Locs.size() == 1);

2934 ForwardDeclarationLocs.push_back(Locs.front());

2935

2936 Locs.clear();

2937 Locs.push_back(Loc);

2938}

2939

2940void Record::checkName() {

2941

2945 "' is not a string!");

2946}

2947

2953

2955 if (!CorrespondingDefInit) {

2956 CorrespondingDefInit =

2957 new (TrackedRecords.getImpl().Allocator) DefInit(this);

2958 }

2959 return CorrespondingDefInit;

2960}

2961

2965

2967 Name = NewName;

2968 checkName();

2969

2970

2971

2972

2973

2974

2975

2976

2977

2978

2979

2980}

2981

2985 if (NewName != OldName) {

2986

2988 }

2989

2990

2992 if (SkipVal == &Value)

2993 continue;

2994 if (const Init *V = Value.getValue()) {

2996 if (Value.setValue(VR)) {

2997 std::string Type;

3000 (Twine("of type '") + VRT->getType()->getAsString() + "' ").str();

3003 Twine("Invalid value ") + Type + "found when setting field '" +

3004 Value.getNameInitAsString() + "' of type '" +

3007 "\n");

3008 }

3009 }

3010 }

3011

3012

3014 const Init *Value = Assertion.Condition->resolveReferences(R);

3015 Assertion.Condition = Value;

3016 Value = Assertion.Message->resolveReferences(R);

3017 Assertion.Message = Value;

3018 }

3019

3020 for (DumpInfo &Dump : Dumps) {

3021 const Init *Value = Dump.Message->resolveReferences(R);

3022 Dump.Message = Value;

3023 }

3024}

3025

3028 R.setName(NewName);

3029 R.setFinal(true);

3031}

3032

3033#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

3035#endif

3036

3038 OS << R.getNameInitAsString();

3039

3041 if (!TArgs.empty()) {

3042 OS << "<";

3044 for (const Init *TA : TArgs) {

3045 const RecordVal *RV = R.getValue(TA);

3046 assert(RV && "Template argument record not found??");

3047 OS << LS;

3048 RV->print(OS, false);

3049 }

3050 OS << ">";

3051 }

3052

3053 OS << " {";

3054 std::vector<const Record *> SCs = R.getSuperClasses();

3055 if (!SCs.empty()) {

3056 OS << "\t//";

3057 for (const Record *SC : SCs)

3058 OS << " " << SC->getNameInitAsString();

3059 }

3060 OS << "\n";

3061

3062 for (const RecordVal &Val : R.getValues())

3063 if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))

3064 OS << Val;

3065 for (const RecordVal &Val : R.getValues())

3066 if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))

3067 OS << Val;

3068

3069 return OS << "}\n";

3070}

3071

3074 if (!R)

3076 "' does not have a field named `" + FieldName + "'!\n");

3077 return R->getLoc();

3078}

3079

3082 if (!R || !R->getValue())

3084 "' does not have a field named `" + FieldName + "'!\n");

3085 return R->getValue();

3086}

3087

3091 return SI->getValue();

3093 "' exists but does not have a string value");

3094}

3095

3096std::optional

3099 if (!R || !R->getValue())

3100 return std::nullopt;

3102 return std::nullopt;

3103

3105 return SI->getValue();

3106

3108 "Record `" + getName() + "', ` field `" + FieldName +

3109 "' exists but does not have a string initializer!");

3110}

3111

3115 return BI;

3117 "' exists but does not have a bits value");

3118}

3119

3123 return LI;

3125 "' exists but does not have a list value");

3126}

3127

3128std::vector<const Record *>

3131 std::vector<const Record *> Defs;

3132 for (const Init *I : List->getElements()) {

3134 Defs.push_back(DI->getDef());

3135 else

3137 FieldName +

3138 "' list is not entirely DefInit!");

3139 }

3140 return Defs;

3141}

3142

3146 return II->getValue();

3149 Twine("Record `") + getName() + "', field `" + FieldName +

3150 "' exists but does not have an int value: " + I->getAsString());

3151}

3152

3153std::vector<int64_t>

3156 std::vector<int64_t> Ints;

3157 for (const Init *I : List->getElements()) {

3159 Ints.push_back(II->getValue());

3160 else

3162 Twine("Record `") + getName() + "', field `" + FieldName +

3163 "' exists but does not have a list of ints value: " +

3164 I->getAsString());

3165 }

3166 return Ints;

3167}

3168

3169std::vector

3172 std::vector Strings;

3173 for (const Init *I : List->getElements()) {

3175 Strings.push_back(SI->getValue());

3176 else

3178 Twine("Record `") + getName() + "', field `" + FieldName +

3179 "' exists but does not have a list of strings value: " +

3180 I->getAsString());

3181 }

3182 return Strings;

3183}

3184

3188 return DI->getDef();

3190 FieldName + "' does not have a def initializer!");

3191}

3192

3196 return DI->getDef();

3198 return nullptr;

3200 FieldName + "' does not have either a def initializer or '?'!");

3201}

3202

3206 return BI->getValue();

3208 FieldName + "' does not have a bit initializer!");

3209}

3210

3215 return false;

3216 }

3219 return BI->getValue();

3221 FieldName + "' does not have a bit initializer!");

3222}

3223

3227 return DI;

3229 FieldName + "' does not have a dag initializer!");

3230}

3231

3232

3233

3234

3235

3238 R.setFinal(true);

3239

3240 bool AnyFailed = false;

3244 AnyFailed |= CheckAssert(Assertion.Loc, Condition, Message);

3245 }

3246

3247 if (!AnyFailed)

3248 return;

3249

3250

3251

3252 PrintError(this, "assertion failed in this record");

3253}

3254

3257 R.setFinal(true);

3258

3260 const Init *Message = Dump.Message->resolveReferences(R);

3262 }

3263}

3264

3265

3271 "unused template argument: " + Twine(Arg->getName()));

3272 }

3273}

3274

3276 : Impl(std::make_unique<detail::RecordKeeperImpl>(*this)),

3277 Timer(std::make_unique<TGTimer>()) {}

3278

3280

3281#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

3283#endif

3284

3286 OS << "------------- Classes -----------------\n";

3288 OS << "class " << *C;

3289

3290 OS << "------------- Defs -----------------\n";

3291 for (const auto &[_, D] : RK.getDefs())

3292 OS << "def " << *D;

3293 return OS;

3294}

3295

3296

3297

3301

3304

3305

3306 auto [Iter, Inserted] = Cache.try_emplace(ClassName.str());

3307 if (Inserted)

3309 return Iter->second;

3310}

3311

3312std::vector<const Record *>

3315 std::vector<const Record *> Defs;

3316

3317 assert(ClassNames.size() > 0 && "At least one class must be passed.");

3318 for (StringRef ClassName : ClassNames) {

3320 if (!Class)

3321 PrintFatalError("The class '" + ClassName + "' is not defined\n");

3323 }

3324

3325 for (const auto &OneDef : getDefs()) {

3326 if (all_of(ClassRecs, [&OneDef](const Record *Class) {

3327 return OneDef.second->isSubClassOf(Class);

3328 }))

3329 Defs.push_back(OneDef.second.get());

3330 }

3332 return Defs;

3333}

3334

3339 return Cache[""];

3340}

3341

3343 Impl->dumpAllocationStats(OS);

3344}

3345

3347 auto It = Map.find(VarName);

3348 if (It == Map.end())

3349 return nullptr;

3350

3351 const Init *I = It->second.V;

3352

3353 if (!It->second.Resolved && Map.size() > 1) {

3354

3355

3356 Map.erase(It);

3357 I = I->resolveReferences(*this);

3358 Map[VarName] = {I, true};

3359 }

3360

3361 return I;

3362}

3363

3365 const Init *Val = Cache.lookup(VarName);

3366 if (Val)

3367 return Val;

3368

3370 return nullptr;

3371

3374 Val = RV->getValue();

3375 Stack.push_back(VarName);

3377 Stack.pop_back();

3378 }

3379 } else if (Name && VarName == getCurrentRecord()->getNameInit()) {

3380 Stack.push_back(VarName);

3382 Stack.pop_back();

3383 }

3384

3385 Cache[VarName] = Val;

3386 return Val;

3387}

3388

3390 const Init *I = nullptr;

3391

3392 if (R) {

3393 I = R->resolve(VarName);

3394 if (I && !FoundUnresolved) {

3395

3396

3397

3399 I->resolveReferences(Sub);

3400 FoundUnresolved |= Sub.FoundUnresolved;

3401 }

3402 }

3403

3404 if (I)

3405 FoundUnresolved = true;

3406 return I;

3407}

3408

3410 if (VarName == VarNameToTrack)

3411 Found = true;

3412 return nullptr;

3413}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file defines the StringMap class.

This file defines the BumpPtrAllocator interface.

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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.

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

uint64_t IntrinsicInst * II

OptimizedStructLayoutField Field

const SmallVectorImpl< MachineOperand > & Cond

static void ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Range)

Definition Record.cpp:458

static bool canFitInBitfield(int64_t Value, unsigned NumBits)

Definition Record.cpp:613

static void ProfileCondOpInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Conds, ArrayRef< const Init * > Vals, const RecTy *ValType)

Definition Record.cpp:2622

static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef< const Init * > Elements, const RecTy *EltTy)

Definition Record.cpp:698

static std::optional< unsigned > getDagArgNoByKey(const DagInit *Dag, const Init *Key, std::string &Error)

Definition Record.cpp:1271

static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *LHS, const Init *RHS, const RecTy *Type)

Definition Record.cpp:1086

static const StringInit * ConcatStringInits(const StringInit *I0, const StringInit *I1)

Definition Record.cpp:1114

static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type)

Definition Record.cpp:1679

static void ProfileExistsOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)

Definition Record.cpp:2181

static const ListInit * ConcatListInits(const ListInit *LHS, const ListInit *RHS)

Definition Record.cpp:1175

static const StringInit * interleaveStringList(const ListInit *List, const StringInit *Delim)

Definition Record.cpp:1123

static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)

Definition Record.cpp:2737

static void ProfileFoldOpInit(FoldingSetNodeID &ID, const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)

Definition Record.cpp:2046

static void ProfileInstancesOpInit(FoldingSetNodeID &ID, const RecTy *Type, const Init *Regex)

Definition Record.cpp:2256

static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, const Init *Op, const RecTy *Type)

Definition Record.cpp:817

static void ProfileArgumentInit(FoldingSetNodeID &ID, const Init *Value, ArgAuxType Aux)

Definition Record.cpp:399

static const Init * ForeachDagApply(const Init *LHS, const DagInit *MHSd, const Init *RHS, const Record *CurRec)

Definition Record.cpp:1716

static const Init * FilterHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)

Definition Record.cpp:1765

static const Init * ItemApply(const Init *LHS, const Init *MHSe, const Init *RHS, const Record *CurRec)

Definition Record.cpp:1709

static const RecordRecTy * resolveRecordTypes(const RecordRecTy *T1, const RecordRecTy *T2)

Definition Record.cpp:325

static void ProfileRecordRecTy(FoldingSetNodeID &ID, ArrayRef< const Record * > Classes)

Definition Record.cpp:230

static const Init * ForeachHelper(const Init *LHS, const Init *MHS, const Init *RHS, const RecTy *Type, const Record *CurRec)

Definition Record.cpp:1743

static void ProfileVarDefInit(FoldingSetNodeID &ID, const Record *Class, ArrayRef< const ArgumentInit * > Args)

Definition Record.cpp:2443

static void ProfileIsAOpInit(FoldingSetNodeID &ID, const RecTy *CheckType, const Init *Expr)

Definition Record.cpp:2117

static const StringInit * interleaveIntList(const ListInit *List, const StringInit *Delim)

Definition Record.cpp:1144

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)

Definition Record.cpp:658

const StringInit * getNameInit() const

Definition Record.cpp:662

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...

Definition Record.cpp:670

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:666

const ArgumentInit * cloneWithValue(const Init *Value) const

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:410

static const ArgumentInit * get(const Init *Value, ArgAuxType Aux)

Definition Record.cpp:414

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...

Definition Record.cpp:430

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

static const BinOpInit * get(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)

Definition Record.cpp:1095

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:1110

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...

Definition Record.cpp:1602

static const Init * getStrConcat(const Init *lhs, const Init *rhs)

Definition Record.cpp:1166

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:1630

BinaryOp getOpcode() const

const Init * getRHS() const

std::optional< bool > CompareInit(unsigned Opc, const Init *LHS, const Init *RHS) const

Definition Record.cpp:1193

const Init * getLHS() const

static const Init * getListConcat(const TypedInit *lhs, const Init *rhs)

Definition Record.cpp:1183

const Init * Fold(const Record *CurRec) const

Definition Record.cpp:1303

'true'/'false' - Represent a concrete initializer for a bit.

static BitInit * get(RecordKeeper &RK, bool V)

Definition Record.cpp:438

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:442

'bit' - Represent a single bit

static const BitRecTy * get(RecordKeeper &RK)

Definition Record.cpp:151

bool typeIsConvertibleTo(const RecTy *RHS) const override

Return true if all values of 'this' type can be converted to the specified type.

Definition Record.cpp:155

'{ a, b, c }' - Represents an initializer for a BitsRecTy value.

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:488

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:554

bool isComplete() const override

Is this a complete value with no unset (uninitialized) subvalues?

Definition Record.cpp:544

unsigned getNumBits() const

std::optional< int64_t > convertInitializerToInt() const

Definition Record.cpp:514

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.

Definition Record.cpp:533

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...

Definition Record.cpp:569

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:492

ArrayRef< const Init * > getBits() const

uint64_t convertKnownBitsToInt() const

Definition Record.cpp:524

bool allInComplete() const

Definition Record.cpp:547

static BitsInit * get(RecordKeeper &RK, ArrayRef< const Init * > Range)

Definition Record.cpp:472

bool isConcrete() const override

Is this a concrete and fully resolved value without any references or stuck operations?

Definition Record.cpp:550

'bits' - 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.

Definition Record.cpp:177

static const BitsRecTy * get(RecordKeeper &RK, unsigned Sz)

Definition Record.cpp:163

std::string getAsString() const override

Definition Record.cpp:173

const Init * Fold(const Record *CurRec) const

Definition Record.cpp:2691

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...

Definition Record.cpp:2669

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2733

bool isConcrete() const override

Is this a concrete and fully resolved value without any references or stuck operations?

Definition Record.cpp:2710

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2644

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2722

static const CondOpInit * get(ArrayRef< const Init * > Conds, ArrayRef< const Init * > Values, const RecTy *Type)

Definition Record.cpp:2648

const RecTy * getValType() const

bool isComplete() const override

Is this a complete value with no unset (uninitialized) subvalues?

Definition Record.cpp:2716

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?

Definition Record.cpp:2827

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...

Definition Record.cpp:2800

const StringInit * getName() const

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2789

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...

Definition Record.cpp:2810

ArrayRef< const StringInit * > getArgNames() const

static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)

Definition Record.cpp:2758

const Record * getOperatorAsDef(ArrayRef< SMLoc > Loc) const

Definition Record.cpp:2793

auto getArgAndNames() const

ArrayRef< const Init * > getArgs() const

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2833

'dag' - Represent a dag fragment

std::string getAsString() const override

Definition Record.cpp:226

static const DagRecTy * get(RecordKeeper &RK)

Definition Record.cpp:222

AL - Represent a reference to a 'def' in the description.

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2441

const RecTy * getFieldType(const StringInit *FieldName) const override

This function is used to implement the FieldInit class.

Definition Record.cpp:2435

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:2428

Lightweight error class with error context and mandatory checking.

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2203

static const ExistsOpInit * get(const RecTy *CheckType, const Init *Expr)

Definition Record.cpp:2187

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2250

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...

Definition Record.cpp:2239

const Init * Fold(const Record *CurRec, bool IsFinal=false) const

Definition Record.cpp:2207

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2246

X.Y - Represent a reference to a subfield of a variable.

const Init * Fold(const Record *CurRec) const

Definition Record.cpp:2599

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2586

static const FieldInit * get(const Init *R, const StringInit *FN)

Definition Record.cpp:2578

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...

Definition Record.cpp:2592

bool isConcrete() const override

Is this a concrete and fully resolved value without any references or stuck operations?

Definition Record.cpp:2614

const Init * Fold(const Record *CurRec) const

Definition Record.cpp:2077

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2110

static const FoldOpInit * get(const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)

Definition Record.cpp:2057

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2106

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...

Definition Record.cpp:2091

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2073

void InsertNode(T *N, void *InsertPos)

InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...

T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)

FindNodeOrInsertPos - Look up the node specified by ID.

FoldingSetNodeID - This class is used to gather all the unique data bits of a node.

FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...

const Init * resolve(const Init *VarName) override

Return the initializer for the given variable name (should normally be a StringInit),...

Definition Record.cpp:3409

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.

Definition Record.cpp:378

void print(raw_ostream &OS) const

Print this value.

virtual std::string getAsString() const =0

Convert this value to a literal form.

virtual bool isConcrete() const

Is this a concrete and fully resolved value without any references or stuck operations?

virtual bool isComplete() const

Is this a complete value with no unset (uninitialized) subvalues?

virtual const Init * getBit(unsigned Bit) const =0

Get the Init value of the specified bit.

virtual const Init * convertInitializerTo(const RecTy *Ty) const =0

Convert to a value whose type is Ty, or return null if this is not possible.

RecordKeeper & getRecordKeeper() const

Get the record keeper that initialized this Init.

Definition Record.cpp:381

Init(InitKind K, uint8_t Opc=0)

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2278

const Init * Fold(const Record *CurRec, bool IsFinal=false) const

Definition Record.cpp:2282

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2311

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...

Definition Record.cpp:2304

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2315

static const InstancesOpInit * get(const RecTy *Type, const Init *Regex)

Definition Record.cpp:2262

static IntInit * get(RecordKeeper &RK, int64_t V)

Definition Record.cpp:602

const Init * convertInitializerBitRange(ArrayRef< unsigned > Bits) const override

This function is used to implement the bit range selection operator.

Definition Record.cpp:646

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:609

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:619

'int' - Represent an integer value of no particular size

static const IntRecTy * get(RecordKeeper &RK)

Definition Record.cpp:184

bool typeIsConvertibleTo(const RecTy *RHS) const override

Return true if all values of 'this' type can be converted to the specified type.

Definition Record.cpp:188

static const IsAOpInit * get(const RecTy *CheckType, const Init *Expr)

Definition Record.cpp:2123

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2138

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...

Definition Record.cpp:2164

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2175

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2171

const Init * Fold() const

Definition Record.cpp:2142

[AL, AH, CL] - Represent a list of defs

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:801

const RecTy * getElementType() const

static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)

Definition Record.cpp:714

bool isConcrete() const override

Is this a concrete and fully resolved value without any references or stuck operations?

Definition Record.cpp:796

bool isComplete() const override

Is this a complete value with no unset (uninitialized) subvalues?

Definition Record.cpp:791

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...

Definition Record.cpp:775

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:739

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:734

const Record * getElementAsRecord(unsigned Idx) const

Definition Record.cpp:768

ArrayRef< const Init * > getElements() const

const Init * getElement(unsigned Idx) const

'list' - 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.

Definition Record.cpp:216

std::string getAsString() const override

Definition Record.cpp:206

bool typeIsConvertibleTo(const RecTy *RHS) const override

Return true if all values of 'this' type can be converted to the specified type.

Definition Record.cpp:210

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),...

Definition Record.cpp:3346

const Init * getBit(unsigned Bit) const final

Get the Init value of the specified bit.

Definition Record.cpp:811

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.

Definition Record.cpp:149

virtual bool typeIsConvertibleTo(const RecTy *RHS) const

Return true if all values of 'this' type can be converted to the specified type.

Definition Record.cpp:144

RecTyKind

Subclass discriminator (for dyn_cast<> et al.)

RecTy(RecTyKind K, RecordKeeper &RK)

virtual std::string getAsString() const =0

void dump() const

Definition Record.cpp:135

const ListRecTy * getListTy() const

Returns the type representing list.

Definition Record.cpp:138

RecordKeeper()

Definition Record.cpp:3275

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.

Definition Record.cpp:3298

const RecordMap & getDefs() const

Get the map of records (defs).

void dump() const

Definition Record.cpp:3282

detail::RecordKeeperImpl & getImpl()

Return the internal implementation of the RecordKeeper.

void dumpAllocationStats(raw_ostream &OS) const

Definition Record.cpp:3342

ArrayRef< const Record * > getAllDerivedDefinitionsIfDefined(StringRef ClassName) const

Get all the concrete records that inherit from specified class, if the class is defined.

Definition Record.cpp:3336

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.

Definition Record.cpp:3303

'[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.

Definition Record.cpp:308

bool isSubClassOf(const Record *Class) const

Definition Record.cpp:302

ArrayRef< const Record * > getClasses() const

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:284

std::string getAsString() const override

Definition Record.cpp:288

bool typeIsA(const RecTy *RHS) const override

Return true if 'this' type is equal to or a subtype of RHS.

Definition Record.cpp:321

static const RecordRecTy * get(RecordKeeper &RK, ArrayRef< const Record * > Classes)

Get the record type with the given non-redundant list of superclasses.

Definition Record.cpp:242

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),...

Definition Record.cpp:3364

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.

Definition Record.cpp:2887

RecordKeeper & getRecordKeeper() const

Get the record keeper used to unique this value.

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.

void dump() const

Definition Record.cpp:2919

StringRef getName() const

Get the name of the field as a StringRef.

Definition Record.cpp:2868

void print(raw_ostream &OS, bool PrintSem=true) const

Print the value to an output stream, possibly with a semicolon.

Definition Record.cpp:2922

RecordVal(const Init *N, const RecTy *T, FieldKind K)

Definition Record.cpp:2854

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.

Definition Record.cpp:2872

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,...

Definition Record.cpp:3154

const RecordRecTy * getType() const

Definition Record.cpp:2948

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...

Definition Record.cpp:3080

bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const

This method looks up the specified field and returns its value as a bit.

Definition Record.cpp:3211

bool getValueAsBit(StringRef FieldName) const

This method looks up the specified field and returns its value as a bit, throwing an exception if the...

Definition Record.cpp:3203

static unsigned getNewUID(RecordKeeper &RK)

Definition Record.cpp:2962

ArrayRef< SMLoc > getLoc() const

void checkUnusedTemplateArgs()

Definition Record.cpp:3266

void emitRecordDumps()

Definition Record.cpp:3255

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,...

Definition Record.cpp:3129

ArrayRef< AssertionInfo > getAssertions() const

std::string getNameInitAsString() const

void dump() const

Definition Record.cpp:3034

const Record * getValueAsDef(StringRef FieldName) const

This method looks up the specified field and returns its value as a Record, throwing an exception if ...

Definition Record.cpp:3185

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...

Definition Record.cpp:3224

std::vector< StringRef > getValueAsListOfStrings(StringRef FieldName) const

This method looks up the specified field and returns its value as a vector of strings,...

Definition Record.cpp:3170

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...

Definition Record.cpp:3193

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)

Definition Record.cpp:2966

const ListInit * getValueAsListInit(StringRef FieldName) const

This method looks up the specified field and returns its value as a ListInit, throwing an exception i...

Definition Record.cpp:3120

void appendDumps(const Record *Rec)

bool isSubClassOf(const Record *R) const

DefInit * getDefInit() const

get the corresponding DefInit.

Definition Record.cpp:2954

SMLoc getFieldLoc(StringRef FieldName) const

Return the source location for the named field.

Definition Record.cpp:3072

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...

Definition Record.cpp:3026

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 ...

Definition Record.cpp:3097

void removeValue(const Init *Name)

ArrayRef< const Init * > getTemplateArgs() const

void updateClassLoc(SMLoc Loc)

Definition Record.cpp:2932

const BitsInit * getValueAsBitsInit(StringRef FieldName) const

This method looks up the specified field and returns its value as a BitsInit, throwing an exception i...

Definition Record.cpp:3112

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...

Definition Record.cpp:3143

void checkRecordAssertions()

Definition Record.cpp:3236

StringRef getValueAsString(StringRef FieldName) const

This method looks up the specified field and returns its value as a string, throwing an exception if ...

Definition Record.cpp:3088

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)

Definition Record.cpp:680

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.

Definition Record.cpp:691

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

Definition Record.cpp:197

static const StringRecTy * get(RecordKeeper &RK)

Definition Record.cpp:193

bool typeIsConvertibleTo(const RecTy *RHS) const override

Return true if all values of 'this' type can be converted to the specified type.

Definition Record.cpp:201

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

const Init * Fold(const Record *CurRec) const

Definition Record.cpp:1790

const Init * getLHS() const

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:1705

const Init * getMHS() const

const Init * getRHS() const

static const TernOpInit * get(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs, const RecTy *Type)

Definition Record.cpp:1689

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2020

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...

Definition Record.cpp:1990

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),...

Definition Record.cpp:3389

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.

Definition Record.cpp:2320

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.

Definition Record.cpp:2342

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 !...

Definition Record.cpp:2358

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:2330

const RecTy * getType() const

Get the type of the Init as a RecTy.

const Init * getOperand() const

UnaryOp getOpcode() const

static const UnOpInit * get(UnaryOp opc, const Init *lhs, const RecTy *Type)

Definition Record.cpp:824

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:838

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...

Definition Record.cpp:1044

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:1053

const Init * Fold(const Record *CurRec, bool IsFinal=false) const

Definition Record.cpp:842

'?' - 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 !...

Definition Record.cpp:393

const Init * convertInitializerTo(const RecTy *Ty) const override

Convert to a value whose type is Ty, or return null if this is not possible.

Definition Record.cpp:395

static UnsetInit * get(RecordKeeper &RK)

Get the singleton unset Init.

Definition Record.cpp:389

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)

Definition Record.cpp:2405

unsigned getBitNum() const

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2413

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...

Definition Record.cpp:2417

ArrayRef< const ArgumentInit * > args() const

static const VarDefInit * get(SMLoc Loc, const Record *Class, ArrayRef< const ArgumentInit * > Args)

Definition Record.cpp:2459

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...

Definition Record.cpp:2534

const Init * Fold() const

Definition Record.cpp:2555

void Profile(FoldingSetNodeID &ID) const

Definition Record.cpp:2476

std::string getAsString() const override

Convert this value to a literal form.

Definition Record.cpp:2568

'Opcode' - Represent a reference to an entire variable object.

static const VarInit * get(StringRef VN, const RecTy *T)

Definition Record.cpp:2375

const Init * getBit(unsigned Bit) const override

Get the Init value of the specified bit.

Definition Record.cpp:2393

StringRef getName() const

Definition Record.cpp:2388

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...

Definition Record.cpp:2399

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records

This is an optimization pass for GlobalISel generic memory operations.

detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)

zip iterator for two or more iteratable types.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

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.

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 - Return the argument parameter cast to the specified type.

void PrintFatalError(const Twine &Msg)

void PrintError(const Twine &Msg)

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

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.

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.

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.

FunctionAddr VTableAddr Count

bool isa(const From &Val)

isa - 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.

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.

void dumpMessage(SMLoc Loc, const Init *Message)

decltype(auto) cast(const From &Val)

cast - 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.

Definition Record.cpp:342

BumpPtrAllocatorImpl<> BumpPtrAllocator

The standard BumpPtrAllocator which just uses the default template parameters.

std::variant< unsigned, const Init * > ArgAuxType

std::string itostr(int64_t X)

Implement std::hash so that hash_code can be used in STL containers.

This class represents the internal implementation of the RecordKeeper.

Definition Record.cpp:53

unsigned LastRecordID

Definition Record.cpp:97

StringMap< const StringInit *, BumpPtrAllocator & > StringInitCodePool

Definition Record.cpp:77

BitInit FalseBitInit

Definition Record.cpp:71

StringRecTy SharedStringRecTy

Definition Record.cpp:65

FoldingSet< ListInit > TheListInitPool

Definition Record.cpp:78

FoldingSet< BitsInit > TheBitsInitPool

Definition Record.cpp:74

BumpPtrAllocator Allocator

Definition Record.cpp:61

std::map< int64_t, IntInit * > TheIntInitPool

Definition Record.cpp:75

FoldingSet< ArgumentInit > TheArgumentInitPool

Definition Record.cpp:73

UnsetInit TheUnsetInit

Definition Record.cpp:69

RecordRecTy AnyRecord

Definition Record.cpp:68

FoldingSet< UnOpInit > TheUnOpInitPool

Definition Record.cpp:79

DenseMap< std::pair< const Init *, const StringInit * >, FieldInit * > TheFieldInitPool

Definition Record.cpp:91

std::vector< BitsRecTy * > SharedBitsRecTys

Definition Record.cpp:62

BitInit TrueBitInit

Definition Record.cpp:70

FoldingSet< RecordRecTy > RecordTypePool

Definition Record.cpp:94

FoldingSet< VarDefInit > TheVarDefInitPool

Definition Record.cpp:89

RecordKeeperImpl(RecordKeeper &RK)

Definition Record.cpp:54

StringMap< const StringInit *, BumpPtrAllocator & > StringInitStringPool

Definition Record.cpp:76

FoldingSet< TernOpInit > TheTernOpInitPool

Definition Record.cpp:81

FoldingSet< InstancesOpInit > TheInstancesOpInitPool

Definition Record.cpp:85

void dumpAllocationStats(raw_ostream &OS) const

Definition Record.cpp:102

unsigned AnonCounter

Definition Record.cpp:96

FoldingSet< ExistsOpInit > TheExistsOpInitPool

Definition Record.cpp:84

DenseMap< std::pair< const RecTy *, const Init * >, VarInit * > TheVarInitPool

Definition Record.cpp:86

FoldingSet< IsAOpInit > TheIsAOpInitPool

Definition Record.cpp:83

DagRecTy SharedDagRecTy

Definition Record.cpp:66

IntRecTy SharedIntRecTy

Definition Record.cpp:64

FoldingSet< DagInit > TheDagInitPool

Definition Record.cpp:93

DenseMap< std::pair< const TypedInit *, unsigned >, VarBitInit * > TheVarBitInitPool

Definition Record.cpp:88

BitRecTy SharedBitRecTy

Definition Record.cpp:63

FoldingSet< CondOpInit > TheCondOpInitPool

Definition Record.cpp:92

FoldingSet< BinOpInit > TheBinOpInitPool

Definition Record.cpp:80

FoldingSet< FoldOpInit > TheFoldOpInitPool

Definition Record.cpp:82

Sorting predicate to sort record pointers by name.