LLVM: lib/CodeGen/LiveDebugVariables.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

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

59#include

60#include

61#include

62#include

63#include

64#include

65#include

66

67using namespace llvm;

68

69#define DEBUG_TYPE "livedebugvars"

70

74

75STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted");

76STATISTIC(NumInsertedDebugLabels, "Number of DBG_LABELs inserted");

77

79

81 "Debug Variable Analysis", false, false)

86

91 AU.setPreservesAll();

93}

94

99}

100

102

103namespace {

104

105

106class DbgVariableValue {

107public:

108 DbgVariableValue(ArrayRef NewLocs, bool WasIndirect, bool WasList,

110 : WasIndirect(WasIndirect), WasList(WasList), Expression(&Expr) {

111 assert(!(WasIndirect && WasList) &&

112 "DBG_VALUE_LISTs should not be indirect.");

114 for (unsigned LocNo : NewLocs) {

115 auto It = find(LocNoVec, LocNo);

116 if (It == LocNoVec.end())

118 else {

119

120

121 unsigned OpIdx = LocNoVec.size();

122 unsigned DuplicatingIdx = std::distance(LocNoVec.begin(), It);

125 }

126 }

127

128

129

130

131

132

133 if (LocNoVec.size() < 64) {

134 LocNoCount = LocNoVec.size();

135 if (LocNoCount > 0) {

136 LocNos = std::make_unique<unsigned[]>(LocNoCount);

137 std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin());

138 }

139 } else {

140 LLVM_DEBUG(dbgs() << "Found debug value with 64+ unique machine "

141 "locations, dropping...\n");

142 LocNoCount = 1;

143

144

146 DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0});

149 Expression, FragmentInfoOpt->OffsetInBits,

150 FragmentInfoOpt->SizeInBits);

151 LocNos = std::make_unique<unsigned[]>(LocNoCount);

153 }

154 }

155

156 DbgVariableValue() : LocNoCount(0), WasIndirect(false), WasList(false) {}

157 DbgVariableValue(const DbgVariableValue &Other)

158 : LocNoCount(Other.LocNoCount), WasIndirect(Other.getWasIndirect()),

160 if (Other.getLocNoCount()) {

161 LocNos.reset(new unsigned[Other.getLocNoCount()]);

162 std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());

163 }

164 }

165

166 DbgVariableValue &operator=(const DbgVariableValue &Other) {

167 if (this == &Other)

168 return *this;

169 if (Other.getLocNoCount()) {

170 LocNos.reset(new unsigned[Other.getLocNoCount()]);

171 std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());

172 } else {

173 LocNos.release();

174 }

175 LocNoCount = Other.getLocNoCount();

176 WasIndirect = Other.getWasIndirect();

177 WasList = Other.getWasList();

179 return *this;

180 }

181

183 uint8_t getLocNoCount() const { return LocNoCount; }

184 bool containsLocNo(unsigned LocNo) const {

186 }

187 bool getWasIndirect() const { return WasIndirect; }

188 bool getWasList() const { return WasList; }

189 bool isUndef() const { return LocNoCount == 0 || containsLocNo(UndefLocNo); }

190

191 DbgVariableValue decrementLocNosAfterPivot(unsigned Pivot) const {

193 for (unsigned LocNo : loc_nos())

195 : LocNo);

196 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);

197 }

198

201 for (unsigned LocNo : loc_nos())

202

203

205 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);

206 }

207

208 DbgVariableValue changeLocNo(unsigned OldLocNo, unsigned NewLocNo) const {

210 NewLocNos.assign(loc_nos_begin(), loc_nos_end());

211 auto OldLocIt = find(NewLocNos, OldLocNo);

212 assert(OldLocIt != NewLocNos.end() && "Old location must be present.");

213 *OldLocIt = NewLocNo;

214 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);

215 }

216

217 bool hasLocNoGreaterThan(unsigned LocNo) const {

218 return any_of(loc_nos(),

219 [LocNo](unsigned ThisLocNo) { return ThisLocNo > LocNo; });

220 }

221

223 for (const unsigned &Loc : loc_nos())

224 OS << (&Loc == loc_nos_begin() ? " " : ", ") << Loc;

225 }

226

227 friend inline bool operator==(const DbgVariableValue &LHS,

228 const DbgVariableValue &RHS) {

229 if (std::tie(LHS.LocNoCount, LHS.WasIndirect, LHS.WasList,

230 LHS.Expression) !=

231 std::tie(RHS.LocNoCount, RHS.WasIndirect, RHS.WasList, RHS.Expression))

232 return false;

233 return std::equal(LHS.loc_nos_begin(), LHS.loc_nos_end(),

234 RHS.loc_nos_begin());

235 }

236

237 friend inline bool operator!=(const DbgVariableValue &LHS,

238 const DbgVariableValue &RHS) {

239 return !(LHS == RHS);

240 }

241

242 unsigned *loc_nos_begin() { return LocNos.get(); }

243 const unsigned *loc_nos_begin() const { return LocNos.get(); }

244 unsigned *loc_nos_end() { return LocNos.get() + LocNoCount; }

245 const unsigned *loc_nos_end() const { return LocNos.get() + LocNoCount; }

248 }

249

250private:

251

252

253

254

255

256 std::unique_ptr<unsigned[]> LocNos;

258 bool WasIndirect : 1;

259 bool WasList : 1;

261};

262}

263

264

266

267

268

270

271

272

273

274

275

278

279namespace {

280

281

282

283

284

285

286

287

288

289class UserValue {

291

292 const DILocalVariable *Variable;

293

294 const std::optionalDIExpression::FragmentInfo Fragment;

295 DebugLoc dl;

296

297 UserValue *leader;

298 UserValue *next = nullptr;

299

300

302

303

305

306

307

309

310

318

319

320

323

324public:

325

327 std::optionalDIExpression::FragmentInfo Fragment, DebugLoc L,

329 : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(this),

330 locInts(alloc) {}

331

332

333 UserValue *getLeader() {

334 UserValue *l = leader;

335 while (l != l->leader)

336 l = l->leader;

337 return leader = l;

338 }

339

340

341 UserValue *getNext() const { return next; }

342

343

344 static UserValue *merge(UserValue *L1, UserValue *L2) {

345 L2 = L2->getLeader();

346 if (!L1)

347 return L2;

348 L1 = L1->getLeader();

349 if (L1 == L2)

350 return L1;

351

352 UserValue *End = L2;

353 while (End->next) {

354 End->leader = L1;

356 }

357 End->leader = L1;

358 End->next = L1->next;

359 L1->next = L2;

360 return L1;

361 }

362

363

364

365

366

367

368

369 unsigned getLocationNo(const MachineOperand &LocMO) {

370 if (LocMO.isReg()) {

371 if (LocMO.getReg() == 0)

373

374 for (unsigned i = 0, e = locations.size(); i != e; ++i)

375 if (locations[i].isReg() &&

377 locations[i].getSubReg() == LocMO.getSubReg())

378 return i;

379 } else

380 for (unsigned i = 0, e = locations.size(); i != e; ++i)

382 return i;

384

385 locations.back().clearParent();

386

387 if (locations.back().isReg()) {

388 if (locations.back().isDef())

389 locations.back().setIsDead(false);

390 locations.back().setIsUse();

391 }

392 return locations.size() - 1;

393 }

394

395

396

397 void removeLocationIfUnused(unsigned LocNo) {

398

400 const DbgVariableValue &DbgValue = I.value();

401 if (DbgValue.containsLocNo(LocNo))

402 return;

403 }

404

405

406 locations.erase(locations.begin() + LocNo);

408 const DbgVariableValue &DbgValue = I.value();

409 if (DbgValue.hasLocNoGreaterThan(LocNo))

410 I.setValueUnchecked(DbgValue.decrementLocNosAfterPivot(LocNo));

411 }

412 }

413

414

415 void mapVirtRegs(LDVImpl *LDV);

416

417

423 DbgVariableValue DbgValue(Locs, IsIndirect, IsList, Expr);

424

426 if (I.valid() || I.start() != Idx)

428 else

429

431 }

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448 void

450 SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>

451 &LiveIntervalInfo,

454

455

456

457

458

459

460

461

462

463

464 void addDefsFromCopies(

466 SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,

468 SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,

470

471

472

475

476

477

480

481

482

483

488

489

495

496

498

500};

501

502

503class UserLabel {

504 const DILabel *Label;

505 DebugLoc dl;

506

507 SlotIndex loc;

508

509

513

514public:

515

517 : Label(label), dl(std::move(L)), loc(Idx) {}

518

519

522 return Label == L && dl->getInlinedAt() == IA && loc == Index;

523 }

524

525

528

529

531

533};

534

535}

536

537namespace llvm {

538

539

540

544

550

551

552 struct PHIValPos {

553 SlotIndex SI;

554 Register Reg;

555 unsigned SubReg;

556 };

557

558

559 std::map<unsigned, PHIValPos> PHIValToPos;

560

561

562

564

565

566

567

568 struct InstrPos {

569 MachineInstr *MI;

570 SlotIndex Idx;

572 };

573

574

576

577

578 bool EmitDone = false;

579

580

581 bool ModifiedMF = false;

582

583

585

586

588

589

591 VRMap virtRegToEqClass;

592

593

595 UVMap userVarMap;

596

597

599 std::optionalDIExpression::FragmentInfo Fragment,

601

602

603 UserValue *lookupVirtReg(Register VirtReg);

604

605

606

607

608

609

610

612

613

614

615

616

617

618

619

620

621

622

623

625

626

627

628

629

630

631

633

634

635

636

637

638

639

640

641

642 bool collectDebugValues(MachineFunction &mf, bool InstrRef);

643

644

645

646 void computeIntervals();

647

648public:

650

652

653

655 MF = nullptr;

656 PHIValToPos.clear();

657 RegToPHIIdx.clear();

658 StashedDebugInstrs.clear();

659 userValues.clear();

660 userLabels.clear();

661 virtRegToEqClass.clear();

662 userVarMap.clear();

663

664 assert((!ModifiedMF || EmitDone) &&

665 "Dbg values are not emitted in LDV");

666 EmitDone = false;

667 ModifiedMF = false;

668 }

669

670

672

673

674

676

677

679

680

682

684};

685

686}

687

690 if (DL)

691 return;

692

693 auto *Scope = cast(DL.getScope());

694

695 CommentOS << Scope->getFilename();

696 CommentOS << ':' << DL.getLine();

697 if (DL.getCol() != 0)

698 CommentOS << ':' << DL.getCol();

699

700 DebugLoc InlinedAtDL = DL.getInlinedAt();

701 if (!InlinedAtDL)

702 return;

703

704 CommentOS << " @[ ";

706 CommentOS << " ]";

707}

708

713 unsigned Line = 0;

714 if (const auto *V = dyn_cast(Node)) {

715 Res = V->getName();

716 Line = V->getLine();

717 } else if (const auto *L = dyn_cast(Node)) {

718 Res = L->getName();

719 Line = L->getLine();

720 }

721

722 if (!Res.empty())

723 OS << Res << "," << Line;

724 auto *InlinedAt = DL ? DL->getInlinedAt() : nullptr;

725 if (InlinedAt) {

726 if (DebugLoc InlinedAtDL = InlinedAt) {

727 OS << " @[";

729 OS << "]";

730 }

731 }

732}

733

735 OS << "!\"";

737

738 OS << "\"\t";

740 OS << " [" << I.start() << ';' << I.stop() << "):";

741 if (I.value().isUndef())

742 OS << " undef";

743 else {

744 I.value().printLocNos(OS);

745 if (I.value().getWasIndirect())

746 OS << " ind";

747 else if (I.value().getWasList())

748 OS << " list";

749 }

750 }

751 for (unsigned i = 0, e = locations.size(); i != e; ++i) {

752 OS << " Loc" << i << '=';

753 locations[i].print(OS, TRI);

754 }

755 OS << '\n';

756}

757

759 OS << "!\"";

761

762 OS << "\"\t";

763 OS << loc;

764 OS << '\n';

765}

766

768 OS << "********** DEBUG VARIABLES **********\n";

769 for (auto &userValue : userValues)

770 userValue->print(OS, TRI);

771 OS << "********** DEBUG LABELS **********\n";

772 for (auto &userLabel : userLabels)

773 userLabel->print(OS, TRI);

774}

775

778 if (MO.isReg() && MO.getReg().isVirtual())

780}

781

782UserValue *LiveDebugVariables::LDVImpl::getUserValue(

784 std::optionalDIExpression::FragmentInfo Fragment, const DebugLoc &DL) {

785

786

788 UserValue *&UV = userVarMap[ID];

789 if (!UV) {

790 userValues.push_back(

791 std::make_unique(Var, Fragment, DL, allocator));

792 UV = userValues.back().get();

793 }

794 return UV;

795}

796

799 UserValue *&Leader = virtRegToEqClass[VirtReg];

800 Leader = UserValue::merge(Leader, EC);

801}

802

803UserValue *LiveDebugVariables::LDVImpl::lookupVirtReg(Register VirtReg) {

804 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))

805 return UV->getLeader();

806 return nullptr;

807}

808

809bool LiveDebugVariables::LDVImpl::handleDebugValue(MachineInstr &MI,

811

812

813 if (MI.isDebugValue()) {

815 return false;

816 }

817 if (MI.getDebugVariableOp().isMetadata()) {

818 LLVM_DEBUG(dbgs() << "Can't handle DBG_VALUE* with invalid variable: "

819 << MI);

820 return false;

821 }

822 if (MI.isNonListDebugValue() &&

823 (MI.getNumOperands() != 4 ||

824 !(MI.getDebugOffset().isImm() || MI.getDebugOffset().isReg()))) {

825 LLVM_DEBUG(dbgs() << "Can't handle malformed DBG_VALUE: " << MI);

826 return false;

827 }

828

829

830

831

832

833 bool Discard = false;

835 if (Op.isReg() && Op.getReg().isVirtual()) {

837 if (!LIS->hasInterval(Reg)) {

838

839

840 Discard = true;

841 LLVM_DEBUG(dbgs() << "Discarding debug info (no LIS interval): " << Idx

842 << " " << MI);

843 } else {

844

845

846

847 const LiveInterval &LI = LIS->getInterval(Reg);

850

851

852 Discard = true;

853 LLVM_DEBUG(dbgs() << "Discarding debug info (reg not live): " << Idx

854 << " " << MI);

855 }

856 }

857 }

858 }

859

860

861 bool IsIndirect = MI.isDebugOffsetImm();

862 if (IsIndirect)

863 assert(MI.getDebugOffset().getImm() == 0 &&

864 "DBG_VALUE with nonzero offset");

865 bool IsList = MI.isDebugValueList();

868 UserValue *UV = getUserValue(Var, Expr->getFragmentInfo(), MI.getDebugLoc());

869 if (!Discard)

870 UV->addDef(Idx,

872 MI.debug_operands().end()),

873 IsIndirect, IsList, *Expr);

874 else {

877

878

879

881 UV->addDef(Idx, UndefMOs, false, IsList, *Expr);

882 }

883 return true;

884}

885

888 assert(MI.isDebugValueLike() || MI.isDebugPHI());

889

890

891

892 if (MI.isDebugValueLike())

895 return MO.isReg() && MO.getReg().isVirtual();

896 }) &&

897 "MIs should not refer to Virtual Registers in InstrRef mode.");

898

899

900 auto NextInst = std::next(MI.getIterator());

901 auto *MBB = MI.getParent();

902 MI.removeFromParent();

903 StashedDebugInstrs.push_back({&MI, Idx, MBB});

904 return NextInst;

905}

906

907bool LiveDebugVariables::LDVImpl::handleDebugLabel(MachineInstr &MI,

909

910 if (MI.getNumOperands() != 1 || MI.getOperand(0).isMetadata()) {

912 return false;

913 }

914

915

918 bool Found = false;

919 for (auto const &L : userLabels) {

920 if (L->matches(Label, DL->getInlinedAt(), Idx)) {

921 Found = true;

922 break;

923 }

924 }

925 if (!Found)

926 userLabels.push_back(std::make_unique(Label, DL, Idx));

927

928 return true;

929}

930

931bool LiveDebugVariables::LDVImpl::collectDebugValues(MachineFunction &mf,

932 bool InstrRef) {

933 bool Changed = false;

936 MBBI != MBBE;) {

937

938

939 if (MBBI->isDebugOrPseudoInstr()) {

941 continue;

942 }

943

944

947 ? LIS->getMBBStartIdx(&MBB)

948 : LIS->getInstructionIndex(*std::prev(MBBI)).getRegSlot();

949

950 do {

951

952

953

954 if (InstrRef && (MBBI->isNonListDebugValue() || MBBI->isDebugPHI() ||

955 MBBI->isDebugRef())) {

957 Changed = true;

958

959

960 } else if ((MBBI->isDebugValue() && handleDebugValue(*MBBI, Idx)) ||

961 (MBBI->isDebugLabel() && handleDebugLabel(*MBBI, Idx))) {

963 Changed = true;

964 } else

966 } while (MBBI != MBBE && MBBI->isDebugOrPseudoInstr());

967 }

968 }

969 return Changed;

970}

971

972void UserValue::extendDef(

974 SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>

975 &LiveIntervalInfo,

982

983

984 for (auto &LII : LiveIntervalInfo) {

985 LiveRange *LR = LII.second.first;

986 assert(LR && LII.second.second && "Missing range info for Idx.");

988 assert(Segment && Segment->valno == LII.second.second &&

989 "Invalid VNInfo for Idx given?");

990 if (Segment->end < Stop) {

991 Stop = Segment->end;

992 Kills = {Stop, {LII.first}};

993 } else if (Segment->end == Stop && Kills) {

994

995

996 Kills->second.push_back(LII.first);

997 }

998 }

999

1000

1001 if (I.valid() && I.start() <= Start) {

1002

1003 Start = Start.getNextSlot();

1004 if (I.value() != DbgValue || I.stop() != Start) {

1005

1006 Kills = std::nullopt;

1007 return;

1008 }

1009

1010 ++I;

1011 }

1012

1013

1014 if (I.valid() && I.start() < Stop) {

1015 Stop = I.start();

1016

1017 Kills = std::nullopt;

1018 }

1019

1020 if (Start < Stop) {

1021 DbgVariableValue ExtDbgValue(DbgValue);

1022 I.insert(Start, Stop, std::move(ExtDbgValue));

1023 }

1024}

1025

1026void UserValue::addDefsFromCopies(

1028 SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,

1030 SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,

1032

1033 if (any_of(LocIntervals,

1034 [](auto LocI) { return !LocI.second->reg().isVirtual(); }))

1035 return;

1036

1037

1040 CopyValues;

1041 for (auto &LocInterval : LocIntervals) {

1042 unsigned LocNo = LocInterval.first;

1046

1048 continue;

1049 Register DstReg = MI->getOperand(0).getReg();

1050

1051

1052

1053

1054

1056 continue;

1057

1058

1059

1062 if (I.valid() || I.value() != DbgValue)

1063 continue;

1064

1066 continue;

1069 assert(DstVNI && DstVNI->def == Idx.getRegSlot() && "Bad copy value");

1070 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));

1071 }

1072 }

1073

1074 if (CopyValues.empty())

1075 return;

1076

1077#if !defined(NDEBUG)

1078 for (auto &LocInterval : LocIntervals)

1079 LLVM_DEBUG(dbgs() << "Got " << CopyValues[LocInterval.first].size()

1080 << " copies of " << *LocInterval.second << '\n');

1081#endif

1082

1083

1084

1086 if (I.valid() && I.start() <= KilledAt)

1087 return;

1088 DbgVariableValue NewValue(DbgValue);

1089 for (auto &LocInterval : LocIntervals) {

1090 unsigned LocNo = LocInterval.first;

1091 bool FoundCopy = false;

1092 for (auto &LIAndVNI : CopyValues[LocNo]) {

1094 const VNInfo *DstVNI = LIAndVNI.second;

1095 if (DstLI->getVNInfoAt(KilledAt) != DstVNI)

1096 continue;

1097 LLVM_DEBUG(dbgs() << "Kill at " << KilledAt << " covered by valno #"

1098 << DstVNI->id << " in " << *DstLI << '\n');

1100 assert(CopyMI && CopyMI->isCopy() && "Bad copy value");

1101 unsigned NewLocNo = getLocationNo(CopyMI->getOperand(0));

1102 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);

1103 FoundCopy = true;

1104 break;

1105 }

1106

1107

1108 if (!FoundCopy)

1109 return;

1110 }

1111 I.insert(KilledAt, KilledAt.getNextSlot(), NewValue);

1112 NewDefs.push_back(std::make_pair(KilledAt, NewValue));

1113}

1114

1119

1120

1122 if (I.value().isUndef())

1123 Defs.push_back(std::make_pair(I.start(), I.value()));

1124

1125

1126 for (unsigned i = 0; i != Defs.size(); ++i) {

1128 DbgVariableValue DbgValue = Defs[i].second;

1131 bool ShouldExtendDef = false;

1132 for (unsigned LocNo : DbgValue.loc_nos()) {

1135 ShouldExtendDef |= !LocMO.isReg();

1136 continue;

1137 }

1138 ShouldExtendDef = true;

1140 const VNInfo *VNI = nullptr;

1144 }

1145 if (LI && VNI)

1146 LIs[LocNo] = {LI, VNI};

1147 }

1148 if (ShouldExtendDef) {

1149 std::optional<std::pair<SlotIndex, SmallVector>> Kills;

1150 extendDef(Idx, DbgValue, LIs, Kills, LIS);

1151

1152 if (Kills) {

1154 bool AnySubreg = false;

1155 for (unsigned LocNo : Kills->second) {

1156 const MachineOperand &LocMO = this->locations[LocNo];

1158 AnySubreg = true;

1159 break;

1160 }

1162 KilledLocIntervals.push_back({LocNo, LI});

1163 }

1164

1165

1166

1167

1168

1169

1170

1171

1172

1173 if (!AnySubreg)

1174 addDefsFromCopies(DbgValue, KilledLocIntervals, Kills->first, Defs,

1175 MRI, LIS);

1176 }

1177 }

1178

1179

1180

1181

1182

1183

1184

1185 }

1186

1187

1188

1189

1190

1191

1192

1193

1194 if (!dl.getInlinedAt())

1195 return;

1196

1198 if (!Scope)

1199 return;

1200

1203

1204

1205

1206

1207

1211

1212

1213

1214 if (Range.first == Range.first->getParent()->begin())

1216

1217

1218

1219 if (PrevEnd && I.start() < PrevEnd) {

1221 DbgVariableValue DbgValue = I.value();

1222

1223

1224

1225 I.setStopUnchecked(PrevEnd);

1226 ++I;

1227

1228

1229

1230

1231 if (RStart < IStop)

1232 I.insert(RStart, IStop, DbgValue);

1233 }

1234

1235

1236 I.advanceTo(RStart);

1237 if (I.valid())

1238 return;

1239

1240 if (I.start() < RStart) {

1241

1242 I.setStartUnchecked(RStart);

1243

1244 trimmedDefs.insert(RStart);

1245 }

1246

1247

1248

1249

1251

1252

1253 I.advanceTo(REnd);

1254 if (I.valid())

1255 return;

1256

1257 PrevEnd = REnd;

1258 }

1259

1260

1261 if (PrevEnd && I.start() < PrevEnd)

1262 I.setStopUnchecked(PrevEnd);

1263}

1264

1265void LiveDebugVariables::LDVImpl::computeIntervals() {

1267 LS.initialize(*MF);

1268

1269 for (const auto &UV : userValues) {

1270 UV->computeIntervals(MF->getRegInfo(), *TRI, *LIS, LS);

1271 UV->mapVirtRegs(this);

1272 }

1273}

1274

1276 bool InstrRef) {

1277 clear();

1278 MF = &mf;

1280 LLVM_DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: "

1281 << mf.getName() << " **********\n");

1282

1283 bool Changed = collectDebugValues(mf, InstrRef);

1284 computeIntervals();

1286

1287

1288

1290 for (const auto &PHIIt : MF->DebugPHIPositions) {

1293 Register Reg = Position.Reg;

1294 unsigned SubReg = Position.SubReg;

1296 PHIValPos VP = {SI, Reg, SubReg};

1297 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));

1298 RegToPHIIdx[Reg].push_back(PHIIt.first);

1299 }

1300

1301 ModifiedMF = Changed;

1302 return Changed;

1303}

1304

1308 if (MI.isDebugInstr())

1310 }

1311}

1312

1315 auto *LIS = &getAnalysis().getLIS();

1316

1317 Impl = std::make_unique();

1318 Impl->analyze(mf, LIS);

1319 return false;

1320}

1321

1322AnalysisKey LiveDebugVariablesAnalysis::Key;

1323

1328

1331 LDV.analyze(MF, LIS);

1332 return LDV;

1333}

1334

1341}

1342

1344 if (PImpl)

1345 PImpl->clear();

1346}

1347

1352

1353

1354

1355 return !PAC.preservedWhenStateless();

1356}

1357

1360 return;

1363 return;

1364 }

1365

1366 PImpl.reset(new LDVImpl(LIS));

1367

1368

1369

1371 PImpl->runOnMachineFunction(MF, InstrRef);

1372}

1373

1374

1375

1376

1377

1378bool

1379UserValue::splitLocation(unsigned OldLocNo, ArrayRef NewRegs,

1382 dbgs() << "Splitting Loc" << OldLocNo << '\t';

1384 });

1385 bool DidChange = false;

1387 LocMapI.setMap(locInts);

1388 for (Register NewReg : NewRegs) {

1390 if (LI->empty())

1391 continue;

1392

1393

1395

1396

1398 if (!LocMapI.valid())

1399 continue;

1402 while (LocMapI.valid() && LII != LIE) {

1403

1405 if (LII == LIE)

1406 break;

1407

1408

1409 if (LocMapI.value().containsLocNo(OldLocNo) &&

1410 LII->start < LocMapI.stop()) {

1411

1414 MO.setSubReg(locations[OldLocNo].getSubReg());

1415 NewLocNo = getLocationNo(MO);

1416 DidChange = true;

1417 }

1418

1421 DbgVariableValue OldDbgValue = LocMapI.value();

1422

1423

1424 if (LStart < LII->start)

1426 if (LStop > LII->end)

1428

1429

1430 LocMapI.setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));

1431

1432

1433 if (LStart < LocMapI.start()) {

1434 LocMapI.insert(LStart, LocMapI.start(), OldDbgValue);

1435 ++LocMapI;

1436 assert(LocMapI.valid() && "Unexpected coalescing");

1437 }

1438 if (LStop > LocMapI.stop()) {

1439 ++LocMapI;

1440 LocMapI.insert(LII->end, LStop, OldDbgValue);

1441 --LocMapI;

1442 }

1443 }

1444

1445

1446 if (LII->end < LocMapI.stop()) {

1447 if (++LII == LIE)

1448 break;

1450 } else {

1451 ++LocMapI;

1452 if (!LocMapI.valid())

1453 break;

1455 }

1456 }

1457 }

1458

1459

1460

1461

1462

1463

1464

1465

1466

1467

1468

1469 removeLocationIfUnused(OldLocNo);

1470

1472 dbgs() << "Split result: \t";

1474 });

1475 return DidChange;

1476}

1477

1478bool

1481 bool DidChange = false;

1482

1483

1484 for (unsigned i = locations.size(); i ; --i) {

1485 unsigned LocNo = i-1;

1487 if (!Loc->isReg() || Loc->getReg() != OldReg)

1488 continue;

1489 DidChange |= splitLocation(LocNo, NewRegs, LIS);

1490 }

1491 return DidChange;

1492}

1493

1496 auto RegIt = RegToPHIIdx.find(OldReg);

1497 if (RegIt == RegToPHIIdx.end())

1498 return;

1499

1500 std::vector<std::pair<Register, unsigned>> NewRegIdxes;

1501

1502 for (unsigned InstrID : RegIt->second) {

1503 auto PHIIt = PHIValToPos.find(InstrID);

1504 assert(PHIIt != PHIValToPos.end());

1505 const SlotIndex &Slot = PHIIt->second.SI;

1506 assert(OldReg == PHIIt->second.Reg);

1507

1508

1509 for (auto NewReg : NewRegs) {

1511 auto LII = LI.find(Slot);

1512 if (LII != LI.end() && LII->start <= Slot) {

1513

1514 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));

1515

1516 PHIIt->second.Reg = NewReg;

1517 break;

1518 }

1519 }

1520

1521

1522

1523

1524

1525 }

1526

1527

1528 RegToPHIIdx.erase(RegIt);

1529 for (auto &RegAndInstr : NewRegIdxes)

1530 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);

1531}

1532

1535

1536 splitPHIRegister(OldReg, NewRegs);

1537

1538

1539

1540 bool DidChange = false;

1541 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())

1542 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);

1543

1544 if (!DidChange)

1545 return;

1546

1547

1548 UserValue *UV = lookupVirtReg(OldReg);

1549 for (Register NewReg : NewRegs)

1550 mapVirtReg(NewReg, UV);

1551}

1552

1555 if (PImpl)

1556 PImpl->splitRegister(OldReg, NewRegs);

1557}

1558

1563

1564

1565

1566

1567

1568

1569

1570

1573 for (unsigned I = 0, E = locations.size(); I != E; ++I) {

1574 bool Spilled = false;

1575 unsigned SpillOffset = 0;

1577

1581

1582

1583

1586

1587 unsigned SpillSize;

1591 SpillOffset, MF);

1592

1593

1595

1597 Spilled = true;

1598 } else {

1601 }

1602 }

1603

1604

1605

1606 auto InsertResult = NewLocations.insert({Loc, {Spilled, SpillOffset}});

1607 unsigned NewLocNo = std::distance(NewLocations.begin(), InsertResult.first);

1608 LocNoMap[I] = NewLocNo;

1609 }

1610

1611

1612 locations.clear();

1613 SpillOffsets.clear();

1614 for (auto &Pair : NewLocations) {

1615 bool Spilled;

1616 unsigned SpillOffset;

1617 std::tie(Spilled, SpillOffset) = Pair.second;

1618 locations.push_back(Pair.first);

1619 if (Spilled) {

1620 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);

1621 SpillOffsets[NewLocNo] = SpillOffset;

1622 }

1623 }

1624

1625

1626

1627

1628

1630 I.setValueUnchecked(I.value().remapLocNos(LocNoMap));

1631 I.setStart(I.start());

1632 }

1633}

1634

1635

1640 Idx = Idx.getBaseIndex();

1641

1642

1645

1646 if (Idx == Start) {

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656

1657

1658

1659

1660

1662 auto MapIt = BBSkipInstsMap.find(MBB);

1663 if (MapIt == BBSkipInstsMap.end())

1665 else

1666 BeginIt = std::next(MapIt->second);

1668 if (I != BeginIt)

1669 BBSkipInstsMap[MBB] = std::prev(I);

1670 return I;

1671 }

1672 Idx = Idx.getPrevIndex();

1673 }

1674

1675

1679}

1680

1681

1682

1689 if (LocMO.isReg())

1691 if (Regs.empty())

1693

1694

1695 while (I != MBB->end() && I->isTerminator()) {

1698 break;

1700 return I->definesRegister(Reg, &TRI);

1701 }))

1702

1703 return std::next(I);

1704 ++I;

1705 }

1707}

1708

1717

1718 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;

1721

1722

1727 0, false, false,

1728 false, false,

1729 false, false,

1730 0, true));

1731 } else {

1732 for (unsigned LocNo : DbgValue.loc_nos())

1733 MOs.push_back(locations[LocNo]);

1734 }

1735

1736 ++NumInsertedDebugValues;

1737

1738 assert(cast(Variable)

1739 ->isValidLocationForIntrinsic(getDebugLoc()) &&

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

1741

1742

1743

1744

1745

1747 bool IsIndirect = DbgValue.getWasIndirect();

1748 bool IsList = DbgValue.getWasList();

1749 for (unsigned I = 0, E = LocSpills.size(); I != E; ++I) {

1750 if (LocSpills[I]) {

1751 if (!IsList) {

1753 if (IsIndirect)

1756 IsIndirect = true;

1757 } else {

1760 Ops.push_back(dwarf::DW_OP_deref);

1762 }

1763 }

1764

1765 assert((!LocSpills[I] || MOs[I].isFI()) &&

1766 "a spilled location must be a frame index");

1767 }

1768

1769 unsigned DbgValueOpcode =

1770 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;

1771 do {

1773 Variable, Expr);

1774

1775

1776

1778 } while (I != MBB->end());

1779}

1780

1786 ++NumInsertedDebugLabels;

1789}

1790

1797

1801 DbgVariableValue DbgValue = I.value();

1802

1805 for (unsigned LocNo : DbgValue.loc_nos()) {

1806 auto SpillIt =

1807 DbgValue.isUndef() ? SpillOffsets.find(LocNo) : SpillOffsets.end();

1808 bool Spilled = SpillIt != SpillOffsets.end();

1810 LocSpillOffsets.push_back(Spilled ? SpillIt->second : 0);

1811 }

1812

1813

1814

1815

1816 if (trimmedDefs.count(Start))

1817 Start = Start.getPrevIndex();

1818

1819 LLVM_DEBUG(auto &dbg = dbgs(); dbg << "\t[" << Start << ';' << Stop << "):";

1823

1825 insertDebugValue(&*MBB, Start, Stop, DbgValue, SpilledLocs, LocSpillOffsets,

1826 LIS, TII, TRI, BBSkipInstsMap);

1827

1828

1829 while (Stop > MBBEnd) {

1830

1831 Start = MBBEnd;

1832 if (++MBB == MFEnd)

1833 break;

1836 insertDebugValue(&*MBB, Start, Stop, DbgValue, SpilledLocs,

1837 LocSpillOffsets, LIS, TII, TRI, BBSkipInstsMap);

1838 }

1840 if (MBB == MFEnd)

1841 break;

1842

1843 ++I;

1844 }

1845}

1846

1851

1853 insertDebugLabel(&*MBB, loc, LIS, TII, BBSkipInstsMap);

1854

1856}

1857

1859 LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n");

1860 if (!MF)

1861 return;

1862

1866 for (auto &userValue : userValues) {

1868 userValue->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets);

1869 userValue->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets,

1870 BBSkipInstsMap);

1871 }

1872 LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG LABELS **********\n");

1873 for (auto &userLabel : userLabels) {

1875 userLabel->emitDebugLabel(*LIS, *TII, BBSkipInstsMap);

1876 }

1877

1878 LLVM_DEBUG(dbgs() << "********** EMITTING DEBUG PHIS **********\n");

1879

1881 for (auto &It : PHIValToPos) {

1882

1883

1884 unsigned InstNum = It.first;

1885 auto Slot = It.second.SI;

1886 Register Reg = It.second.Reg;

1887 unsigned SubReg = It.second.SubReg;

1888

1891 unsigned PhysReg = VRM->getPhys(Reg);

1893 PhysReg = TRI->getSubReg(PhysReg, SubReg);

1894

1896 TII->get(TargetOpcode::DBG_PHI));

1897 Builder.addReg(PhysReg);

1898 Builder.addImm(InstNum);

1902 unsigned SpillSize, SpillOffset;

1903

1904 unsigned regSizeInBits = TRI->getRegSizeInBits(*TRC);

1906 regSizeInBits = TRI->getSubRegIdxSize(SubReg);

1907

1908

1909

1910

1912 TII->getStackSlotRange(TRC, SubReg, SpillSize, SpillOffset, *MF);

1913

1914 if (Success && SpillOffset == 0) {

1916 TII->get(TargetOpcode::DBG_PHI));

1917 Builder.addFrameIndex(VRM->getStackSlot(Reg));

1918 Builder.addImm(InstNum);

1919

1920

1921

1922 Builder.addImm(regSizeInBits);

1923 }

1924

1927 << " has nonzero offset\n";

1928 });

1929 }

1930

1931

1932 }

1934

1935 LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");

1936

1937

1938

1939

1940

1941

1942

1943 for (auto *StashIt = StashedDebugInstrs.begin();

1944 StashIt != StashedDebugInstrs.end(); ++StashIt) {

1948

1949 auto EmitInstsHere = [this, &StashIt, MBB, Idx,

1951

1953

1954

1955

1956 auto NextItem = std::next(StashIt);

1957 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx == Idx) {

1958 assert(NextItem->MBB == MBB && "Instrs with same slot index should be"

1959 "in the same block");

1960 MBB->insert(InsertPos, NextItem->MI);

1961 StashIt = NextItem;

1962 NextItem = std::next(StashIt);

1963 };

1964 };

1965

1966

1967

1968 if (Idx == Slots->getMBBStartIdx(MBB)) {

1971 EmitInstsHere(InsertPos);

1972 continue;

1973 }

1974

1975 if (MachineInstr *Pos = Slots->getInstructionFromIndex(Idx)) {

1976

1977 auto PostDebug = std::next(Pos->getIterator());

1979 EmitInstsHere(PostDebug);

1980 } else {

1981

1982

1984 for (; Idx < End; Idx = Slots->getNextNonNullIndex(Idx)) {

1985 Pos = Slots->getInstructionFromIndex(Idx);

1986 if (Pos) {

1987 EmitInstsHere(Pos->getIterator());

1988 break;

1989 }

1990 }

1991

1992

1993

1994

1997 EmitInstsHere(TermIt);

1998 }

1999 }

2000 }

2001

2002 EmitDone = true;

2003 BBSkipInstsMap.clear();

2004}

2005

2007 if (PImpl)

2008 PImpl->emitDebugValues(VRM);

2009}

2010

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

2013#endif

2014

2016 if (PImpl)

2017 PImpl->print(OS);

2018}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug

This file defines the DenseMap class.

This file contains constants used for implementing Dwarf debug support.

std::optional< std::vector< StOtherPiece > > Other

const HexagonInstrInfo * TII

static bool isUndef(ArrayRef< int > Mask)

This file implements a coalescing interval map for small objects.

static void printExtendedName(raw_ostream &OS, const DINode *Node, const DILocation *DL)

static MachineBasicBlock::iterator findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS, BlockSkipInstsMap &BBSkipInstsMap)

Find an iterator for inserting a DBG_VALUE instruction.

static MachineBasicBlock::iterator findNextInsertLocation(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, SlotIndex StopIdx, ArrayRef< MachineOperand > LocMOs, LiveIntervals &LIS, const TargetRegisterInfo &TRI)

Find an iterator for inserting the next DBG_VALUE instruction (or end if no more insert locations fou...

static cl::opt< bool > EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden)

static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS, const LLVMContext &Ctx)

static void removeDebugInstrs(MachineFunction &mf)

static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)

static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)

Return the first found DebugLoc that has a DILocation, given a range of instructions.

unsigned const TargetRegisterInfo * TRI

This file implements a map that provides insertion order iteration.

static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

static bool isReg(const MCInst &MI, unsigned OpNo)

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

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallSet class.

This file defines the SmallVector class.

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

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

API to communicate dependencies between analyses during invalidation.

A container for analyses that lazily runs them and caches their results.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

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

size_t size() const

size - Get the array size.

static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)

Append Ops with operations to apply the Offset.

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

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

Retrieve the details of this fragment expression.

static DIExpression * replaceArg(const DIExpression *Expr, uint64_t OldArg, uint64_t NewArg)

Create a copy of Expr with each instance of DW_OP_LLVM_arg, \p OldArg replaced with DW_OP_LLVM_arg,...

static std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)

Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...

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

Tagged DWARF-like metadata node.

This class represents an Operation in the Expression.

Identifies a unique instance of a variable.

iterator find(const_arg_type_t< KeyT > Val)

Class representing an expression and its matching format.

DISubprogram * getSubprogram() const

Get the attached subprogram.

void setMap(const IntervalMap &m)

setMap - Change the map iterated over.

void advanceTo(KeyT x)

advanceTo - Move to the first interval with stop >= x, or end().

const KeyT & stop() const

stop - Return the end of the current interval.

bool valid() const

valid - Return true if the current position is valid, false for end().

const KeyT & start() const

start - Return the beginning of the current interval.

const ValT & value() const

value - Return the mapped value at the current interval.

void find(KeyT x)

find - Move to the first interval with stop >= x, or end().

void insert(KeyT a, KeyT b, ValT y)

insert - Insert mapping [a;b] -> y before the current position.

void setValue(ValT x)

setValue - Change the mapped value of the current interval.

void setStartUnchecked(KeyT a)

setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...

void setStopUnchecked(KeyT b)

setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps.

const_iterator begin() const

typename Sizer::Allocator Allocator

const_iterator find(KeyT x) const

find - Return an iterator pointing to the first interval ending at or after x, or end().

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

LexicalScope - This class is used to track scope information.

LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...

Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

LiveDebugVariablesWrapperLegacy()

bool runOnMachineFunction(MachineFunction &) override

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

LDVImpl(LiveIntervals *LIS)

void print(raw_ostream &)

void splitRegister(Register OldReg, ArrayRef< Register > NewRegs)

Replace all references to OldReg with NewRegs.

bool runOnMachineFunction(MachineFunction &mf, bool InstrRef)

void mapVirtReg(Register VirtReg, UserValue *EC)

Map virtual register to an equivalence class.

void clear()

Release all memory.

void emitDebugValues(VirtRegMap *VRM)

Recreate DBG_VALUE instruction from data structures.

void splitPHIRegister(Register OldReg, ArrayRef< Register > NewRegs)

Replace any PHI referring to OldReg with its corresponding NewReg, if present.

void dump() const

dump - Print data structures to dbgs().

void splitRegister(Register OldReg, ArrayRef< Register > NewRegs, LiveIntervals &LIS)

splitRegister - Move any user variables in OldReg to the live ranges in NewRegs where they are live.

LiveDebugVariables()

Implementation of the LiveDebugVariables pass.

void print(raw_ostream &OS) const

void analyze(MachineFunction &MF, LiveIntervals *LIS)

void emitDebugValues(VirtRegMap *VRM)

emitDebugValues - Emit new DBG_VALUE instructions reflecting the changes that happened during registe...

bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &Inv)

LiveInterval - This class represents the liveness of a register, or stack slot.

bool hasInterval(Register Reg) const

SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const

Return the first index in the given basic block.

MachineInstr * getInstructionFromIndex(SlotIndex index) const

Returns the instruction associated with the given index.

SlotIndexes * getSlotIndexes() const

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const

Return the last index in the given basic block.

LiveInterval & getInterval(Register Reg)

bool isNotInMIMap(const MachineInstr &Instr) const

Returns true if the specified machine instr has been removed or was never entered in the map.

MachineBasicBlock * getMBBFromIndex(SlotIndex index) const

Result of a LiveRange query.

VNInfo * valueOutOrDead() const

Returns the value alive at the end of the instruction, if any.

This class represents the liveness of a register, stack slot, etc.

const Segment * getSegmentContaining(SlotIndex Idx) const

Return the segment that contains the specified index, or null if there is none.

iterator advanceTo(iterator I, SlotIndex Pos)

advanceTo - Advance the specified iterator to point to the Segment containing the specified position,...

LiveQueryResult Query(SlotIndex Idx) const

Query Liveness at Idx.

SlotIndex beginIndex() const

beginIndex - Return the lowest numbered slot covered.

VNInfo * getVNInfoAt(SlotIndex Idx) const

getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.

iterator find(SlotIndex Pos)

find - Return an iterator pointing to the first segment that ends after Pos, or end().

LLVMContext & getContext() const

An RAII based helper class to modify MachineFunctionProperties when running pass.

instr_iterator insert(instr_iterator I, MachineInstr *M)

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

iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)

Return the first instruction in MBB after I that is not a PHI, label or debug.

iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

instr_iterator instr_end()

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

Analysis pass which computes a MachineDominatorTree.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

Location of a PHI instruction that is also a debug-info variable value, for the duration of register ...

bool useDebugInstrRef() const

Returns true if the function's variable locations are tracked with instruction referencing.

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

DenseMap< unsigned, DebugPHIRegallocPos > DebugPHIPositions

Map of debug instruction numbers to the position of their PHI instructions during register allocation...

const MachineInstrBuilder & addMetadata(const MDNode *MD) const

Representation of each machine instruction.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

void setSubReg(unsigned subReg)

unsigned getSubReg() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

void setReg(Register Reg)

Change the register this operand corresponds to.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

void substPhysReg(MCRegister Reg, const TargetRegisterInfo &)

substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...

void setIsDebug(bool Val=true)

Register getReg() const

getReg - Returns the register number.

bool isIdenticalTo(const MachineOperand &Other) const

Returns true if this operand is identical to the specified operand except for liveness related flags ...

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)

static MachineOperand CreateFI(int Idx)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

This class implements a map that also provides access to all stored values in a deterministic order.

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

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalysisChecker getChecker() const

Build a checker for this PreservedAnalyses and the specified analysis type.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

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

SlotIndex - An opaque wrapper around machine indexes.

SlotIndex getNextIndex() const

Returns the next index.

static bool isEarlierEqualInstr(SlotIndex A, SlotIndex B)

Return true if A refers to the same instruction as B or an earlier one.

SlotIndex getNextSlot() const

Returns the next slot in the index list.

SlotIndex getMBBStartIdx(unsigned Num) const

Returns the first index in the given basic block number.

SlotIndex getIndexBefore(const MachineInstr &MI) const

getIndexBefore - Returns the index of the last indexed instruction before MI, or the start index of i...

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

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

void assign(size_type NumElts, ValueParamT Elt)

iterator erase(const_iterator CI)

void push_back(const T &Elt)

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

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

constexpr bool empty() const

empty - Check if the string is empty.

TargetInstrInfo - Interface to description of machine instruction set.

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

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

virtual const TargetInstrInfo * getInstrInfo() const

VNInfo - Value Number Information.

unsigned id

The ID number of this value.

SlotIndex def

The index of the defining instruction.

int getStackSlot(Register virtReg) const

returns the stack slot mapped to the specified virtual register

MachineFunction & getMachineFunction() const

MCRegister getPhys(Register virtReg) const

returns the physical register mapped to the specified virtual register

bool hasPhys(Register virtReg) const

returns true if the specified virtual register is mapped to a physical register

bool isAssignedReg(Register virtReg) const

returns true if the specified virtual register is not mapped to a stack slot or rematerialized.

static constexpr int NO_STACK_SLOT

self_iterator getIterator()

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

unsigned ID

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

Reg

All possible values of the reg field in the ModR/M byte.

initializer< Ty > init(const Ty &Val)

Scope

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

This is an optimization pass for GlobalISel generic memory operations.

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

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

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

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

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

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

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

IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)

Increment It until it points to a non-debug instruction or to End and return the resulting iterator.

bool any_of(R &&range, UnaryPredicate P)

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

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.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

void initializeLiveDebugVariablesWrapperLegacyPass(PassRegistry &)

std::pair< const MachineInstr *, const MachineInstr * > InsnRange

InsnRange - This is used to track range of instructions with identical lexical scope.

Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

A special type used by analysis passes to provide an address that identifies that particular analysis...

This represents a simple continuous liveness interval for a value.