LLVM: lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

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

117#include

118#include

119#include

120#include

121#include

122#include

123#include

124#include

125#include

126

129#include

130

131using namespace llvm;

133

134

135#undef DEBUG_TYPE

136#define DEBUG_TYPE "livedebugvalues"

137

138

139

141 cl::desc("Act like old LiveDebugValues did"),

143

144

145

146

147

148

149

150

151

152

155 cl::desc("livedebugvalues-stack-ws-limit"),

157

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

177public:

180

181

182

187

188

189

190

198

199

200

201

219

220

222

223

224

225

226

228

229

230

231

233

234

235

236

238

239

241

242

243

244

256

257

258

260

261

262

263

265

268

276 TLI = MF.getSubtarget().getTargetLowering();

278 }

279

281 unsigned Reg = MTracker->LocIdxToLocID[L];

282 if (Reg >= MTracker->NumRegs)

283 return false;

286 return true;

287 return false;

288 };

289

290

291

292

293

294

302

304 unsigned Location : 24;

305 unsigned Quality : 8;

306

307 public:

310 : Location(L.asU64()), Quality(static_cast<unsigned>(Q)) {}

312 if (!Quality)

314 return LocIdx(Location);

315 }

319 };

320

321 using ValueLocPair = std::pair<ValueIDNum, LocationAndQuality>;

322

325 return A.first < B.first;

326 };

327

328

329

330 std::optional

332 if (L.isIllegal())

333 return std::nullopt;

335 return std::nullopt;

339 return std::nullopt;

343 return std::nullopt;

345 }

346

347

348

349

350

351

352

353

354

360 bool IsValueValid = true;

361 unsigned LastUseBeforeDef = 0;

362 bool DbgLocAvailableAndIsEntryVal = false;

363

364

365

366

367

368

369

370

371

372

373

377 if (ID.isUndef()) {

378 IsValueValid = false;

379 break;

380 }

381 if (ID.isConst()) {

383 continue;

384 }

385

386

387

390 auto ValuesPreferredLoc =

392

393

394 assert(ValuesPreferredLoc != ValueToLoc.end() &&

395 ValuesPreferredLoc->first == Num);

396

397 if (ValuesPreferredLoc->second.isIllegal()) {

398

399

400

401

402 if (Num.getBlock() == (unsigned)MBB.getNumber() && !Num.isPHI()) {

403 LastUseBeforeDef = std::max(LastUseBeforeDef,

404 static_cast<unsigned>(Num.getInst()));

405 continue;

406 }

408 IsValueValid = false;

409 break;

410 }

411

412

413

414 LocIdx M = ValuesPreferredLoc->second.getLoc();

416 if (Value.Properties.DIExpr->isEntryValue())

417 DbgLocAvailableAndIsEntryVal = true;

418 }

419

420

421

422 if (!IsValueValid)

423 return;

424

425

426 if (LastUseBeforeDef) {

428 return;

429 }

430

431 auto &[Var, DILoc] = DVMap.lookupDVID(VarID);

433 std::make_pair(VarID, &*MTracker->emitLoc(ResolvedDbgOps, Var, DILoc,

434 Value.Properties)));

435

436

437

438 if (DbgLocAvailableAndIsEntryVal)

439 return;

440

441

442

444 if (Op.IsConst)

447 auto Result = ActiveVLocs.insert(std::make_pair(VarID, NewValue));

448 if (!Result.second)

449 Result.first->second = NewValue;

450 }

451

452

453

454

455

456

457

458 void

460 const SmallVectorImpl<std::pair<DebugVariableID, DbgValue>> &VLocs,

461 unsigned NumLocs) {

465 VarLocs.reserve(NumLocs);

468

469

470

472

473

474

475 for (const auto &VLoc : VLocs)

477 for (DbgOpID OpID : VLoc.second.getDbgOpIDs())

478 if (!OpID.ID.IsConst)

481

485

486

487

488

489 for (auto Location : MTracker->locations()) {

490 LocIdx Idx = Location.Idx;

493 continue;

495

496

499 if (VIt == ValueToLoc.end() || VIt->first != VNum)

500 continue;

501

502 auto &Previous = VIt->second;

503

504

505 std::optional ReplacementQuality =

507 if (ReplacementQuality)

509 }

510

511

512 for (const auto &Var : VLocs) {

513 loadVarInloc(MBB, DbgOpStore, ValueToLoc, Var.first, Var.second);

514 }

516 }

517

518

519

526

527

528

529

530

534 return;

535

536

537

539

540

541

542 for (auto &Use : MIt->second) {

544 continue;

545

547 assert(Op.isUndef() && "UseBeforeDef erroneously created for a "

548 "DbgValue with undef values.");

549 if (Op.IsConst)

550 continue;

551

553 }

554 }

555

556

557 if (ValueToLoc.empty())

558 return;

559

560

561 for (auto Location : MTracker->locations()) {

562 LocIdx Idx = Location.Idx;

564

565

566 auto VIt = ValueToLoc.find(LocValueID);

567 if (VIt == ValueToLoc.end())

568 continue;

569

570 auto &Previous = VIt->second;

571

572

573 std::optional ReplacementQuality =

575 if (ReplacementQuality)

577 }

578

579

580

581 for (auto &Use : MIt->second) {

583 continue;

584

586

588 if (Op.IsConst) {

590 continue;

591 }

592 LocIdx NewLoc = ValueToLoc.find(Op.ID)->second.getLoc();

594 break;

596 }

597

598

599

600

601 if (DbgOps.size() != Use.Values.size())

602 continue;

603

604

605 auto &[Var, DILoc] = DVMap.lookupDVID(Use.VarID);

607 Use.VarID, MTracker->emitLoc(DbgOps, Var, DILoc, Use.Properties)));

608 }

610 }

611

612

615 return;

616

617

619 if (MBB && Pos == MBB->begin())

620 BundleStart = MBB->instr_begin();

621 else

623

626 }

627

631 return false;

632

634 return false;

635

637 return false;

638

639 return true;

640 }

641

643

645 return false;

646

647

649 return false;

650

651 Register SP = TLI->getStackPointerRegisterToSaveRestore();

654 return Reg != SP && Reg != FP;

655 }

656

660

661

663 return false;

664

666

667

669

670

671 auto NonVariadicExpression =

673 if (!NonVariadicExpression)

674 return false;

675 DIExpr = *NonVariadicExpression;

676 }

677

678 auto &[Var, DILoc] = DVMap.lookupDVID(VarID);

679

680

681

687 return true;

688 }

689

690

692 return false;

693

694

696 return false;

697

698

705 return true;

706 }

707

708

710 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),

711 MI.getDebugLoc()->getInlinedAt());

714

715

716 if (MI.isUndefDebugValue() || MI.getDebugExpression()->isEntryValue() ||

718 [](const MachineOperand &MO) { return !MO.isReg(); })) {

721 for (LocIdx Loc : It->second.loc_indices())

724 }

725

727 return;

728 }

729

732 if (MO.isReg()) {

733

737 } else {

739 }

740 }

741

743 }

744

745

746

747

750 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),

751 MI.getDebugLoc()->getInlinedAt());

753

755

756

759 for (LocIdx Loc : It->second.loc_indices())

761 }

762

763

764 if (NewLocs.empty()) {

767 return;

768 }

769

772 if (Op.IsConst)

773 continue;

774

776

777

778

779

784 for (LocIdx Loc : LostVLocIt->second.loc_indices()) {

785

786

787 if (Loc == NewLoc)

788 continue;

790 }

791 }

793 }

794 for (const auto &LostMLoc : LostMLocs)

795 ActiveMLocs[LostMLoc.first].erase(LostMLoc.second);

796 LostMLocs.clear();

800 }

801

803 }

804

808 } else {

809 It->second.Ops.assign(NewLocs);

810 It->second.Properties = Properties;

811 }

812 }

813

814

815

816

817

819 bool MakeUndef = true) {

820 auto ActiveMLocIt = ActiveMLocs.find(MLoc);

822 return;

823

824

826 clobberMloc(MLoc, OldValue, Pos, MakeUndef);

827 }

828

829

830

833 auto ActiveMLocIt = ActiveMLocs.find(MLoc);

835 return;

836

838

839

840

841 std::optional NewLoc;

843 if (Loc.Value == OldValue)

844 NewLoc = Loc.Idx;

845

846

847

848 if (!NewLoc && !MakeUndef) {

849

853 }

855 return;

856 }

857

858

860

861

865

866

867

868 const DbgValueProperties &Properties = ActiveVLocIt->second.Properties;

869

870

871

872

874 if (NewLoc) {

877

878 DbgOps.insert(DbgOps.begin(), ActiveVLocIt->second.Ops.size(),

880 replace_copy(ActiveVLocIt->second.Ops, DbgOps.begin(), OldOp, NewOp);

881 }

882

883 auto &[Var, DILoc] = DVMap.lookupDVID(VarID);

885 VarID, &*MTracker->emitLoc(DbgOps, Var, DILoc, Properties)));

886

887

888

889 if (!NewLoc) {

890 for (LocIdx Loc : ActiveVLocIt->second.loc_indices()) {

891 if (Loc != MLoc)

893 }

895 } else {

896 ActiveVLocIt->second.Ops = DbgOps;

898 }

899 }

900

901

902

903 for (auto &LocVarIt : LostMLocs) {

904 auto LostMLocIt = ActiveMLocs.find(LocVarIt.first);

906 "Variable was using this MLoc, but ActiveMLocs[MLoc] has no "

907 "entries?");

908 LostMLocIt->second.erase(LocVarIt.second);

909 }

910

911

912

913 if (NewLoc)

914 VarLocs[NewLoc->asU64()] = OldValue;

915

917

918

919 ActiveMLocIt->second.clear();

920 if (!NewMLocs.empty())

921 ActiveMLocs[*NewLoc].insert_range(NewMLocs);

922 }

923

924

925

926

928

929

931 return;

932

933

934

935

936

938 ActiveMLocs[Dst].insert_range(MovingVars);

940

941

947

948

950

951 auto &[Var, DILoc] = DVMap.lookupDVID(VarID);

953 ActiveVLocIt->second.Properties);

955 }

958

959

960

963 }

964

971 auto MIB = BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE));

972 MIB.add(MO);

974 MIB.addImm(0);

975 else

976 MIB.addReg(0);

978 MIB.addMetadata(Properties.DIExpr);

979 return MIB;

980 }

981};

982

983

984

985

986

989

990#ifndef NDEBUG

1001 } else if (isUndef()) {

1003 }

1004}

1006 if (!OpStore) {

1007 dbgs() << "ID(" << asU32() << ")";

1008 } else {

1009 OpStore->find(*this).dump(MTrack);

1010 }

1011}

1019 else

1020 dbgs() << "Def(";

1021 for (unsigned Idx = 0; Idx < getDbgOpIDs().size(); ++Idx) {

1023 if (Idx != 0)

1024 dbgs() << ",";

1025 }

1026 dbgs() << ")";

1027 }

1029 dbgs() << " indir";

1032}

1033#endif

1034

1044

1045

1046

1047

1048 Register SP = TLI.getStackPointerRegisterToSaveRestore();

1049 if (SP) {

1052

1055 }

1056

1057

1058

1066

1067

1068

1069

1070 for (unsigned int I = 1; I < TRI.getNumSubRegIndices(); ++I) {

1071 unsigned Size = TRI.getSubRegIdxSize(I);

1072 unsigned Offs = TRI.getSubRegIdxOffset(I);

1074

1075

1076

1077 if (Size > 60000 || Offs > 60000)

1078 continue;

1079

1081 }

1082

1083

1085 unsigned Size = TRI.getRegSizeInBits(*RC);

1086

1087

1088

1089

1090 if (Size > 512)

1091 continue;

1092

1095 }

1096

1099

1101}

1102

1108

1109

1111

1112 for (const auto &MaskPair : reverse(Masks)) {

1113 if (MaskPair.first->clobbersPhysReg(ID)) {

1114

1115 ValNum = {CurBB, MaskPair.second, NewIdx};

1116 break;

1117 }

1118 }

1119

1122 return NewIdx;

1123}

1124

1126 unsigned InstID) {

1127

1128

1129

1130 for (auto Location : locations()) {

1132

1135 }

1136 Masks.push_back(std::make_pair(MO, InstID));

1137}

1138

1141

1142 if (SpillID.id() == 0) {

1143

1144

1146 return std::nullopt;

1147

1148

1149

1151 for (unsigned StackIdx = 0; StackIdx < NumSlotIdxes; ++StackIdx) {

1158

1159

1161 }

1162 }

1163 return SpillID;

1164}

1165

1172 return Twine("slot ")

1176 } else {

1177 return TRI.getRegAsmName(ID).str();

1178 }

1179}

1180

1183 return Num.asString(DefName);

1184}

1185

1186#ifndef NDEBUG

1188 for (auto Location : locations()) {

1189 std::string MLocName = LocIdxToName(Location.Value.getLoc());

1190 std::string DefName = Location.Value.asString(MLocName);

1191 dbgs() << LocIdxToName(Location.Idx) << " --> " << DefName << "\n";

1192 }

1193}

1194

1196 for (auto Location : locations()) {

1197 std::string foo = LocIdxToName(Location.Idx);

1198 dbgs() << "Idx " << Location.Idx.asU64() << " " << foo << "\n";

1199 }

1200}

1201#endif

1202

1208

1210 ? TII.get(TargetOpcode::DBG_VALUE_LIST)

1211 : TII.get(TargetOpcode::DBG_VALUE);

1212

1213#ifdef EXPENSIVE_CHECKS

1216 return Op.IsConst || Op.Loc.isIllegal();

1217 }) &&

1218 "Did not expect illegal ops in DbgOps.");

1221 "Expected to have either one DbgOp per MI LocationOp, or none.");

1222#endif

1223

1224 auto GetRegOp = [](unsigned Reg) -> MachineOperand {

1226 Reg, false, false,

1227 false, false,

1228 false, false,

1229 0, true);

1230 };

1231

1233

1234 auto EmitUndef = [&]() {

1239 };

1240

1241

1242

1243 if (DbgOps.empty())

1244 return EmitUndef();

1245

1246 bool Indirect = Properties.Indirect;

1247

1249

1251

1252

1253

1254

1255 for (size_t Idx = 0; Idx < Properties.getLocationOpCount(); ++Idx) {

1257

1258 if (Op.IsConst) {

1260 continue;

1261 }

1262

1268 unsigned short Offset = StackIdx.second;

1269

1270

1271

1272

1273

1274

1275

1276

1279 unsigned Base = Spill.SpillBase;

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295 bool UseDerefSize = false;

1297 unsigned DerefSizeInBytes = ValueSizeInBits / 8;

1298 if (auto Fragment = Var.getFragment()) {

1299 unsigned VariableSizeInBits = Fragment->SizeInBits;

1300 if (VariableSizeInBits != ValueSizeInBits || Expr->isComplex())

1301 UseDerefSize = true;

1303 if (*Size != ValueSizeInBits) {

1304 UseDerefSize = true;

1305 }

1306 }

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326 if (ValueSizeInBits > MF.getTarget().getPointerSizeInBits(0))

1327 UseDerefSize = false;

1328

1330 TRI.getOffsetOpcodes(Spill.SpillOffset, OffsetOps);

1331 bool StackValue = false;

1332

1334

1335

1336

1338 OffsetOps.push_back(dwarf::DW_OP_deref);

1340

1341

1342

1343

1344

1345 OffsetOps.push_back(dwarf::DW_OP_deref_size);

1346 OffsetOps.push_back(DerefSizeInBytes);

1347 StackValue = true;

1349

1350

1351 OffsetOps.push_back(dwarf::DW_OP_deref);

1352 } else {

1353

1354

1355

1356 Indirect = true;

1357 }

1358

1361 } else {

1362

1363

1364 return EmitUndef();

1365 }

1366 } else {

1367

1369 }

1370 }

1371

1373}

1374

1375

1377

1379 unsigned Reg = MTracker->LocIdxToLocID[L];

1381}

1384 if (CalleeSavedRegs.test((*RAI).id()))

1385 return true;

1386 return false;

1387}

1388

1389

1390

1391

1392

1393#ifndef NDEBUG

1394

1395

1396#endif

1397

1398std::optional

1399InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {

1400 assert(MI.hasOneMemOperand() &&

1401 "Spill instruction does not have exactly one memory operand?");

1402 auto MMOI = MI.memoperands_begin();

1405 "Inconsistent memory operand in spill instruction");

1411}

1412

1413std::optional

1415 std::optional SpillLoc = extractSpillBaseRegAndOffset(MI);

1417 return std::nullopt;

1418

1419

1420

1421

1422

1423 auto *MemOperand = *MI.memoperands_begin();

1424 LocationSize SizeInBits = MemOperand->getSizeInBits();

1425 assert(SizeInBits.hasValue() && "Expected to find a valid size!");

1426

1427

1428 auto IdxIt = MTracker->StackSlotIdxes.find({SizeInBits.getValue(), 0});

1429 if (IdxIt == MTracker->StackSlotIdxes.end())

1430

1431

1432 return std::nullopt;

1433

1434 unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillLoc, IdxIt->second);

1435 return MTracker->getSpillMLoc(SpillID);

1436}

1437

1438

1439

1440bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) {

1441 if (MI.isDebugValue())

1442 return false;

1443

1444 assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&

1445 "Expected inlined-at fields to agree");

1446

1447

1448

1450 if (Scope == nullptr)

1451 return true;

1452

1453

1454

1456 if (MO.isReg() && MO.getReg() != 0)

1457 (void)MTracker->readReg(MO.getReg());

1458

1459

1460

1461

1462 if (VTracker) {

1464

1465

1466 if (MI.isUndefDebugValue()) {

1468

1469

1470 if (MO.isReg()) {

1472 } else if (MO.isImm() || MO.isFPImm() || MO.isCImm()) {

1474 } else {

1476 }

1477 }

1478 }

1479 VTracker->defVar(MI, DbgValueProperties(MI), DebugOps);

1480 }

1481

1482

1483

1484 if (TTracker)

1485 TTracker->redefVar(MI);

1486 return true;

1487}

1488

1489std::optional InstrRefBasedLDV::getValueForInstrRef(

1492

1493

1494

1495

1496 const MachineFunction &MF = *MI.getParent()->getParent();

1497

1498

1499 auto SoughtSub =

1500 MachineFunction::DebugSubstitution({InstNo, OpNo}, {0, 0}, 0);

1501

1502 SmallVector<unsigned, 4> SeenSubregs;

1505 LowerBoundIt->Src == SoughtSub.Src) {

1506 std::tie(InstNo, OpNo) = LowerBoundIt->Dest;

1507 SoughtSub.Src = LowerBoundIt->Dest;

1508 if (unsigned Subreg = LowerBoundIt->Subreg)

1509 SeenSubregs.push_back(Subreg);

1511 }

1512

1513

1514

1515 std::optional NewID;

1516

1517

1518

1519 auto InstrIt = DebugInstrNumToInstr.find(InstNo);

1521 if (InstrIt != DebugInstrNumToInstr.end()) {

1522 const MachineInstr &TargetInstr = *InstrIt->second.first;

1524

1525

1526

1530 if (L)

1531 NewID = ValueIDNum(BlockNo, InstrIt->second.second, *L);

1533

1534

1535

1536

1537

1539 const MachineOperand &MO = TargetInstr.getOperand(OpNo);

1540

1542 unsigned LocID = MTracker->getLocID(MO.getReg());

1543 LocIdx L = MTracker->LocIDToLocIdx[LocID];

1544 NewID = ValueIDNum(BlockNo, InstrIt->second.second, L);

1545 }

1546 }

1547

1548 if (!NewID) {

1550 { dbgs() << "Seen instruction reference to illegal operand\n"; });

1551 }

1552 }

1553

1554 } else if (PHIIt != DebugPHINumToValue.end() && PHIIt->InstrNum == InstNo) {

1555

1556

1557 assert(MLiveOuts && MLiveIns);

1558 NewID = resolveDbgPHIs(*MI.getParent()->getParent(), *MLiveOuts, *MLiveIns,

1559 MI, InstNo);

1560 }

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570

1571 if (NewID && !SeenSubregs.empty()) {

1572 unsigned Offset = 0;

1573 unsigned Size = 0;

1574

1575

1576

1577

1578

1579 for (unsigned Subreg : reverse(SeenSubregs)) {

1580 unsigned ThisSize = TRI->getSubRegIdxSize(Subreg);

1581 unsigned ThisOffset = TRI->getSubRegIdxOffset(Subreg);

1582 Offset += ThisOffset;

1583 Size = (Size == 0) ? ThisSize : std::min(Size, ThisSize);

1584 }

1585

1586

1587

1588

1589

1590 LocIdx L = NewID->getLoc();

1591 if (NewID && !MTracker->isSpill(L)) {

1592

1593

1595 const TargetRegisterClass *TRC = nullptr;

1596 for (const auto *TRCI : TRI->regclasses())

1597 if (TRCI->contains(Reg))

1598 TRC = TRCI;

1599 assert(TRC && "Couldn't find target register class?");

1600

1601

1602

1603 unsigned MainRegSize = TRI->getRegSizeInBits(*TRC);

1604 if (Size != MainRegSize || Offset) {

1605

1607 for (MCRegister SR : TRI->subregs(Reg)) {

1608 unsigned Subreg = TRI->getSubRegIndex(Reg, SR);

1609 unsigned SubregSize = TRI->getSubRegIdxSize(Subreg);

1610 unsigned SubregOffset = TRI->getSubRegIdxOffset(Subreg);

1611 if (SubregSize == Size && SubregOffset == Offset) {

1612 NewReg = SR;

1613 break;

1614 }

1615 }

1616

1617

1618 if (!NewReg) {

1619 NewID = std::nullopt;

1620 } else {

1621

1622

1623 LocIdx NewLoc =

1624 MTracker->lookupOrTrackRegister(MTracker->getLocID(NewReg));

1625 NewID = ValueIDNum(NewID->getBlock(), NewID->getInst(), NewLoc);

1626 }

1627 }

1628 } else {

1629

1630 NewID = std::nullopt;

1631 }

1632 }

1633

1634 return NewID;

1635}

1636

1637bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,

1640 if (MI.isDebugRef())

1641 return false;

1642

1643

1644

1645 if (!VTracker && !TTracker)

1646 return false;

1647

1648 const DILocalVariable *Var = MI.getDebugVariable();

1649 const DIExpression *Expr = MI.getDebugExpression();

1650 const DILocation *DebugLoc = MI.getDebugLoc();

1651 const DILocation *InlinedAt = DebugLoc->getInlinedAt();

1653 "Expected inlined-at fields to agree");

1654

1655 DebugVariable V(Var, Expr, InlinedAt);

1656

1657 auto *Scope = LS.findLexicalScope(MI.getDebugLoc().get());

1658 if (Scope == nullptr)

1659 return true;

1660

1662 for (const MachineOperand &MO : MI.debug_operands()) {

1664 assert(!MO.isReg() && "DBG_INSTR_REF should not contain registers");

1665 DbgOpID ConstOpID = DbgOpStore.insert(DbgOp(MO));

1667 continue;

1668 }

1669

1672

1673

1674

1675 std::optional NewID =

1676 getValueForInstrRef(InstNo, OpNo, MI, MLiveOuts, MLiveIns);

1677

1678

1679 if (NewID) {

1680 DbgOpIDs.push_back(DbgOpStore.insert(*NewID));

1681 } else {

1682 DbgOpIDs.clear();

1683 break;

1684 }

1685 }

1686

1687

1688

1689

1690

1691 DbgValueProperties Properties(Expr, false, true);

1692 if (VTracker)

1693 VTracker->defVar(MI, Properties, DbgOpIDs);

1694

1695

1696

1697 if (!TTracker)

1698 return true;

1699

1700

1702 for (DbgOpID OpID : DbgOpIDs) {

1703 DbgOps.push_back(DbgOpStore.find(OpID));

1704 }

1705

1706

1707

1708 SmallDenseMap<ValueIDNum, TransferTracker::LocationAndQuality> FoundLocs;

1710

1711

1712 for (const DbgOp &Op : DbgOps) {

1713 if (Op.IsConst)

1716 }

1717

1718 for (auto Location : MTracker->locations()) {

1720 ValueIDNum ID = MTracker->readMLoc(CurL);

1721 auto ValueToFindIt = find(ValuesToFind, ID);

1722 if (ValueToFindIt == ValuesToFind.end())

1723 continue;

1724 auto &Previous = FoundLocs.find(ID)->second;

1725

1726

1727 std::optionalTransferTracker::LocationQuality ReplacementQuality =

1728 TTracker->getLocQualityIfBetter(CurL, Previous.getQuality());

1729 if (ReplacementQuality) {

1730 Previous = TransferTracker::LocationAndQuality(CurL, *ReplacementQuality);

1731 if (Previous.isBest()) {

1732 ValuesToFind.erase(ValueToFindIt);

1733 if (ValuesToFind.empty())

1734 break;

1735 }

1736 }

1737 }

1738

1740 for (const DbgOp &DbgOp : DbgOps) {

1741 if (DbgOp.IsConst) {

1743 continue;

1744 }

1745 LocIdx FoundLoc = FoundLocs.find(DbgOp.ID)->second.getLoc();

1747 NewLocs.clear();

1748 break;

1749 }

1751 }

1752

1753 TTracker->redefVar(MI, Properties, NewLocs);

1754

1755

1756

1757 if (!DbgOps.empty() && NewLocs.empty()) {

1758 bool IsValidUseBeforeDef = true;

1759 uint64_t LastUseBeforeDef = 0;

1760 for (auto ValueLoc : FoundLocs) {

1761 ValueIDNum NewID = ValueLoc.first;

1762 LocIdx FoundLoc = ValueLoc.second.getLoc();

1764 continue;

1765

1766

1767 if (NewID.getBlock() != CurBB || NewID.getInst() <= CurInst) {

1768 IsValidUseBeforeDef = false;

1769 break;

1770 }

1771 LastUseBeforeDef = std::max(LastUseBeforeDef, NewID.getInst());

1772 }

1773 if (IsValidUseBeforeDef) {

1774 DebugVariableID VID = DVMap.insertDVID(V, MI.getDebugLoc().get());

1775 TTracker->addUseBeforeDef(VID, {MI.getDebugExpression(), false, true},

1776 DbgOps, LastUseBeforeDef);

1777 }

1778 }

1779

1780

1781

1782

1783

1784 MachineInstr *DbgMI =

1785 MTracker->emitLoc(NewLocs, V, MI.getDebugLoc().get(), Properties);

1787

1788 TTracker->PendingDbgValues.push_back(std::make_pair(ID, DbgMI));

1789 TTracker->flushDbgValues(MI.getIterator(), nullptr);

1790 return true;

1791}

1792

1793bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {

1794 if (MI.isDebugPHI())

1795 return false;

1796

1797

1798 if (VTracker || TTracker)

1799 return true;

1800

1801

1802

1803 const MachineOperand &MO = MI.getOperand(0);

1804 unsigned InstrNum = MI.getOperand(1).getImm();

1805

1806 auto EmitBadPHI = [this, &MI, InstrNum]() -> bool {

1807

1808

1809

1810

1811 DebugPHINumToValue.push_back(

1812 {InstrNum, MI.getParent(), std::nullopt, std::nullopt});

1813 return true;

1814 };

1815

1817

1818

1820 ValueIDNum Num = MTracker->readReg(Reg);

1821 auto PHIRec = DebugPHIRecord(

1822 {InstrNum, MI.getParent(), Num,

1823 MTracker->lookupOrTrackRegister(MTracker->getLocID(Reg))});

1824 DebugPHINumToValue.push_back(PHIRec);

1825

1826

1827 for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)

1828 MTracker->lookupOrTrackRegister(MTracker->getLocID(*RAI));

1829 } else if (MO.isFI()) {

1830

1831 unsigned FI = MO.getIndex();

1832

1833

1834

1835 if (MFI->isDeadObjectIndex(FI))

1836 return EmitBadPHI();

1837

1838

1840 StackOffset Offs = TFI->getFrameIndexReference(*MI.getMF(), FI, Base);

1841 SpillLoc SL = {Base, Offs};

1842 std::optional SpillNo = MTracker->getOrTrackSpillLoc(SL);

1843

1844

1845

1846 if (!SpillNo)

1847 return EmitBadPHI();

1848

1849

1850 assert(MI.getNumOperands() == 3 && "Stack DBG_PHI with no size?");

1851 unsigned slotBitSize = MI.getOperand(2).getImm();

1852

1853 unsigned SpillID = MTracker->getLocID(*SpillNo, {slotBitSize, 0});

1854 LocIdx SpillLoc = MTracker->getSpillMLoc(SpillID);

1855 ValueIDNum Result = MTracker->readMLoc(SpillLoc);

1856

1857

1858 auto DbgPHI = DebugPHIRecord({InstrNum, MI.getParent(), Result, SpillLoc});

1859 DebugPHINumToValue.push_back(DbgPHI);

1860 } else {

1861

1862

1863

1864

1866 { dbgs() << "Seen DBG_PHI with unrecognised operand format\n"; });

1867 return EmitBadPHI();

1868 }

1869

1870 return true;

1871}

1872

1873void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {

1874

1875

1876 if (MI.isImplicitDef()) {

1877

1878

1879

1880

1881 ValueIDNum Num = MTracker->readReg(MI.getOperand(0).getReg());

1882

1883 if (Num.getLoc() != 0)

1884 return;

1885

1886 } else if (MI.isMetaInstruction())

1887 return;

1888

1889

1890

1891

1892

1893

1894 bool CallChangesSP = false;

1895 if (AdjustsStackInCalls && MI.isCall() && MI.getOperand(0).isSymbol() &&

1896 !strcmp(MI.getOperand(0).getSymbolName(), StackProbeSymbolName.data()))

1897 CallChangesSP = true;

1898

1899

1900

1901 auto IgnoreSPAlias = [this, &MI, CallChangesSP](Register R) -> bool {

1902 if (CallChangesSP)

1903 return false;

1904 return MI.isCall() && MTracker->SPAliases.count(R);

1905 };

1906

1907

1908

1909

1910 SmallSet<uint32_t, 32> DeadRegs;

1911 SmallVector<const uint32_t *, 4> RegMasks;

1913 for (const MachineOperand &MO : MI.operands()) {

1914

1916 !IgnoreSPAlias(MO.getReg())) {

1917

1918 for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI)

1919

1920 DeadRegs.insert((*RAI).id());

1924 }

1925 }

1926

1927

1928 for (uint32_t DeadReg : DeadRegs)

1929 MTracker->defReg(DeadReg, CurBB, CurInst);

1930

1931 for (const auto *MO : RegMaskPtrs)

1932 MTracker->writeRegMask(MO, CurBB, CurInst);

1933

1934

1936 if (std::optional SpillNo =

1937 extractSpillBaseRegAndOffset(MI)) {

1938 for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {

1939 unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillNo, I);

1940 LocIdx L = MTracker->getSpillMLoc(SpillID);

1941 MTracker->setMLoc(L, ValueIDNum(CurBB, CurInst, L));

1942 }

1943 }

1944 }

1945

1946 if (!TTracker)

1947 return;

1948

1949

1950

1951

1952

1953

1954 for (MCRegister DeadReg : DeadRegs) {

1955 LocIdx Loc = MTracker->lookupOrTrackRegister(MTracker->getLocID(DeadReg));

1956 TTracker->clobberMloc(Loc, MI.getIterator(), false);

1957 }

1958

1959

1960

1961 if (!RegMaskPtrs.empty()) {

1962 for (auto L : MTracker->locations()) {

1963

1964 if (MTracker->isSpill(L.Idx))

1965 continue;

1966

1967 Register Reg = MTracker->LocIdxToLocID[L.Idx];

1968 if (IgnoreSPAlias(Reg))

1969 continue;

1970

1971 for (const auto *MO : RegMaskPtrs)

1973 TTracker->clobberMloc(L.Idx, MI.getIterator(), false);

1974 }

1975 }

1976

1977

1979 if (std::optional SpillNo =

1980 extractSpillBaseRegAndOffset(MI)) {

1981 for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {

1982 unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillNo, I);

1983 LocIdx L = MTracker->getSpillMLoc(SpillID);

1984 TTracker->clobberMloc(L, MI.getIterator(), true);

1985 }

1986 }

1987 }

1988}

1989

1990void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) {

1991

1992 for (MCRegAliasIterator RAI(DstRegNum, TRI, true); RAI.isValid(); ++RAI)

1993 MTracker->defReg(*RAI, CurBB, CurInst);

1994

1995 ValueIDNum SrcValue = MTracker->readReg(SrcRegNum);

1996 MTracker->setReg(DstRegNum, SrcValue);

1997

1998

1999 for (MCSubRegIndexIterator SRI(SrcRegNum, TRI); SRI.isValid(); ++SRI) {

2000 MCRegister SrcSubReg = SRI.getSubReg();

2001 unsigned SubRegIdx = SRI.getSubRegIndex();

2002 MCRegister DstSubReg = TRI->getSubReg(DstRegNum, SubRegIdx);

2003 if (!DstSubReg)

2004 continue;

2005

2006

2007

2008

2009

2010

2011 LocIdx SrcL =

2012 MTracker->lookupOrTrackRegister(MTracker->getLocID(SrcSubReg));

2013 LocIdx DstL =

2014 MTracker->lookupOrTrackRegister(MTracker->getLocID(DstSubReg));

2015 (void)SrcL;

2016 (void)DstL;

2017 ValueIDNum CpyValue = MTracker->readReg(SrcSubReg);

2018

2019 MTracker->setReg(DstSubReg, CpyValue);

2020 }

2021}

2022

2023std::optional

2024InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,

2026

2027 if (MI.hasOneMemOperand())

2028 return std::nullopt;

2029

2030

2031 auto MMOI = MI.memoperands_begin();

2032 const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();

2034 return std::nullopt;

2035

2036 if (MI.getSpillSize(TII) && MI.getFoldedSpillSize(TII))

2037 return std::nullopt;

2038

2039

2040 return extractSpillBaseRegAndOffset(MI);

2041}

2042

2043bool InstrRefBasedLDV::isLocationSpill(const MachineInstr &MI,

2045 if (!isSpillInstruction(MI, MF))

2046 return false;

2047

2048 int FI;

2049 Reg = TII->isStoreToStackSlotPostFE(MI, FI);

2050 return Reg != 0;

2051}

2052

2053std::optional

2054InstrRefBasedLDV::isRestoreInstruction(const MachineInstr &MI,

2056 if (MI.hasOneMemOperand())

2057 return std::nullopt;

2058

2059

2060

2061 if (MI.getRestoreSize(TII)) {

2062 Reg = MI.getOperand(0).getReg();

2063 return extractSpillBaseRegAndOffset(MI);

2064 }

2065 return std::nullopt;

2066}

2067

2068bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {

2069

2070

2071

2073 return false;

2074

2075

2076

2077 int DummyFI = -1;

2078 if (!TII->isStoreToStackSlotPostFE(MI, DummyFI) &&

2079 !TII->isLoadFromStackSlotPostFE(MI, DummyFI))

2080 return false;

2081

2082 MachineFunction *MF = MI.getMF();

2083 unsigned Reg;

2084

2086

2087

2088

2089 int FIDummy;

2090 if (!TII->isStoreToStackSlotPostFE(MI, FIDummy) &&

2091 !TII->isLoadFromStackSlotPostFE(MI, FIDummy))

2092 return false;

2093

2094

2095

2096

2097 if (std::optional Loc = isSpillInstruction(MI, MF)) {

2098

2099

2100 for (unsigned SlotIdx = 0; SlotIdx < MTracker->NumSlotIdxes; ++SlotIdx) {

2101 unsigned SpillID = MTracker->getSpillIDWithIdx(*Loc, SlotIdx);

2102 std::optional MLoc = MTracker->getSpillMLoc(SpillID);

2103 if (!MLoc)

2104 continue;

2105

2106

2107

2108

2109

2110 ValueIDNum Def(CurBB, CurInst, *MLoc);

2111 MTracker->setMLoc(*MLoc, Def);

2112 if (TTracker)

2113 TTracker->clobberMloc(*MLoc, MI.getIterator());

2114 }

2115 }

2116

2117

2118 if (isLocationSpill(MI, MF, Reg)) {

2119

2120

2121 SpillLocationNo Loc = *extractSpillBaseRegAndOffset(MI);

2122

2123 auto DoTransfer = [&](Register SrcReg, unsigned SpillID) {

2124 auto ReadValue = MTracker->readReg(SrcReg);

2125 LocIdx DstLoc = MTracker->getSpillMLoc(SpillID);

2126 MTracker->setMLoc(DstLoc, ReadValue);

2127

2128 if (TTracker) {

2129 LocIdx SrcLoc = MTracker->getRegMLoc(SrcReg);

2130 TTracker->transferMlocs(SrcLoc, DstLoc, MI.getIterator());

2131 }

2132 };

2133

2134

2136

2137 (void)MTracker->lookupOrTrackRegister(MTracker->getLocID(SR));

2138 unsigned SubregIdx = TRI->getSubRegIndex(Reg, SR);

2139 unsigned SpillID = MTracker->getLocID(Loc, SubregIdx);

2140 DoTransfer(SR, SpillID);

2141 }

2142

2143

2144 unsigned Size = TRI->getRegSizeInBits(Reg, *MRI);

2145 unsigned SpillID = MTracker->getLocID(Loc, {Size, 0});

2146 DoTransfer(Reg, SpillID);

2147 } else {

2148 std::optional Loc = isRestoreInstruction(MI, MF, Reg);

2149 if (!Loc)

2150 return false;

2151

2152

2153

2154

2155

2156

2157

2158

2159 for (MCRegAliasIterator RAI(Reg, TRI, true); RAI.isValid(); ++RAI)

2160 MTracker->defReg(*RAI, CurBB, CurInst);

2161

2162

2163

2164 auto DoTransfer = [&](Register DestReg, unsigned SpillID) {

2165 LocIdx SrcIdx = MTracker->getSpillMLoc(SpillID);

2166 auto ReadValue = MTracker->readMLoc(SrcIdx);

2167 MTracker->setReg(DestReg, ReadValue);

2168 };

2169

2171 unsigned Subreg = TRI->getSubRegIndex(Reg, SR);

2172 unsigned SpillID = MTracker->getLocID(*Loc, Subreg);

2173 DoTransfer(SR, SpillID);

2174 }

2175

2176

2177 unsigned Size = TRI->getRegSizeInBits(Reg, *MRI);

2178 unsigned SpillID = MTracker->getLocID(*Loc, {Size, 0});

2179 DoTransfer(Reg, SpillID);

2180 }

2181 return true;

2182}

2183

2184bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {

2185 auto DestSrc = TII->isCopyLikeInstr(MI);

2186 if (!DestSrc)

2187 return false;

2188

2189 const MachineOperand *DestRegOp = DestSrc->Destination;

2190 const MachineOperand *SrcRegOp = DestSrc->Source;

2191

2194

2195

2196 if (SrcReg == DestReg)

2197 return true;

2198

2199

2200

2201

2202

2203

2204

2205

2206

2207

2209 return false;

2210

2211

2213 return false;

2214

2215

2216

2217

2218 DenseMap<LocIdx, ValueIDNum> ClobberedLocs;

2219 if (TTracker) {

2220 for (MCRegAliasIterator RAI(DestReg, TRI, true); RAI.isValid(); ++RAI) {

2221 LocIdx ClobberedLoc = MTracker->getRegMLoc(*RAI);

2222 auto MLocIt = TTracker->ActiveMLocs.find(ClobberedLoc);

2223

2224

2225 if (MLocIt == TTracker->ActiveMLocs.end() || MLocIt->second.empty())

2226 continue;

2227 ValueIDNum Value = MTracker->readReg(*RAI);

2228 ClobberedLocs[ClobberedLoc] = Value;

2229 }

2230 }

2231

2232

2233 InstrRefBasedLDV::performCopy(SrcReg, DestReg);

2234

2235

2236

2237

2238 if (TTracker) {

2239 for (auto LocVal : ClobberedLocs) {

2240 TTracker->clobberMloc(LocVal.first, LocVal.second, MI.getIterator(), false);

2241 }

2242 }

2243

2244

2245

2246

2248 TTracker->transferMlocs(MTracker->getRegMLoc(SrcReg),

2249 MTracker->getRegMLoc(DestReg), MI.getIterator());

2250

2251

2253 MTracker->defReg(SrcReg, CurBB, CurInst);

2254

2255 return true;

2256}

2257

2258

2259

2260

2261

2262

2263

2264void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) {

2265 assert(MI.isDebugValueLike());

2266 DebugVariable MIVar(MI.getDebugVariable(), MI.getDebugExpression(),

2267 MI.getDebugLoc()->getInlinedAt());

2268 FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();

2269

2270

2271

2272

2273 auto [SeenIt, Inserted] = SeenFragments.try_emplace(MIVar.getVariable());

2274 if (Inserted) {

2275 SeenIt->second.insert(ThisFragment);

2276

2277 OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});

2278 return;

2279 }

2280

2281

2282

2283 auto IsInOLapMap =

2284 OverlapFragments.insert({{MIVar.getVariable(), ThisFragment}, {}});

2285 if (!IsInOLapMap.second)

2286 return;

2287

2288 auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;

2289 auto &AllSeenFragments = SeenIt->second;

2290

2291

2292

2293

2294 for (const auto &ASeenFragment : AllSeenFragments) {

2295

2297

2298 ThisFragmentsOverlaps.push_back(ASeenFragment);

2299

2300

2301 auto ASeenFragmentsOverlaps =

2302 OverlapFragments.find({MIVar.getVariable(), ASeenFragment});

2303 assert(ASeenFragmentsOverlaps != OverlapFragments.end() &&

2304 "Previously seen var fragment has no vector of overlaps");

2305 ASeenFragmentsOverlaps->second.push_back(ThisFragment);

2306 }

2307 }

2308

2309 AllSeenFragments.insert(ThisFragment);

2310}

2311

2315

2316

2317

2318 if (transferDebugValue(MI))

2319 return;

2320 if (transferDebugInstrRef(MI, MLiveOuts, MLiveIns))

2321 return;

2322 if (transferDebugPHI(MI))

2323 return;

2324 if (transferRegisterCopy(MI))

2325 return;

2326 if (transferSpillOrRestoreInst(MI))

2327 return;

2328 transferRegisterDef(MI);

2329}

2330

2331void InstrRefBasedLDV::produceMLocTransferFunction(

2334

2335

2336

2337

2338

2339

2340

2341

2344

2345

2347 for (auto &BV : BlockMasks)

2348 BV.resize(TRI->getNumRegs(), true);

2349

2350

2351 for (auto &MBB : MF) {

2352

2353

2355 CurInst = 1;

2356

2357

2358

2359 MTracker->reset();

2360 MTracker->setMPhis(CurBB);

2361

2362

2363 for (auto &MI : MBB) {

2364

2365

2366 process(MI, nullptr, nullptr);

2367

2368

2369 if (MI.isDebugValueLike())

2370 accumulateFragmentMap(MI);

2371

2372

2373

2374 if (uint64_t InstrNo = MI.peekDebugInstrNum()) {

2375 auto InstrAndPos = std::make_pair(&MI, CurInst);

2376 auto InsertResult =

2377 DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));

2378

2379

2380 assert(InsertResult.second);

2381 (void)InsertResult;

2382 }

2383

2384 ++CurInst;

2385 }

2386

2387

2388

2389

2390

2391 for (auto Location : MTracker->locations()) {

2394 if (P.isPHI() && P.getLoc() == Idx.asU64())

2395 continue;

2396

2397

2398 auto &TransferMap = MLocTransfer[CurBB];

2399 auto Result = TransferMap.insert(std::make_pair(Idx.asU64(), P));

2401 Result.first->second = P;

2402 }

2403

2404

2405

2406 for (auto &P : MTracker->Masks) {

2407 BlockMasks[CurBB].clearBitsNotInMask(P.first->getRegMask(), BVWords);

2408 }

2409 }

2410

2411

2412 BitVector UsedRegs(TRI->getNumRegs());

2413 for (auto Location : MTracker->locations()) {

2414 unsigned ID = MTracker->LocIdxToLocID[Location.Idx];

2415

2416 if (ID >= TRI->getNumRegs() || MTracker->SPAliases.count(ID))

2417 continue;

2418 UsedRegs.set(ID);

2419 }

2420

2421

2422

2423

2425 BitVector &BV = BlockMasks[I];

2427 BV &= UsedRegs;

2428

2429

2430

2431 for (unsigned Bit : BV.set_bits()) {

2432 unsigned ID = MTracker->getLocID(Bit);

2433 LocIdx Idx = MTracker->LocIDToLocIdx[ID];

2434 auto &TransferMap = MLocTransfer[I];

2435

2436

2437

2438

2439

2440

2441 ValueIDNum NotGeneratedNum = ValueIDNum(I, 1, Idx);

2443 TransferMap.insert(std::make_pair(Idx.asU64(), NotGeneratedNum));

2444 if (Result.second) {

2445 ValueIDNum &ValueID = Result.first->second;

2447

2448 ValueID = NotGeneratedNum;

2449 }

2450 }

2451 }

2452}

2453

2454bool InstrRefBasedLDV::mlocJoin(

2459

2460

2461

2462

2463

2464

2466

2467

2468 auto Cmp = [&](const MachineBasicBlock *A, const MachineBasicBlock *B) {

2469 return BBToOrder.find(A)->second < BBToOrder.find(B)->second;

2470 };

2472

2473

2474 if (BlockOrders.size() == 0) {

2475

2476

2478 << "Found not reachable block " << MBB.getFullName()

2479 << " from entry which may lead out of "

2480 "bound access to VarLocs\n");

2481 return false;

2482 }

2483

2484

2485

2486 for (auto Location : MTracker->locations()) {

2488

2489

2490

2491 ValueIDNum FirstVal = OutLocs[*BlockOrders[0]][Idx.asU64()];

2492

2493

2494

2495 if (InLocs[Idx.asU64()] != ValueIDNum(MBB.getNumber(), 0, Idx)) {

2496 if (InLocs[Idx.asU64()] != FirstVal) {

2497 InLocs[Idx.asU64()] = FirstVal;

2499 }

2500 continue;

2501 }

2502

2503

2504

2505 bool Disagree = false;

2506 for (unsigned int I = 1; I < BlockOrders.size(); ++I) {

2507 const MachineBasicBlock *PredMBB = BlockOrders[I];

2508 const ValueIDNum &PredLiveOut = OutLocs[*PredMBB][Idx.asU64()];

2509

2510

2511 if (FirstVal == PredLiveOut)

2512 continue;

2513

2514

2515 if (PredLiveOut == ValueIDNum(MBB.getNumber(), 0, Idx))

2516 continue;

2517

2518

2519 Disagree = true;

2520 }

2521

2522

2523 if (!Disagree) {

2524 InLocs[Idx.asU64()] = FirstVal;

2526 }

2527 }

2528

2529

2531}

2532

2533void InstrRefBasedLDV::findStackIndexInterference(

2535

2536

2537

2538

2539

2540

2541

2542

2543

2544

2545

2546 auto It = MTracker->StackSlotIdxes.find({8, 0});

2547 assert(It != MTracker->StackSlotIdxes.end());

2549

2550

2551 for (auto &Pair : MTracker->StackSlotIdxes) {

2552

2553 if (!Pair.first.second)

2554 continue;

2556 }

2557}

2558

2559void InstrRefBasedLDV::placeMLocPHIs(

2562 SmallVector<unsigned, 4> StackUnits;

2563 findStackIndexInterference(StackUnits);

2564

2565

2566

2567

2568

2569

2570

2571

2572 SmallSet<Register, 32> RegUnitsToPHIUp;

2573 SmallSet<LocIdx, 32> NormalLocsToPHI;

2574 SmallSet<SpillLocationNo, 32> StackSlots;

2575 for (auto Location : MTracker->locations()) {

2577 if (MTracker->isSpill(L)) {

2578 StackSlots.insert(MTracker->locIDToSpill(MTracker->LocIdxToLocID[L]));

2579 continue;

2580 }

2581

2582 Register R = MTracker->LocIdxToLocID[L];

2583 SmallSet<Register, 8> FoundRegUnits;

2584 bool AnyIllegal = false;

2585 for (MCRegUnit Unit : TRI->regunits(R.asMCReg())) {

2586 for (MCRegUnitRootIterator URoot(Unit, TRI); URoot.isValid(); ++URoot) {

2587 if (!MTracker->isRegisterTracked(*URoot)) {

2588

2589

2590

2591 AnyIllegal = true;

2592 } else {

2593 FoundRegUnits.insert(*URoot);

2594 }

2595 }

2596 }

2597

2598 if (AnyIllegal) {

2599 NormalLocsToPHI.insert(L);

2600 continue;

2601 }

2602

2603 RegUnitsToPHIUp.insert_range(FoundRegUnits);

2604 }

2605

2606

2607

2608 SmallVector<MachineBasicBlock *, 32> PHIBlocks;

2609 auto CollectPHIsForLoc = [&](LocIdx L) {

2610

2611 SmallPtrSet<MachineBasicBlock *, 32> DefBlocks;

2612 for (MachineBasicBlock *MBB : OrderToBB) {

2613 const auto &TransferFunc = MLocTransfer[MBB->getNumber()];

2614 if (TransferFunc.contains(L))

2616 }

2617

2618

2619

2620

2621 if (!DefBlocks.empty())

2623

2624

2625

2626 PHIBlocks.clear();

2627 BlockPHIPlacement(AllBlocks, DefBlocks, PHIBlocks);

2628 };

2629

2630 auto InstallPHIsAtLoc = [&PHIBlocks, &MInLocs](LocIdx L) {

2631 for (const MachineBasicBlock *MBB : PHIBlocks)

2632 MInLocs[*MBB][L.asU64()] = ValueIDNum(MBB->getNumber(), 0, L);

2633 };

2634

2635

2636 for (LocIdx L : NormalLocsToPHI) {

2637 CollectPHIsForLoc(L);

2638

2639 InstallPHIsAtLoc(L);

2640 }

2641

2642

2643

2644 for (SpillLocationNo Slot : StackSlots) {

2645 for (unsigned Idx : StackUnits) {

2646 unsigned SpillID = MTracker->getSpillIDWithIdx(Slot, Idx);

2647 LocIdx L = MTracker->getSpillMLoc(SpillID);

2648 CollectPHIsForLoc(L);

2649 InstallPHIsAtLoc(L);

2650

2651

2653 std::tie(Size, Offset) = MTracker->StackIdxesToPos[Idx];

2654 for (auto &Pair : MTracker->StackSlotIdxes) {

2655 unsigned ThisSize, ThisOffset;

2656 std::tie(ThisSize, ThisOffset) = Pair.first;

2657 if (ThisSize + ThisOffset <= Offset || Size + Offset <= ThisOffset)

2658 continue;

2659

2660 unsigned ThisID = MTracker->getSpillIDWithIdx(Slot, Pair.second);

2661 LocIdx ThisL = MTracker->getSpillMLoc(ThisID);

2662 InstallPHIsAtLoc(ThisL);

2663 }

2664 }

2665 }

2666

2667

2668 for (Register R : RegUnitsToPHIUp) {

2669 LocIdx L = MTracker->lookupOrTrackRegister(MTracker->getLocID(R));

2670 CollectPHIsForLoc(L);

2671

2672

2673 InstallPHIsAtLoc(L);

2674

2675

2676 for (MCRegAliasIterator RAI(R, TRI, true); RAI.isValid(); ++RAI) {

2677

2678

2679 if (!MTracker->isRegisterTracked(*RAI))

2680 continue;

2681

2682 LocIdx AliasLoc =

2683 MTracker->lookupOrTrackRegister(MTracker->getLocID(*RAI));

2684 InstallPHIsAtLoc(AliasLoc);

2685 }

2686 }

2687}

2688

2689void InstrRefBasedLDV::buildMLocValueMap(

2692 std::priority_queue<unsigned int, std::vector,

2693 std::greater>

2694 Worklist, Pending;

2695

2696

2697

2698

2699 SmallPtrSet<MachineBasicBlock *, 16> OnPending, OnWorklist;

2700

2701

2702

2703 SmallPtrSet<MachineBasicBlock *, 32> AllBlocks;

2704 for (unsigned int I = 0; I < BBToOrder.size(); ++I) {

2705 Worklist.push(I);

2706 OnWorklist.insert(OrderToBB[I]);

2707 AllBlocks.insert(OrderToBB[I]);

2708 }

2709

2710

2711 for (auto Location : MTracker->locations())

2713 ValueIDNum(0, 0, Location.Idx);

2714

2715 MTracker->reset();

2716

2717

2718

2719

2720 placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer);

2721

2722

2723

2724

2725

2726

2727

2728

2729

2730 SmallPtrSet<const MachineBasicBlock *, 16> Visited;

2731 while (!Worklist.empty() || !Pending.empty()) {

2732

2734

2735 while (!Worklist.empty()) {

2736 MachineBasicBlock *MBB = OrderToBB[Worklist.top()];

2738 Worklist.pop();

2739

2740

2741 bool InLocsChanged;

2742 InLocsChanged = mlocJoin(*MBB, Visited, MOutLocs, MInLocs[*MBB]);

2743 InLocsChanged |= Visited.insert(MBB).second;

2744

2745

2746

2747 if (!InLocsChanged)

2748 continue;

2749

2750

2751 MTracker->loadFromArray(MInLocs[*MBB], CurBB);

2752

2753

2754

2755 ToRemap.clear();

2756 for (auto &P : MLocTransfer[CurBB]) {

2757 if (P.second.getBlock() == CurBB && P.second.isPHI()) {

2758

2759 ValueIDNum NewID = MTracker->readMLoc(P.second.getLoc());

2760 ToRemap.push_back(std::make_pair(P.first, NewID));

2761 } else {

2762

2763 assert(P.second.getBlock() == CurBB);

2764 ToRemap.push_back(std::make_pair(P.first, P.second));

2765 }

2766 }

2767

2768

2769

2770 for (auto &P : ToRemap)

2771 MTracker->setMLoc(P.first, P.second);

2772

2773

2774

2775

2776 bool OLChanged = false;

2777 for (auto Location : MTracker->locations()) {

2780 }

2781

2782 MTracker->reset();

2783

2784

2785 if (!OLChanged)

2786 continue;

2787

2788

2789

2790

2792

2793 unsigned Order = BBToOrder[s];

2794 if (Order > BBToOrder[MBB]) {

2795

2796 if (OnWorklist.insert(s).second)

2797 Worklist.push(Order);

2798 } else {

2799

2800 if (OnPending.insert(s).second)

2801 Pending.push(Order);

2802 }

2803 }

2804 }

2805

2806 Worklist.swap(Pending);

2807 std::swap(OnPending, OnWorklist);

2808 OnPending.clear();

2809

2810

2811 assert(Pending.empty() && "Pending should be empty");

2812 }

2813

2814

2815

2816}

2817

2818void InstrRefBasedLDV::BlockPHIPlacement(

2822

2823

2824

2825 IDFCalculatorBase<MachineBasicBlock, false> IDF(*DomTree);

2826

2827 IDF.setLiveInBlocks(AllBlocks);

2828 IDF.setDefiningBlocks(DefBlocks);

2829 IDF.calculate(PHIBlocks);

2830}

2831

2832bool InstrRefBasedLDV::pickVPHILoc(

2836

2837

2838 if (BlockOrders.empty())

2839 return false;

2840

2841

2842

2843 SmallDenseSet LocOpsToJoin;

2844

2845 auto FirstValueIt = LiveOuts.find(BlockOrders[0]);

2846 if (FirstValueIt == LiveOuts.end())

2847 return false;

2848 const DbgValue &FirstValue = *FirstValueIt->second;

2849

2850 for (const auto p : BlockOrders) {

2851 auto OutValIt = LiveOuts.find(p);

2852 if (OutValIt == LiveOuts.end())

2853

2854 return false;

2855 const DbgValue &OutVal = *OutValIt->second;

2856

2857

2859 return false;

2860

2861

2862

2864 return false;

2865

2867 return false;

2868

2869 for (unsigned Idx = 0; Idx < FirstValue.getLocationOpCount(); ++Idx) {

2870

2871

2873 LocOpsToJoin.insert(Idx);

2874 continue;

2875 }

2876 DbgOpID FirstValOp = FirstValue.getDbgOpID(Idx);

2877 DbgOpID OutValOp = OutVal.getDbgOpID(Idx);

2878 if (FirstValOp != OutValOp) {

2879

2880

2882 return false;

2883 else

2884 LocOpsToJoin.insert(Idx);

2885 }

2886 }

2887 }

2888

2890

2891 for (unsigned Idx = 0; Idx < FirstValue.getLocationOpCount(); ++Idx) {

2892

2893

2894 if (!LocOpsToJoin.contains(Idx)) {

2896 continue;

2897 }

2898

2899 std::optional JoinedOpLoc =

2900 pickOperandPHILoc(Idx, MBB, LiveOuts, MOutLocs, BlockOrders);

2901

2902 if (!JoinedOpLoc)

2903 return false;

2904

2905 NewDbgOps.push_back(DbgOpStore.insert(*JoinedOpLoc));

2906 }

2907

2908 OutValues.append(NewDbgOps);

2909 return true;

2910}

2911

2912std::optional InstrRefBasedLDV::pickOperandPHILoc(

2916

2917

2918

2920 unsigned NumLocs = MTracker->getNumLocs();

2921

2922 for (const auto p : BlockOrders) {

2923 auto OutValIt = LiveOuts.find(p);

2924 assert(OutValIt != LiveOuts.end());

2925 const DbgValue &OutVal = *OutValIt->second;

2926 DbgOpID OutValOpID = OutVal.getDbgOpID(DbgOpIdx);

2927 DbgOp OutValOp = DbgOpStore.find(OutValOpID);

2929

2930

2932

2933

2934

2938 ValueIDNum ValToLookFor = OutValOp.ID;

2939

2940 for (unsigned int I = 0; I < NumLocs; ++I) {

2941 if (MOutLocs[*p][I] == ValToLookFor)

2942 Locs.back().push_back(LocIdx(I));

2943 }

2944 } else {

2946

2947

2948

2949

2950

2951

2952 for (unsigned int I = 0; I < NumLocs; ++I) {

2954 if (MOutLocs[*p][I] == MPHI)

2955 Locs.back().push_back(LocIdx(I));

2956 }

2957 }

2958 }

2959

2960 assert(Locs.size() == BlockOrders.size());

2961

2962

2963

2965 for (unsigned int I = 1; I < Locs.size(); ++I) {

2966 auto &LocVec = Locs[I];

2968 std::set_intersection(CandidateLocs.begin(), CandidateLocs.end(),

2969 LocVec.begin(), LocVec.end(), std::inserter(NewCandidates, NewCandidates.begin()));

2970 CandidateLocs = std::move(NewCandidates);

2971 }

2972 if (CandidateLocs.empty())

2973 return std::nullopt;

2974

2975

2976

2977

2978 LocIdx L = *CandidateLocs.begin();

2979

2980

2981 ValueIDNum PHIVal = {(unsigned)MBB.getNumber(), 0, L};

2982 return PHIVal;

2983}

2984

2985bool InstrRefBasedLDV::vlocJoin(

2991

2992

2993 SmallVector<MachineBasicBlock *, 8> BlockOrders(MBB.predecessors());

2994

2995 auto Cmp = [&](MachineBasicBlock *A, MachineBasicBlock *B) {

2996 return BBToOrder[A] < BBToOrder[B];

2997 };

2998

3000

3001 unsigned CurBlockRPONum = BBToOrder[&MBB];

3002

3003

3004

3006 bool Bail = false;

3007 int BackEdgesStart = 0;

3008 for (auto *p : BlockOrders) {

3009

3010

3011 if (!BlocksToExplore.contains(p)) {

3012 Bail = true;

3013 break;

3014 }

3015

3016

3017 DbgValue &OutLoc = *VLOCOutLocs.find(p)->second;

3018

3019

3020

3021 unsigned ThisBBRPONum = BBToOrder[p];

3022 if (ThisBBRPONum < CurBlockRPONum)

3023 ++BackEdgesStart;

3024

3025 Values.push_back(std::make_pair(p, &OutLoc));

3026 }

3027

3028

3029

3030

3031 if (Bail || Values.size() == 0)

3032 return false;

3033

3034

3035

3036

3037 const DbgValue &FirstVal = *Values[0].second;

3038

3039

3040

3041

3043 Changed = LiveIn != FirstVal;

3045 LiveIn = FirstVal;

3047 }

3048

3049

3050

3051

3052 for (const auto &V : Values) {

3053 if (V.second->Properties.isJoinable(FirstVal.Properties))

3054 return false;

3056 return false;

3057 if (V.second->hasJoinableLocOps(FirstVal))

3058 return false;

3059 }

3060

3061

3062 bool Disagree = false;

3063 for (auto &V : Values) {

3064 if (*V.second == FirstVal)

3065 continue;

3066

3067

3068

3069

3070 if (V.second->hasIdenticalValidLocOps(FirstVal))

3071 continue;

3072

3073

3076

3077 std::distance(Values.begin(), &V) >= BackEdgesStart)

3078 continue;

3079

3080 Disagree = true;

3081 }

3082

3083

3084 if (!Disagree) {

3085 Changed = LiveIn != FirstVal;

3087 LiveIn = FirstVal;

3089 } else {

3090

3092 Changed = LiveIn != VPHI;

3094 LiveIn = VPHI;

3096 }

3097}

3098

3099void InstrRefBasedLDV::getBlocksForScope(

3103

3104 LS.getMachineBasicBlocks(DILoc, BlocksToExplore);

3105

3106

3107

3108

3110

3111

3112 DenseSet<const MachineBasicBlock *> ToAdd;

3113

3114

3115

3116

3117

3118

3119 for (const auto *MBB : BlocksToExplore) {

3120

3121

3122 SmallVector<std::pair<const MachineBasicBlock *,

3124 8>

3125 DFS;

3126

3127

3129 if (BlocksToExplore.count(succ))

3130 continue;

3131 if (!ArtificialBlocks.count(succ))

3132 continue;

3134 DFS.push_back({succ, succ->succ_begin()});

3135 }

3136

3137

3138 while (!DFS.empty()) {

3139 const MachineBasicBlock *CurBB = DFS.back().first;

3141

3142 if (CurSucc == CurBB->succ_end()) {

3143 DFS.pop_back();

3144 continue;

3145 }

3146

3147

3148

3149 if (!ToAdd.count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {

3150 ToAdd.insert(*CurSucc);

3151 DFS.push_back({*CurSucc, (*CurSucc)->succ_begin()});

3152 continue;

3153 }

3154

3155 ++CurSucc;

3156 }

3157 };

3158

3159 BlocksToExplore.insert_range(ToAdd);

3160}

3161

3162void InstrRefBasedLDV::buildVLocValueMap(

3168

3169

3170

3171

3172 std::priority_queue<unsigned int, std::vector,

3173 std::greater>

3174 Worklist, Pending;

3175 SmallPtrSet<MachineBasicBlock *, 16> OnWorklist, OnPending;

3176

3177

3178 SmallPtrSet<const MachineBasicBlock *, 8> BlocksToExplore;

3179

3180

3182 SmallVector<unsigned, 32> BlockOrderNums;

3183

3184 getBlocksForScope(DILoc, BlocksToExplore, AssignBlocks);

3185

3186

3187

3188

3189

3190 if (BlocksToExplore.size() == 1)

3191 return;

3192

3193

3194

3195

3196 SmallPtrSet<MachineBasicBlock *, 8> MutBlocksToExplore;

3197 for (const auto *MBB : BlocksToExplore)

3198 MutBlocksToExplore.insert(const_cast<MachineBasicBlock *>(MBB));

3199

3200

3201

3202

3203 for (const auto *MBB : BlocksToExplore)

3205

3207 for (unsigned int I : BlockOrderNums)

3208 BlockOrders.push_back(OrderToBB[I]);

3209 BlockOrderNums.clear();

3210 unsigned NumBlocks = BlockOrders.size();

3211

3212

3214 LiveIns.reserve(NumBlocks);

3215 LiveOuts.reserve(NumBlocks);

3216

3217

3218

3219 DbgValueProperties EmptyProperties(EmptyExpr, false, false);

3220 for (unsigned int I = 0; I < NumBlocks; ++I) {

3221 DbgValue EmptyDbgValue(I, EmptyProperties, DbgValue::NoVal);

3222 LiveIns.push_back(EmptyDbgValue);

3223 LiveOuts.push_back(EmptyDbgValue);

3224 }

3225

3226

3227

3228 LiveIdxT LiveOutIdx, LiveInIdx;

3229 LiveOutIdx.reserve(NumBlocks);

3230 LiveInIdx.reserve(NumBlocks);

3231 for (unsigned I = 0; I < NumBlocks; ++I) {

3232 LiveOutIdx[BlockOrders[I]] = &LiveOuts[I];

3233 LiveInIdx[BlockOrders[I]] = &LiveIns[I];

3234 }

3235

3236

3237

3238

3239

3241

3242

3243 for (unsigned int I = 0; I < NumBlocks; ++I) {

3244 DbgValue EmptyDbgValue(I, EmptyProperties, DbgValue::NoVal);

3245 LiveIns[I] = EmptyDbgValue;

3246 LiveOuts[I] = EmptyDbgValue;

3247 }

3248

3249

3250

3251 SmallPtrSet<MachineBasicBlock *, 32> DefBlocks;

3252 for (const MachineBasicBlock *ExpMBB : BlocksToExplore) {

3253 auto &TransferFunc = AllTheVLocs[ExpMBB->getNumber()].Vars;

3254 if (TransferFunc.contains(VarID))

3255 DefBlocks.insert(const_cast<MachineBasicBlock *>(ExpMBB));

3256 }

3257

3258 SmallVector<MachineBasicBlock *, 32> PHIBlocks;

3259

3260

3261

3262 if (DefBlocks.size() == 1) {

3263 placePHIsForSingleVarDefinition(MutBlocksToExplore, *DefBlocks.begin(),

3264 AllTheVLocs, VarID, Output);

3265 continue;

3266 }

3267

3268

3269 BlockPHIPlacement(MutBlocksToExplore, DefBlocks, PHIBlocks);

3270

3271

3272 for (MachineBasicBlock *PHIMBB : PHIBlocks) {

3273 unsigned BlockNo = PHIMBB->getNumber();

3274 DbgValue *LiveIn = LiveInIdx[PHIMBB];

3275 *LiveIn = DbgValue(BlockNo, EmptyProperties, DbgValue::VPHI);

3276 }

3277

3278 for (auto *MBB : BlockOrders) {

3279 Worklist.push(BBToOrder[MBB]);

3281 }

3282

3283

3284

3285

3286

3287

3288

3289

3290 bool FirstTrip = true;

3291 while (!Worklist.empty() || !Pending.empty()) {

3292 while (!Worklist.empty()) {

3293 auto *MBB = OrderToBB[Worklist.top()];

3295 Worklist.pop();

3296

3297 auto LiveInsIt = LiveInIdx.find(MBB);

3298 assert(LiveInsIt != LiveInIdx.end());

3299 DbgValue *LiveIn = LiveInsIt->second;

3300

3301

3302

3303 bool InLocsChanged =

3304 vlocJoin(*MBB, LiveOutIdx, BlocksToExplore, *LiveIn);

3305

3307

3308

3309

3310

3311

3313

3314

3315

3316

3318

3319 if (pickVPHILoc(JoinedOps, *MBB, LiveOutIdx, MOutLocs, Preds)) {

3320 bool NewLocPicked = equal(LiveIn->getDbgOpIDs(), JoinedOps);

3321 InLocsChanged |= NewLocPicked;

3322 if (NewLocPicked)

3324 }

3325 }

3326

3327 if (!InLocsChanged && !FirstTrip)

3328 continue;

3329

3330 DbgValue *LiveOut = LiveOutIdx[MBB];

3331 bool OLChanged = false;

3332

3333

3334 auto &VTracker = AllTheVLocs[MBB->getNumber()];

3335 auto TransferIt = VTracker.Vars.find(VarID);

3336 if (TransferIt != VTracker.Vars.end()) {

3337

3340 if (*LiveOut != NewVal) {

3341 *LiveOut = NewVal;

3342 OLChanged = true;

3343 }

3344 } else {

3345

3346 if (*LiveOut != TransferIt->second) {

3347 *LiveOut = TransferIt->second;

3348 OLChanged = true;

3349 }

3350 }

3351 } else {

3352

3353 if (*LiveOut != *LiveIn) {

3354 *LiveOut = *LiveIn;

3355 OLChanged = true;

3356 }

3357 }

3358

3359

3360 if (!OLChanged)

3361 continue;

3362

3363

3364

3365

3367

3368 if (!LiveInIdx.contains(s))

3369 continue;

3370

3371 unsigned Order = BBToOrder[s];

3372 if (Order > BBToOrder[MBB]) {

3373 if (OnWorklist.insert(s).second)

3374 Worklist.push(Order);

3375 } else if (OnPending.insert(s).second && (FirstTrip || OLChanged)) {

3376 Pending.push(Order);

3377 }

3378 }

3379 }

3380 Worklist.swap(Pending);

3381 std::swap(OnWorklist, OnPending);

3382 OnPending.clear();

3383 assert(Pending.empty());

3384 FirstTrip = false;

3385 }

3386

3387

3388

3389

3390 for (auto *MBB : BlockOrders) {

3391 DbgValue *BlockLiveIn = LiveInIdx[MBB];

3393 continue;

3395 continue;

3398 [[maybe_unused]] auto &[Var, DILoc] = DVMap.lookupDVID(VarID);

3400 Var.getFragment() &&

3401 "Fragment info missing during value prop");

3402 Output[MBB->getNumber()].push_back(std::make_pair(VarID, *BlockLiveIn));

3403 }

3404 }

3405

3406 BlockOrders.clear();

3407 BlocksToExplore.clear();

3408}

3409

3410void InstrRefBasedLDV::placePHIsForSingleVarDefinition(

3414

3415

3416

3417

3418

3419

3420

3421

3422

3423

3424

3425 VLocTracker &VLocs = AllTheVLocs[AssignMBB->getNumber()];

3426 auto ValueIt = VLocs.Vars.find(VarID);

3427 const DbgValue &Value = ValueIt->second;

3428

3429

3430

3432 return;

3433

3434

3435

3436

3437 for (auto *ScopeBlock : InScopeBlocks) {

3438 if (!DomTree->properlyDominates(AssignMBB, ScopeBlock))

3439 continue;

3440

3441 Output[ScopeBlock->getNumber()].push_back({VarID, Value});

3442 }

3443

3444

3445

3446}

3447

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

3451 for (const auto &P : mloc_transfer) {

3452 std::string foo = MTracker->LocIdxToName(P.first);

3453 std::string bar = MTracker->IDAsString(P.second);

3454 dbgs() << "Loc " << foo << " --> " << bar << "\n";

3455 }

3456}

3457#endif

3458

3459void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {

3460

3461

3464

3465 auto hasNonArtificialLocation = [](const MachineInstr &MI) -> bool {

3467 return DL.getLine() != 0;

3468 return false;

3469 };

3470

3471

3472

3473 unsigned int Size = 0;

3474 for (auto &MBB : MF) {

3477 ArtificialBlocks.insert(&MBB);

3478 }

3479

3480

3481 ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);

3482 unsigned int RPONumber = 0;

3483 OrderToBB.reserve(Size);

3484 BBToOrder.reserve(Size);

3485 BBNumToRPO.reserve(Size);

3486 auto processMBB = [&](MachineBasicBlock *MBB) {

3487 OrderToBB.push_back(MBB);

3488 BBToOrder[MBB] = RPONumber;

3490 ++RPONumber;

3491 };

3492 for (MachineBasicBlock *MBB : RPOT)

3493 processMBB(MBB);

3494 for (MachineBasicBlock &MBB : MF)

3495 if (!BBToOrder.contains(&MBB))

3496 processMBB(&MBB);

3497

3498

3499 llvm::sort(MF.DebugValueSubstitutions);

3500

3501#ifdef EXPENSIVE_CHECKS

3502

3503

3504 if (MF.DebugValueSubstitutions.size() > 2) {

3505 for (auto It = MF.DebugValueSubstitutions.begin();

3506 It != std::prev(MF.DebugValueSubstitutions.end()); ++It) {

3507 assert(It->Src != std::next(It)->Src && "Duplicate variable location "

3508 "substitution seen");

3509 }

3510 }

3511#endif

3512}

3513

3514

3515

3516

3517void InstrRefBasedLDV::makeDepthFirstEjectionMap(

3519 const ScopeToDILocT &ScopeToDILocation,

3520 ScopeToAssignBlocksT &ScopeToAssignBlocks) {

3521 SmallPtrSet<const MachineBasicBlock *, 8> BlocksToExplore;

3523 auto *TopScope = LS.getCurrentFunctionScope();

3524

3525

3526

3527 WorkStack.push_back({TopScope, TopScope->getChildren().size() - 1});

3528

3529 while (!WorkStack.empty()) {

3530 auto &ScopePosition = WorkStack.back();

3531 LexicalScope *WS = ScopePosition.first;

3532 ssize_t ChildNum = ScopePosition.second--;

3533

3535 if (ChildNum >= 0) {

3536

3537

3538 auto &ChildScope = Children[ChildNum];

3540 std::make_pair(ChildScope, ChildScope->getChildren().size() - 1));

3541 } else {

3543

3544

3545

3546

3547 auto DILocationIt = ScopeToDILocation.find(WS);

3548 if (DILocationIt != ScopeToDILocation.end()) {

3549 getBlocksForScope(DILocationIt->second, BlocksToExplore,

3550 ScopeToAssignBlocks.find(WS)->second);

3551 for (const auto *MBB : BlocksToExplore) {

3553 if (EjectionMap[BBNum] == 0)

3554 EjectionMap[BBNum] = WS->getDFSOut();

3555 }

3556

3557 BlocksToExplore.clear();

3558 }

3559 }

3560 }

3561}

3562

3563bool InstrRefBasedLDV::depthFirstVLocAndEmit(

3564 unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation,

3565 const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,

3568 bool ShouldEmitDebugEntryValues) {

3569 TTracker = new TransferTracker(TII, MTracker, MF, DVMap, *TRI,

3570 CalleeSavedRegs, ShouldEmitDebugEntryValues);

3571 unsigned NumLocs = MTracker->getNumLocs();

3572 VTracker = nullptr;

3573

3574

3575 if (!LS.getCurrentFunctionScope())

3576 return false;

3577

3578

3579 SmallVector<unsigned, 16> EjectionMap;

3581 makeDepthFirstEjectionMap(EjectionMap, ScopeToDILocation,

3582 ScopeToAssignBlocks);

3583

3584

3585

3586

3587 auto EjectBlock = [&](MachineBasicBlock &MBB) -> void {

3589 AllTheVLocs[BBNum].clear();

3590

3591

3592

3593 MTracker->reset();

3594 MTracker->loadFromArray(MInLocs[MBB], BBNum);

3595 TTracker->loadInlocs(MBB, MInLocs[MBB], DbgOpStore, Output[BBNum], NumLocs);

3596

3597 CurBB = BBNum;

3598 CurInst = 1;

3599 for (auto &MI : MBB) {

3600 process(MI, &MOutLocs, &MInLocs);

3601 TTracker->checkInstForNewValues(CurInst, MI.getIterator());

3602 ++CurInst;

3603 }

3604

3605

3608

3609 Output[BBNum].clear();

3610 AllTheVLocs[BBNum].clear();

3611 };

3612

3613 SmallPtrSet<const MachineBasicBlock *, 8> BlocksToExplore;

3615 WorkStack.push_back({LS.getCurrentFunctionScope(), 0});

3616 unsigned HighestDFSIn = 0;

3617

3618

3619 while (!WorkStack.empty()) {

3620 auto &ScopePosition = WorkStack.back();

3621 LexicalScope *WS = ScopePosition.first;

3622 ssize_t ChildNum = ScopePosition.second++;

3623

3624

3625

3626

3627

3628

3629 auto DILocIt = ScopeToDILocation.find(WS);

3630 if (HighestDFSIn <= WS->getDFSIn() && DILocIt != ScopeToDILocation.end()) {

3631 const DILocation *DILoc = DILocIt->second;

3632 auto &VarsWeCareAbout = ScopeToVars.find(WS)->second;

3633 auto &BlocksInScope = ScopeToAssignBlocks.find(WS)->second;

3634

3635 buildVLocValueMap(DILoc, VarsWeCareAbout, BlocksInScope, Output, MOutLocs,

3636 MInLocs, AllTheVLocs);

3637 }

3638

3639 HighestDFSIn = std::max(HighestDFSIn, WS->getDFSIn());

3640

3641

3643 if (ChildNum < (ssize_t)Children.size()) {

3644

3645 auto &ChildScope = Children[ChildNum];

3646 WorkStack.push_back(std::make_pair(ChildScope, 0));

3647 } else {

3649

3650

3651

3652 auto DILocationIt = ScopeToDILocation.find(WS);

3653 if (DILocationIt == ScopeToDILocation.end())

3654 continue;

3655

3656 getBlocksForScope(DILocationIt->second, BlocksToExplore,

3657 ScopeToAssignBlocks.find(WS)->second);

3658 for (const auto *MBB : BlocksToExplore)

3660 EjectBlock(const_cast<MachineBasicBlock &>(*MBB));

3661

3662 BlocksToExplore.clear();

3663 }

3664 }

3665

3666

3667

3668

3669

3670

3671 for (auto *MBB : ArtificialBlocks)

3673 EjectBlock(*MBB);

3674

3675 return emitTransfers();

3676}

3677

3678bool InstrRefBasedLDV::emitTransfers() {

3679

3680

3681

3682 for (auto &P : TTracker->Transfers) {

3683

3684

3685

3686

3687 llvm::sort(P.Insts, llvm::less_first());

3688

3689

3690 if (P.MBB) {

3691 MachineBasicBlock &MBB = *P.MBB;

3692 for (const auto &Pair : P.Insts)

3694 } else {

3695

3696

3697 if (P.Pos->isTerminator())

3698 continue;

3699

3701 for (const auto &Pair : P.Insts)

3703 }

3704 }

3705

3706 return TTracker->Transfers.size() != 0;

3707}

3708

3709

3710

3713 bool ShouldEmitDebugEntryValues,

3715 unsigned InputDbgValLimit) {

3716

3718 return false;

3719

3721

3722 this->DomTree = DomTree;

3729 LS.scanFunction(MF);

3730

3732 AdjustsStackInCalls = MFI->adjustsStack() &&

3734 if (AdjustsStackInCalls)

3735 StackProbeSymbolName = STI.getTargetLowering()->getStackProbeSymbolName(MF);

3736

3737 MTracker =

3739 VTracker = nullptr;

3740 TTracker = nullptr;

3741

3745

3747 for (auto &MBB : MF)

3751

3752 initialSetup(MF);

3753

3755 vlocs.resize(MaxNumBlocks, VLocTracker(DVMap, OverlapFragments, EmptyExpr));

3757

3758 produceMLocTransferFunction(MF, MLocTransfer, MaxNumBlocks);

3759

3760

3761

3762

3763 unsigned NumLocs = MTracker->getNumLocs();

3764 FuncValueTable MOutLocs(MaxNumBlocks, NumLocs);

3765 FuncValueTable MInLocs(MaxNumBlocks, NumLocs);

3766

3767

3768

3769

3770

3771 buildMLocValueMap(MF, MInLocs, MOutLocs, MLocTransfer);

3772

3773

3774

3775 for (auto &DBG_PHI : DebugPHINumToValue) {

3776

3777 if (!DBG_PHI.ValueRead)

3778 continue;

3779

3780 ValueIDNum &Num = *DBG_PHI.ValueRead;

3781 if (!Num.isPHI())

3782 continue;

3783

3784 unsigned BlockNo = Num.getBlock();

3785 LocIdx LocNo = Num.getLoc();

3786 ValueIDNum ResolvedValue = MInLocs[BlockNo][LocNo.asU64()];

3787

3788

3789

3791 Num = ResolvedValue;

3792 }

3793

3795

3796

3797

3798 for (MachineBasicBlock *MBB : OrderToBB) {

3800 VTracker = &vlocs[CurBB];

3801 VTracker->MBB = MBB;

3802 MTracker->loadFromArray(MInLocs[*MBB], CurBB);

3803 CurInst = 1;

3804 for (auto &MI : *MBB) {

3805 process(MI, &MOutLocs, &MInLocs);

3806 ++CurInst;

3807 }

3808 MTracker->reset();

3809 }

3810

3811

3813

3814

3815

3817

3818

3820

3821

3822

3823 unsigned VarAssignCount = 0;

3824 for (MachineBasicBlock *MBB : OrderToBB) {

3826

3827 for (auto &idx : VTracker->Vars) {

3829 const DILocation *ScopeLoc = VTracker->Scopes[VarID];

3830 assert(ScopeLoc != nullptr);

3831 auto *Scope = LS.findLexicalScope(ScopeLoc);

3832

3833

3834 assert(Scope != nullptr);

3835

3837 ScopeToAssignBlocks[Scope].insert(VTracker->MBB);

3838 ScopeToDILocation[Scope] = ScopeLoc;

3839 ++VarAssignCount;

3840 }

3841 }

3842

3844

3845

3846

3847

3849 VarAssignCount > InputDbgValLimit) {

3850 LLVM_DEBUG(dbgs() << "Disabling InstrRefBasedLDV: " << MF.getName()

3851 << " has " << MaxNumBlocks << " basic blocks and "

3852 << VarAssignCount

3853 << " variable assignments, exceeding limits.\n");

3854 } else {

3855

3856

3857

3858 Changed = depthFirstVLocAndEmit(

3859 MaxNumBlocks, ScopeToDILocation, ScopeToVars, ScopeToAssignBlocks,

3860 SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, ShouldEmitDebugEntryValues);

3861 }

3862

3863 delete MTracker;

3864 delete TTracker;

3865 MTracker = nullptr;

3866 VTracker = nullptr;

3867 TTracker = nullptr;

3868

3869 ArtificialBlocks.clear();

3870 OrderToBB.clear();

3871 BBToOrder.clear();

3872 BBNumToRPO.clear();

3873 DebugInstrNumToInstr.clear();

3874 DebugPHINumToValue.clear();

3875 OverlapFragments.clear();

3876 SeenFragments.clear();

3877 SeenDbgPHIs.clear();

3878 DbgOpStore.clear();

3879 DVMap.clear();

3880

3882}

3883

3887

3888namespace {

3889class LDVSSABlock;

3890class LDVSSAUpdater;

3891

3892

3893

3894

3895typedef uint64_t BlockValueNum;

3896

3897

3898

3899

3900class LDVSSAPhi {

3901public:

3903 LDVSSABlock *ParentBlock;

3904 BlockValueNum PHIValNum;

3905 LDVSSAPhi(BlockValueNum PHIValNum, LDVSSABlock *ParentBlock)

3906 : ParentBlock(ParentBlock), PHIValNum(PHIValNum) {}

3907

3908 LDVSSABlock *getParent() { return ParentBlock; }

3909};

3910

3911

3912

3913class LDVSSABlockIterator {

3914public:

3916 LDVSSAUpdater &Updater;

3917

3919 LDVSSAUpdater &Updater)

3920 : PredIt(PredIt), Updater(Updater) {}

3921

3922 bool operator!=(const LDVSSABlockIterator &OtherIt) const {

3923 return OtherIt.PredIt != PredIt;

3924 }

3925

3926 LDVSSABlockIterator &operator++() {

3927 ++PredIt;

3928 return *this;

3929 }

3930

3932};

3933

3934

3935

3936

3937class LDVSSABlock {

3938public:

3939 MachineBasicBlock &BB;

3940 LDVSSAUpdater &Updater;

3941 using PHIListT = SmallVector<LDVSSAPhi, 1>;

3942

3943 PHIListT PHIList;

3944

3945 LDVSSABlock(MachineBasicBlock &BB, LDVSSAUpdater &Updater)

3946 : BB(BB), Updater(Updater) {}

3947

3949 return LDVSSABlockIterator(BB.succ_begin(), Updater);

3950 }

3951

3952 LDVSSABlockIterator succ_end() {

3953 return LDVSSABlockIterator(BB.succ_end(), Updater);

3954 }

3955

3956

3957 LDVSSAPhi *newPHI(BlockValueNum Value) {

3958 PHIList.emplace_back(Value, this);

3959 return &PHIList.back();

3960 }

3961

3962

3963 PHIListT &phis() { return PHIList; }

3964};

3965

3966

3967

3968

3969class LDVSSAUpdater {

3970public:

3971

3972 DenseMap<BlockValueNum, LDVSSAPhi *> PHIs;

3973

3974

3975 DenseMap<MachineBasicBlock *, BlockValueNum> PoisonMap;

3976

3977 DenseMap<MachineBasicBlock *, LDVSSABlock *> BlockMap;

3978

3979 LocIdx Loc;

3980

3981 const FuncValueTable &MLiveIns;

3982

3983 LDVSSAUpdater(LocIdx L, const FuncValueTable &MLiveIns)

3984 : Loc(L), MLiveIns(MLiveIns) {}

3985

3986 void reset() {

3987 for (auto &Block : BlockMap)

3988 delete Block.second;

3989

3991 PoisonMap.clear();

3992 BlockMap.clear();

3993 }

3994

3995 ~LDVSSAUpdater() { reset(); }

3996

3997

3998

3999 LDVSSABlock *getSSALDVBlock(MachineBasicBlock *BB) {

4000 auto [It, Inserted] = BlockMap.try_emplace(BB);

4001 if (Inserted)

4002 It->second = new LDVSSABlock(*BB, *this);

4003 return It->second;

4004 }

4005

4006

4007

4008 BlockValueNum getValue(LDVSSABlock *LDVBB) {

4009 return MLiveIns[LDVBB->BB][Loc.asU64()].asU64();

4010 }

4011};

4012

4013LDVSSABlock *LDVSSABlockIterator::operator*() {

4014 return Updater.getSSALDVBlock(*PredIt);

4015}

4016

4017#ifndef NDEBUG

4018

4020 out << "SSALDVPHI " << PHI.PHIValNum;

4021 return out;

4022}

4023

4024#endif

4025

4026}

4027

4028namespace llvm {

4029

4030

4031

4032

4033

4035public:

4040

4041

4044

4045

4047 private:

4048 LDVSSAPhi *PHI;

4049 unsigned Idx;

4050

4051 public:

4055 : PHI(P), Idx(PHI->IncomingValues.size()) {}

4056

4058 Idx++;

4059 return *this;

4060 }

4063

4064 BlockValueNum getIncomingValue() { return PHI->IncomingValues[Idx].second; }

4065

4067 };

4068

4070

4074

4075

4076

4080 Preds->push_back(BB->Updater.getSSALDVBlock(Pred));

4081 }

4082

4083

4084

4085

4086 static BlockValueNum GetPoisonVal(LDVSSABlock *BB, LDVSSAUpdater *Updater) {

4087

4088

4089

4091 Updater->PoisonMap[&BB->BB] = Num;

4092 return Num;

4093 }

4094

4095

4096

4097

4098

4099

4100 static BlockValueNum CreateEmptyPHI(LDVSSABlock *BB, unsigned NumPreds,

4101 LDVSSAUpdater *Updater) {

4102 BlockValueNum PHIValNum = Updater->getValue(BB);

4103 LDVSSAPhi *PHI = BB->newPHI(PHIValNum);

4104 Updater->PHIs[PHIValNum] = PHI;

4105 return PHIValNum;

4106 }

4107

4108

4109

4110 static void AddPHIOperand(LDVSSAPhi *PHI, BlockValueNum Val, LDVSSABlock *Pred) {

4111 PHI->IncomingValues.push_back(std::make_pair(Pred, Val));

4112 }

4113

4114

4115

4116 static LDVSSAPhi *ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater) {

4117 return Updater->PHIs.lookup(Val);

4118 }

4119

4120

4121

4122 static LDVSSAPhi *ValueIsNewPHI(BlockValueNum Val, LDVSSAUpdater *Updater) {

4124 if (PHI && PHI->IncomingValues.size() == 0)

4125 return PHI;

4126 return nullptr;

4127 }

4128

4129

4130

4132};

4133

4134}

4135

4136std::optional InstrRefBasedLDV::resolveDbgPHIs(

4139

4140

4141 auto SeenDbgPHIIt = SeenDbgPHIs.find(std::make_pair(&Here, InstrNum));

4142 if (SeenDbgPHIIt != SeenDbgPHIs.end())

4143 return SeenDbgPHIIt->second;

4144

4145 std::optional Result =

4146 resolveDbgPHIsImpl(MF, MLiveOuts, MLiveIns, Here, InstrNum);

4147 SeenDbgPHIs.insert({std::make_pair(&Here, InstrNum), Result});

4149}

4150

4151std::optional InstrRefBasedLDV::resolveDbgPHIsImpl(

4154

4155

4156 auto RangePair = std::equal_range(DebugPHINumToValue.begin(),

4157 DebugPHINumToValue.end(), InstrNum);

4158 auto LowerIt = RangePair.first;

4159 auto UpperIt = RangePair.second;

4160

4161

4162 if (LowerIt == UpperIt)

4163 return std::nullopt;

4164

4165

4166

4167

4168

4169 auto DBGPHIRange = make_range(LowerIt, UpperIt);

4170 for (const DebugPHIRecord &DBG_PHI : DBGPHIRange)

4171 if (!DBG_PHI.ValueRead)

4172 return std::nullopt;

4173

4174

4175 if (std::distance(LowerIt, UpperIt) == 1)

4176 return *LowerIt->ValueRead;

4177

4178

4179

4180

4181

4182 LocIdx Loc = *LowerIt->ReadLoc;

4183

4184

4185

4186

4187

4188

4189

4190

4191 LDVSSAUpdater Updater(Loc, MLiveIns);

4192

4193 DenseMap<LDVSSABlock *, BlockValueNum> AvailableValues;

4194

4196

4197

4198

4199 for (const auto &DBG_PHI : DBGPHIRange) {

4200 LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB);

4201 const ValueIDNum &Num = *DBG_PHI.ValueRead;

4203 }

4204

4205 LDVSSABlock *HereBlock = Updater.getSSALDVBlock(Here.getParent());

4206 const auto &AvailIt = AvailableValues.find(HereBlock);

4207 if (AvailIt != AvailableValues.end()) {

4208

4209

4211 }

4212

4213

4214

4215 SSAUpdaterImpl Impl(&Updater, &AvailableValues, &CreatedPHIs);

4216 BlockValueNum ResultInt = Impl.GetValue(Updater.getSSALDVBlock(Here.getParent()));

4218

4219

4220

4221

4222

4223

4224

4225

4226

4227

4228

4229

4230 DenseMap<LDVSSABlock *, ValueIDNum> ValidatedValues;

4231

4232

4233 for (const auto &DBG_PHI : DBGPHIRange) {

4234 LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB);

4235 const ValueIDNum &Num = *DBG_PHI.ValueRead;

4236 ValidatedValues.insert(std::make_pair(Block, Num));

4237 }

4238

4239

4241

4242 llvm::sort(SortedPHIs, [&](LDVSSAPhi *A, LDVSSAPhi *B) {

4243 return BBToOrder[&A->getParent()->BB] < BBToOrder[&B->getParent()->BB];

4244 });

4245

4246 for (auto &PHI : SortedPHIs) {

4247 ValueIDNum ThisBlockValueNum = MLiveIns[PHI->ParentBlock->BB][Loc.asU64()];

4248

4249

4250 for (auto &PHIIt : PHI->IncomingValues) {

4251

4252 if (Updater.PoisonMap.contains(&PHIIt.first->BB))

4253 return std::nullopt;

4254

4255 ValueIDNum ValueToCheck;

4256 const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB];

4257

4258 auto VVal = ValidatedValues.find(PHIIt.first);

4259 if (VVal == ValidatedValues.end()) {

4260

4261

4262

4263

4264 ValueToCheck = ThisBlockValueNum;

4265 } else {

4266

4267

4268 ValueToCheck = VVal->second;

4269 }

4270

4271 if (BlockLiveOuts[Loc.asU64()] != ValueToCheck)

4272 return std::nullopt;

4273 }

4274

4275

4276 ValidatedValues.insert({PHI->ParentBlock, ThisBlockValueNum});

4277 }

4278

4279

4280

4282}

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static cl::opt< unsigned > MaxNumBlocks("debug-ata-max-blocks", cl::init(10000), cl::desc("Maximum num basic blocks before debug info dropped"), cl::Hidden)

static const Function * getParent(const Value *V)

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

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 contains constants used for implementing Dwarf debug support.

Compute iterated dominance frontiers using a linear time algorithm.

static cl::opt< unsigned > StackWorkingSetLimit("livedebugvalues-max-stack-slots", cl::Hidden, cl::desc("livedebugvalues-stack-ws-limit"), cl::init(250))

static cl::opt< bool > EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden, cl::desc("Act like old LiveDebugValues did"), cl::init(false))

static cl::opt< unsigned > InputBBLimit("livedebugvalues-input-bb-limit", cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), cl::init(10000), cl::Hidden)

Promote Memory to Register

This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.

This file defines the SmallPtrSet class.

This file defines the SmallSet class.

This file defines the SmallVector class.

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

This file describes how to lower LLVM code to machine code.

Class storing the complete set of values that are observed by DbgValues within the current function.

DbgOp find(DbgOpID ID) const

Returns the DbgOp associated with ID.

DbgOpID insert(DbgOp Op)

If Op does not already exist in this map, it is inserted and the corresponding DbgOpID is returned.

Meta qualifiers for a value.

const DIExpression * DIExpr

bool isJoinable(const DbgValueProperties &Other) const

unsigned getLocationOpCount() const

Class recording the (high level) value of a variable.

int BlockNo

For a NoVal or VPHI DbgValue, which block it was generated in.

DbgValueProperties Properties

Qualifiers for the ValueIDNum above.

ArrayRef< DbgOpID > getDbgOpIDs() const

void setDbgOpIDs(ArrayRef< DbgOpID > NewIDs)

void dump(const MLocTracker *MTrack=nullptr, const DbgOpIDMap *OpStore=nullptr) const

Definition InstrRefBasedImpl.cpp:1012

bool isUnjoinedPHI() const

DbgOpID getDbgOpID(unsigned Index) const

KindT Kind

Discriminator for whether this is a constant or an in-program value.

unsigned getLocationOpCount() const

Mapping from DebugVariable to/from a unique identifying number.

DenseMap< const LexicalScope *, const DILocation * > ScopeToDILocT

Mapping from lexical scopes to a DILocation in that scope.

std::optional< LocIdx > findLocationForMemOperand(const MachineInstr &MI)

Definition InstrRefBasedImpl.cpp:1414

SmallVector< SmallVector< VarAndLoc, 8 >, 8 > LiveInsT

Vector (per block) of a collection (inner smallvector) of live-ins.

LLVM_ABI_FOR_TEST InstrRefBasedLDV()

Default construct and initialize the pass.

DenseMap< const LexicalScope *, SmallPtrSet< MachineBasicBlock *, 4 > > ScopeToAssignBlocksT

Mapping from lexical scopes to blocks where variables in that scope are assigned.

DIExpression::FragmentInfo FragmentInfo

DenseMap< const LexicalScope *, SmallSet< DebugVariableID, 4 > > ScopeToVarsT

Mapping from lexical scopes to variables in that scope.

SmallDenseMap< const MachineBasicBlock *, DbgValue *, 16 > LiveIdxT

Live in/out structure for the variable values: a per-block map of variables to their values.

SmallDenseMap< LocIdx, ValueIDNum > MLocTransferMap

Machine location/value transfer function, a mapping of which locations are assigned which new values.

bool hasFoldedStackStore(const MachineInstr &MI)

bool isCalleeSaved(LocIdx L) const

Definition InstrRefBasedImpl.cpp:1378

bool isCalleeSavedReg(Register R) const

Definition InstrRefBasedImpl.cpp:1382

LLVM_DUMP_METHOD void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const

Definition InstrRefBasedImpl.cpp:3449

Handle-class for a particular "location".

static LocIdx MakeIllegalLoc()

Tracker for what values are in machine locations.

unsigned getLocSizeInBits(LocIdx L) const

How large is this location (aka, how wide is a value defined there?).

LLVM_ABI_FOR_TEST std::optional< SpillLocationNo > getOrTrackSpillLoc(SpillLoc L)

Find LocIdx for SpillLoc L, creating a new one if it's not tracked.

Definition InstrRefBasedImpl.cpp:1139

IndexedMap< unsigned, LocIdxToIndexFunctor > LocIdxToLocID

Inverse map of LocIDToLocIdx.

unsigned getSpillIDWithIdx(SpillLocationNo Spill, unsigned Idx)

Given a spill number, and a slot within the spill, calculate the ID number for that location.

iterator_range< MLocIterator > locations()

Return a range over all locations currently tracked.

SmallSet< Register, 8 > SPAliases

When clobbering register masks, we chose to not believe the machine model and don't clobber SP.

unsigned getLocID(Register Reg)

Produce location ID number for a Register.

const TargetLowering & TLI

const TargetRegisterInfo & TRI

unsigned NumRegs

Cached local copy of the number of registers the target has.

DenseMap< StackSlotPos, unsigned > StackSlotIdxes

Map from a size/offset pair describing a position in a stack slot, to a numeric identifier for that p...

LocIdx lookupOrTrackRegister(unsigned ID)

SpillLocationNo locIDToSpill(unsigned ID) const

Return the spill number that a location ID corresponds to.

void reset()

Wipe any un-necessary location records after traversing a block.

DenseMap< unsigned, StackSlotPos > StackIdxesToPos

Inverse of StackSlotIdxes.

std::string IDAsString(const ValueIDNum &Num) const

Definition InstrRefBasedImpl.cpp:1181

void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID)

Record a RegMask operand being executed.

Definition InstrRefBasedImpl.cpp:1125

std::pair< unsigned short, unsigned short > StackSlotPos

Pair for describing a position within a stack slot – first the size in bits, then the offset.

const TargetInstrInfo & TII

MachineInstrBuilder emitLoc(const SmallVectorImpl< ResolvedDbgOp > &DbgOps, const DebugVariable &Var, const DILocation *DILoc, const DbgValueProperties &Properties)

Create a DBG_VALUE based on debug operands DbgOps.

Definition InstrRefBasedImpl.cpp:1204

LocToValueType LocIdxToIDNum

Map of LocIdxes to the ValueIDNums that they store.

std::vector< LocIdx > LocIDToLocIdx

"Map" of machine location IDs (i.e., raw register or spill number) to the LocIdx key / number for tha...

SmallVector< std::pair< const MachineOperand *, unsigned >, 32 > Masks

Collection of register mask operands that have been observed.

unsigned NumSlotIdxes

Number of slot indexes the target has – distinct segments of a stack slot that can take on the value ...

UniqueVector< SpillLoc > SpillLocs

Unique-ification of spill.

ValueIDNum readReg(Register R)

void defReg(Register R, unsigned BB, unsigned Inst)

Record a definition of the specified register at the given block / inst.

LLVM_DUMP_METHOD void dump()

Definition InstrRefBasedImpl.cpp:1187

LLVM_ABI_FOR_TEST LocIdx trackRegister(unsigned ID)

Create a LocIdx for an untracked register ID.

Definition InstrRefBasedImpl.cpp:1103

LLVM_ABI_FOR_TEST MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const TargetLowering &TLI)

Definition InstrRefBasedImpl.cpp:1035

LLVM_DUMP_METHOD void dump_mloc_map()

Definition InstrRefBasedImpl.cpp:1195

StackSlotPos locIDToSpillIdx(unsigned ID) const

Returns the spill-slot size/offs that a location ID corresponds to.

std::string LocIdxToName(LocIdx Idx) const

Definition InstrRefBasedImpl.cpp:1166

Thin wrapper around an integer – designed to give more type safety to spill location numbers.

SmallMapVector< DebugVariableID, DbgValue, 8 > Vars

Map DebugVariable to the latest Value it's defined to have.

Unique identifier for a value defined by an instruction, as a value type.

static ValueIDNum fromU64(uint64_t v)

std::string asString(const std::string &mlocname) const

static LLVM_ABI_FOR_TEST ValueIDNum EmptyValue

static LLVM_ABI_FOR_TEST ValueIDNum TombstoneValue

uint64_t getBlock() const

LocationAndQuality(LocIdx L, LocationQuality Q)

Definition InstrRefBasedImpl.cpp:309

LocationQuality getQuality() const

Definition InstrRefBasedImpl.cpp:316

LocIdx getLoc() const

Definition InstrRefBasedImpl.cpp:311

bool isBest() const

Definition InstrRefBasedImpl.cpp:318

bool isIllegal() const

Definition InstrRefBasedImpl.cpp:317

LocationAndQuality()

Definition InstrRefBasedImpl.cpp:308

const DebugVariableMap & DVMap

Definition InstrRefBasedImpl.cpp:185

TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker, MachineFunction &MF, const DebugVariableMap &DVMap, const TargetRegisterInfo &TRI, const BitVector &CalleeSavedRegs, bool ShouldEmitDebugEntryValues)

Definition InstrRefBasedImpl.cpp:269

DenseSet< DebugVariableID > UseBeforeDefVariables

The set of variables that are in UseBeforeDefs and can become a location once the relevant value is d...

Definition InstrRefBasedImpl.cpp:264

const BitVector & CalleeSavedRegs

Definition InstrRefBasedImpl.cpp:267

void loadInlocs(MachineBasicBlock &MBB, ValueTable &MLocs, DbgOpIDMap &DbgOpStore, const SmallVectorImpl< std::pair< DebugVariableID, DbgValue > > &VLocs, unsigned NumLocs)

Load object with live-in variable values.

Definition InstrRefBasedImpl.cpp:459

const TargetLowering * TLI

Definition InstrRefBasedImpl.cpp:179

void addUseBeforeDef(DebugVariableID VarID, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOp > &DbgOps, unsigned Inst)

Record that Var has value ID, a value that becomes available later in the function.

Definition InstrRefBasedImpl.cpp:520

SmallVector< ValueIDNum, 32 > VarLocs

Local cache of what-value-is-in-what-LocIdx.

Definition InstrRefBasedImpl.cpp:227

MLocTracker * MTracker

This machine location tracker is assumed to always contain the up-to-date value mapping for all machi...

Definition InstrRefBasedImpl.cpp:183

void transferMlocs(LocIdx Src, LocIdx Dst, MachineBasicBlock::iterator Pos)

Transfer variables based on Src to be based on Dst.

Definition InstrRefBasedImpl.cpp:927

MachineFunction & MF

Definition InstrRefBasedImpl.cpp:184

std::optional< LocationQuality > getLocQualityIfBetter(LocIdx L, LocationQuality Min) const

Definition InstrRefBasedImpl.cpp:331

SmallVector< std::pair< DebugVariableID, MachineInstr * >, 4 > PendingDbgValues

Temporary cache of DBG_VALUEs to be entered into the Transfers collection.

Definition InstrRefBasedImpl.cpp:240

bool isEntryValueVariable(const DebugVariable &Var, const DIExpression *Expr) const

Definition InstrRefBasedImpl.cpp:628

void checkInstForNewValues(unsigned Inst, MachineBasicBlock::iterator pos)

After the instruction at index Inst and position pos has been processed, check whether it defines a v...

Definition InstrRefBasedImpl.cpp:531

const TargetInstrInfo * TII

Definition InstrRefBasedImpl.cpp:178

LocationQuality

Definition InstrRefBasedImpl.cpp:295

@ Register

Definition InstrRefBasedImpl.cpp:297

@ CalleeSavedRegister

Definition InstrRefBasedImpl.cpp:298

@ Best

Definition InstrRefBasedImpl.cpp:300

@ Illegal

Definition InstrRefBasedImpl.cpp:296

@ SpillSlot

Definition InstrRefBasedImpl.cpp:299

DenseMap< LocIdx, SmallSet< DebugVariableID, 4 > > ActiveMLocs

Map from LocIdxes to which DebugVariables are based that location.

Definition InstrRefBasedImpl.cpp:232

MachineInstrBuilder emitMOLoc(const MachineOperand &MO, const DebugVariable &Var, const DbgValueProperties &Properties)

Definition InstrRefBasedImpl.cpp:965

bool isEntryValueValue(const ValueIDNum &Val) const

Definition InstrRefBasedImpl.cpp:642

const TargetRegisterInfo & TRI

Definition InstrRefBasedImpl.cpp:266

void redefVar(const MachineInstr &MI)

Change a variable value after encountering a DBG_VALUE inside a block.

Definition InstrRefBasedImpl.cpp:709

bool recoverAsEntryValue(DebugVariableID VarID, const DbgValueProperties &Prop, const ValueIDNum &Num)

Definition InstrRefBasedImpl.cpp:657

bool isCalleeSaved(LocIdx L) const

Definition InstrRefBasedImpl.cpp:280

void clobberMloc(LocIdx MLoc, MachineBasicBlock::iterator Pos, bool MakeUndef=true)

Account for a location mloc being clobbered.

Definition InstrRefBasedImpl.cpp:818

void flushDbgValues(MachineBasicBlock::iterator Pos, MachineBasicBlock *MBB)

Helper to move created DBG_VALUEs into Transfers collection.

Definition InstrRefBasedImpl.cpp:613

DenseMap< DebugVariableID, ResolvedDbgValue > ActiveVLocs

Map from DebugVariable to it's current location and qualifying meta information.

Definition InstrRefBasedImpl.cpp:237

DenseMap< unsigned, SmallVector< UseBeforeDef, 1 > > UseBeforeDefs

Map from instruction index (within the block) to the set of UseBeforeDefs that become defined at that...

Definition InstrRefBasedImpl.cpp:259

void clobberMloc(LocIdx MLoc, ValueIDNum OldValue, MachineBasicBlock::iterator Pos, bool MakeUndef=true)

Overload that takes an explicit value OldValue for when the value in MLoc has changed and the Transfe...

Definition InstrRefBasedImpl.cpp:831

SmallVector< Transfer, 32 > Transfers

Collection of transfers (DBG_VALUEs) to be inserted.

Definition InstrRefBasedImpl.cpp:221

bool ShouldEmitDebugEntryValues

Definition InstrRefBasedImpl.cpp:186

void redefVar(const MachineInstr &MI, const DbgValueProperties &Properties, SmallVectorImpl< ResolvedDbgOp > &NewLocs)

Handle a change in variable location within a block.

Definition InstrRefBasedImpl.cpp:748

void loadVarInloc(MachineBasicBlock &MBB, DbgOpIDMap &DbgOpStore, const SmallVectorImpl< ValueLocPair > &ValueToLoc, DebugVariableID VarID, DbgValue Value)

For a variable Var with the live-in value Value, attempts to resolve the DbgValue to a concrete DBG_V...

Definition InstrRefBasedImpl.cpp:355

std::pair< ValueIDNum, LocationAndQuality > ValueLocPair

Definition InstrRefBasedImpl.cpp:321

static bool ValueToLocSort(const ValueLocPair &A, const ValueLocPair &B)

Definition InstrRefBasedImpl.cpp:323

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

iterator_range< const_set_bits_iterator > set_bits() const

LLVM_ABI bool isEntryValue() const

Check if the expression consists of exactly one entry value operand.

unsigned getNumElements() const

LLVM_ABI bool isImplicit() const

Return whether this is an implicit location description.

static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)

Check if fragments overlap between a pair of FragmentInfos.

static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)

Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...

LLVM_ABI bool isComplex() const

Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...

static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)

Retrieve the details of this fragment expression.

static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)

If Expr is a valid single-location expression, i.e.

LLVM_ABI bool isDeref() const

Return whether there is exactly one operator and it is a DW_OP_deref;.

static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)

Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...

LLVM_ABI bool isSingleLocationExpression() const

Return whether the evaluated expression makes use of a single location at the start of the expression...

DILocalScope * getScope() const

Get the local scope for this variable.

bool isValidLocationForIntrinsic(const DILocation *DL) const

Check that a location is valid for this variable.

LLVM_ABI std::optional< uint64_t > getSizeInBits() const

Determines the size of the variable's type.

Identifies a unique instance of a variable.

const DILocation * getInlinedAt() const

std::optional< FragmentInfo > getFragment() const

const DILocalVariable * getVariable() const

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Implements a dense probed hash-table based set.

DISubprogram * getSubprogram() const

Get the attached subprogram.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

This is an important class for using LLVM in a threaded context.

unsigned getDFSIn() const

SmallVectorImpl< LexicalScope * > & getChildren()

unsigned getDFSOut() const

LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)

Find lexical scope, either regular or inlined, for the given DebugLoc.

TypeSize getValue() const

Describe properties that are true of each instruction in the target description file.

MCRegAliasIterator enumerates all registers aliasing Reg.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

LLVMContext & getContext() const

LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

SmallVectorImpl< MachineBasicBlock * >::const_iterator const_succ_iterator

succ_iterator succ_begin()

LLVM_ABI bool isEntryBlock() const

Returns true if this is the entry block of the function.

SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator

Instructions::iterator instr_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

LLVM_ABI std::string getFullName() const

Return a formatted string to identify this block and its parent function.

iterator_range< succ_iterator > successors()

iterator_range< pred_iterator > predecessors()

MachineInstrBundleIterator< MachineInstr > iterator

instr_iterator insertAfterBundle(instr_iterator I, MachineInstr *MI)

If I is bundled then insert MI into the instruction list after the end of the bundle,...

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

SmallVector< DebugSubstitution, 8 > DebugValueSubstitutions

Debug value substitutions: a collection of DebugSubstitution objects, recording changes in where a va...

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

static const unsigned int DebugOperandMemNumber

A reserved operand number representing the instructions memory operand, for instructions that have a ...

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

unsigned getNumOperands() const

Retuns the total number of operands.

bool hasOneMemOperand() const

Return true if this instruction has exactly one MachineMemOperand.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

unsigned getInstrRefOpIndex() const

unsigned getInstrRefInstrIndex() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

bool isRegMask() const

isRegMask - Tests if this is a MO_RegisterMask operand.

static unsigned getRegMaskSize(unsigned NumRegs)

Returns number of elements needed for a regmask array.

Register getReg() const

getReg - Returns the register number.

bool isDbgInstrRef() const

bool isFI() const

isFI - Tests if this is a MO_FrameIndex operand.

static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)

clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.

const uint32_t * getRegMask() const

getRegMask - Returns a bit mask of registers preserved by this RegMask operand.

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

Special value supplied for machine level alias analysis.

virtual bool isAliased(const MachineFrameInfo *) const

Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...

Wrapper class representing virtual and physical registers.

constexpr bool isPhysical() const

Return true if the specified register number is in the physical register namespace.

Iterator for PHI operands.

Definition InstrRefBasedImpl.cpp:4046

BlockValueNum getIncomingValue()

Definition InstrRefBasedImpl.cpp:4064

PHI_iterator(LDVSSAPhi *P, bool)

Definition InstrRefBasedImpl.cpp:4054

LDVSSABlock * getIncomingBlock()

Definition InstrRefBasedImpl.cpp:4066

bool operator!=(const PHI_iterator &X) const

Definition InstrRefBasedImpl.cpp:4062

PHI_iterator(LDVSSAPhi *P)

Definition InstrRefBasedImpl.cpp:4052

PHI_iterator & operator++()

Definition InstrRefBasedImpl.cpp:4057

bool operator==(const PHI_iterator &X) const

Definition InstrRefBasedImpl.cpp:4061

LDVSSABlockIterator BlkSucc_iterator

Definition InstrRefBasedImpl.cpp:4039

static BlockValueNum CreateEmptyPHI(LDVSSABlock *BB, unsigned NumPreds, LDVSSAUpdater *Updater)

CreateEmptyPHI - Create a (representation of a) PHI in the given block.

Definition InstrRefBasedImpl.cpp:4100

static BlockValueNum GetPoisonVal(LDVSSABlock *BB, LDVSSAUpdater *Updater)

GetPoisonVal - Normally creates an IMPLICIT_DEF instruction with a new register.

Definition InstrRefBasedImpl.cpp:4086

static BlkSucc_iterator BlkSucc_end(BlkT *BB)

Definition InstrRefBasedImpl.cpp:4043

LDVSSABlock BlkT

Definition InstrRefBasedImpl.cpp:4036

static PHI_iterator PHI_begin(PhiT *PHI)

Definition InstrRefBasedImpl.cpp:4069

static void AddPHIOperand(LDVSSAPhi *PHI, BlockValueNum Val, LDVSSABlock *Pred)

AddPHIOperand - Add the specified value as an operand of the PHI for the specified predecessor block.

Definition InstrRefBasedImpl.cpp:4110

LDVSSAPhi PhiT

Definition InstrRefBasedImpl.cpp:4038

static void FindPredecessorBlocks(LDVSSABlock *BB, SmallVectorImpl< LDVSSABlock * > *Preds)

FindPredecessorBlocks - Put the predecessors of BB into the Preds vector.

Definition InstrRefBasedImpl.cpp:4077

static BlockValueNum GetPHIValue(LDVSSAPhi *PHI)

GetPHIValue - For the specified PHI instruction, return the value that it defines.

Definition InstrRefBasedImpl.cpp:4131

static LDVSSAPhi * ValueIsNewPHI(BlockValueNum Val, LDVSSAUpdater *Updater)

ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source operands, i....

Definition InstrRefBasedImpl.cpp:4122

BlockValueNum ValT

Definition InstrRefBasedImpl.cpp:4037

static PHI_iterator PHI_end(PhiT *PHI)

Definition InstrRefBasedImpl.cpp:4071

static LDVSSAPhi * ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater)

ValueIsPHI - Check if the instruction that defines the specified value is a PHI instruction.

Definition InstrRefBasedImpl.cpp:4116

static BlkSucc_iterator BlkSucc_begin(BlkT *BB)

Definition InstrRefBasedImpl.cpp:4042

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

void insert_range(Range &&R)

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

bool contains(ConstPtrType Ptr) const

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

void insert_range(Range &&R)

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void assign(size_type NumElts, ValueParamT Elt)

reference emplace_back(ArgTypes &&... Args)

void reserve(size_type N)

iterator erase(const_iterator CI)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

iterator insert(iterator I, T &&Elt)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StackOffset holds a fixed and a scalable offset in bytes.

virtual bool stackProbeFunctionModifiesSP() const

Does the stack probe function call return with a modified stack pointer?

virtual void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const

Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.

virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const

getFrameIndexReference - This method should return the base register and offset used to reference a f...

TargetInstrInfo - Interface to description of machine instruction set.

This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetFrameLowering * getFrameLowering() const

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

virtual const TargetLowering * getTargetLowering() const

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM_ABI std::string str() const

Return the twine contents as a std::string.

Twine concat(const Twine &Suffix) const

A Use represents the edge between a Value definition and its users.

LLVM Value Representation.

std::pair< iterator, bool > insert(const ValueT &V)

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

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

#define llvm_unreachable(msg)

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

SmallVector< ValueIDNum, 0 > ValueTable

Type for a table of values in a block.

unsigned ID

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

initializer< Ty > init(const Ty &Val)

Scope

Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...

NodeAddr< DefNode * > Def

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

std::tuple< const DIScope *, const DIScope *, const DILocalVariable * > VarID

A unique key that represents a debug variable.

auto find(R &&Range, const T &Val)

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

MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)

Returns an iterator to the first instruction in the bundle containing I.

bool all_of(R &&range, UnaryPredicate P)

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

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.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

APInt operator*(APInt a, uint64_t RHS)

bool operator!=(uint64_t V1, const APInt &V2)

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

LDVImpl * makeInstrRefBasedLiveDebugValues()

Definition InstrRefBasedImpl.cpp:3884

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

auto map_range(ContainerTy &&C, FuncTy F)

detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)

Returns a concatenated range across two or more ranges.

auto reverse(ContainerTy &&C)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool none_of(R &&Range, UnaryPredicate P)

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

iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)

Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)

RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)

auto lower_bound(R &&Range, T &&Value)

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

void replace(R &&Range, const T &OldValue, const T &NewValue)

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

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

DWARFExpression::Operation Op

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

OutputIt replace_copy(R &&Range, OutputIt Out, const T &OldValue, const T &NewValue)

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

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

bool equal(L &&LRange, R &&RRange)

Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

An ID used in the DbgOpIDMap (below) to lookup a stored DbgOp.

void dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const

Definition InstrRefBasedImpl.cpp:1005

static LLVM_ABI_FOR_TEST DbgOpID UndefID

TODO: Might pack better if we changed this to a Struct of Arrays, since MachineOperand is width 32,...

void dump(const MLocTracker *MTrack) const

Definition InstrRefBasedImpl.cpp:998

A collection of ValueTables, one per BB in a function, with convenient accessor methods.

void ejectTableForBlock(const MachineBasicBlock &MBB)

Frees the memory of the ValueTable associated with MBB.

ValueTable & tableForEntryMBB() const

Returns the ValueTable associated with the entry MachineBasicBlock.

bool hasTableFor(MachineBasicBlock &MBB) const

Returns true if the ValueTable associated with MBB has not been freed.

A DbgOp whose ID (if any) has resolved to an actual location, LocIdx.

void dump(const MLocTracker *MTrack) const

Definition InstrRefBasedImpl.cpp:991

Stores the resolved operands (machine locations and constants) and qualifying meta-information needed...

Definition InstrRefBasedImpl.cpp:202

SmallVector< ResolvedDbgOp > Ops

Definition InstrRefBasedImpl.cpp:203

DbgValueProperties Properties

Definition InstrRefBasedImpl.cpp:204

ResolvedDbgValue(SmallVectorImpl< ResolvedDbgOp > &Ops, DbgValueProperties Properties)

Definition InstrRefBasedImpl.cpp:206

auto loc_indices() const

Returns all the LocIdx values used in this struct, in the order in which they appear as operands in t...

Definition InstrRefBasedImpl.cpp:212

Record of all changes in variable locations at a block position.

Definition InstrRefBasedImpl.cpp:191

SmallVector< std::pair< DebugVariableID, MachineInstr * >, 4 > Insts

non-null if we should insert after.

Definition InstrRefBasedImpl.cpp:196

MachineBasicBlock * MBB

Position to insert DBG_VALUes.

Definition InstrRefBasedImpl.cpp:193

MachineBasicBlock::instr_iterator Pos

Definition InstrRefBasedImpl.cpp:192

UseBeforeDef(ArrayRef< DbgOp > Values, DebugVariableID VarID, const DbgValueProperties &Properties)

Definition InstrRefBasedImpl.cpp:252

DbgValueProperties Properties

Additional variable properties.

Definition InstrRefBasedImpl.cpp:251

DebugVariableID VarID

Identity of this variable.

Definition InstrRefBasedImpl.cpp:249

SmallVector< DbgOp > Values

Value of this variable, def'd in block.

Definition InstrRefBasedImpl.cpp:247