LLVM: lib/IR/DebugInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

38#include

39#include

40#include

41#include

42

43using namespace llvm;

46

48

49

50 if (!V->isUsedByMetadata())

51 return {};

53 if (!L)

54 return {};

56 if (!MDV)

57 return {};

58

60 for (User *U : MDV->users())

61 if (auto *DDI = dyn_cast(U))

63

64 return Declares;

65}

67

68

69 if (!V->isUsedByMetadata())

70 return {};

72 if (!L)

73 return {};

74

77 if (DVR->getType() == DbgVariableRecord::LocationType::Declare)

79

80 return Declares;

81}

82

84

85

86 if (!V->isUsedByMetadata())

87 return {};

89 if (!L)

90 return {};

91

94 if (DVR->isValueOfVariable())

96

97 return Values;

98}

99

100template <typename IntrinsicT, bool DbgAssignAndValuesOnly>

101static void

104

105

106 if (!V->isUsedByMetadata())

107 return;

108

110

111

112

113

114

117

118

119 auto AppendUsers = [&Ctx, &EncounteredIntrinsics,

120 &EncounteredDbgVariableRecords, &Result,

121 DbgVariableRecords](Metadata *MD) {

123 for (User *U : MDV->users())

124 if (IntrinsicT *DVI = dyn_cast(U))

125 if (EncounteredIntrinsics.insert(DVI).second)

126 Result.push_back(DVI);

127 }

128 if (!DbgVariableRecords)

129 return;

130

131 if (LocalAsMetadata *L = dyn_cast(MD)) {

132 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) {

133 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())

134 if (EncounteredDbgVariableRecords.insert(DVR).second)

135 DbgVariableRecords->push_back(DVR);

136 }

137 }

138 };

139

141 AppendUsers(L);

142 for (Metadata *AL : L->getAllArgListUsers()) {

143 AppendUsers(AL);

144 if (!DbgVariableRecords)

145 continue;

146 DIArgList *DI = cast(AL);

148 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())

149 if (EncounteredDbgVariableRecords.insert(DVR).second)

150 DbgVariableRecords->push_back(DVR);

151 }

152 }

153}

154

159 DbgValues, V, DbgVariableRecords);

160}

161

166 DbgUsers, V, DbgVariableRecords);

167}

168

170 if (auto *LocalScope = dyn_cast_or_null(Scope))

172 return nullptr;

173}

174

176

180

181

182

183

184 return DILocation::get(DII->getContext(), 0, 0, Scope, InlinedAt);

185}

186

188

192

193

194

195

196 return DILocation::get(DVR->getContext(), 0, 0, Scope, InlinedAt);

197}

198

199

200

201

202

204 CUs.clear();

205 SPs.clear();

206 GVs.clear();

207 TYs.clear();

208 Scopes.clear();

209 NodesSeen.clear();

210}

211

213 for (auto *CU : M.debug_compile_units())

214 processCompileUnit(CU);

215 for (auto &F : M.functions()) {

216 if (auto *SP = cast_or_null(F.getSubprogram()))

218

219

223 }

224}

225

226void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {

227 if (!addCompileUnit(CU))

228 return;

229 for (auto *DIG : CU->getGlobalVariables()) {

230 if (!addGlobalVariable(DIG))

231 continue;

232 auto *GV = DIG->getVariable();

233 processScope(GV->getScope());

234 processType(GV->getType());

235 }

236 for (auto *ET : CU->getEnumTypes())

237 processType(ET);

238 for (auto *RT : CU->getRetainedTypes())

239 if (auto *T = dyn_cast(RT))

240 processType(T);

241 else

243 for (auto *Import : CU->getImportedEntities()) {

244 auto *Entity = Import->getEntity();

245 if (auto *T = dyn_cast(Entity))

246 processType(T);

247 else if (auto *SP = dyn_cast(Entity))

249 else if (auto *NS = dyn_cast(Entity))

250 processScope(NS->getScope());

251 else if (auto *M = dyn_cast(Entity))

252 processScope(M->getScope());

253 }

254}

255

258 if (auto *DVI = dyn_cast(&I))

260

261 if (auto DbgLoc = I.getDebugLoc())

263

264 for (const DbgRecord &DPR : I.getDbgRecordRange())

266}

267

269 if (!Loc)

270 return;

271 processScope(Loc->getScope());

273}

274

276 if (const DbgVariableRecord *DVR = dyn_cast(&DR))

279}

280

281void DebugInfoFinder::processType(DIType *DT) {

282 if (!addType(DT))

283 return;

284 processScope(DT->getScope());

285 if (auto *ST = dyn_cast(DT)) {

286 for (DIType *Ref : ST->getTypeArray())

287 processType(Ref);

288 return;

289 }

290 if (auto *DCT = dyn_cast(DT)) {

291 processType(DCT->getBaseType());

292 for (Metadata *D : DCT->getElements()) {

293 if (auto *T = dyn_cast(D))

294 processType(T);

295 else if (auto *SP = dyn_cast(D))

297 }

298 return;

299 }

300 if (auto *DDT = dyn_cast(DT)) {

301 processType(DDT->getBaseType());

302 }

303}

304

305void DebugInfoFinder::processScope(DIScope *Scope) {

306 if (!Scope)

307 return;

308 if (auto *Ty = dyn_cast(Scope)) {

309 processType(Ty);

310 return;

311 }

312 if (auto *CU = dyn_cast(Scope)) {

313 addCompileUnit(CU);

314 return;

315 }

316 if (auto *SP = dyn_cast(Scope)) {

318 return;

319 }

320 if (!addScope(Scope))

321 return;

322 if (auto *LB = dyn_cast(Scope)) {

323 processScope(LB->getScope());

324 } else if (auto *NS = dyn_cast(Scope)) {

325 processScope(NS->getScope());

326 } else if (auto *M = dyn_cast(Scope)) {

327 processScope(M->getScope());

328 }

329}

330

332 if (!addSubprogram(SP))

333 return;

334 processScope(SP->getScope());

335

336

337

338

339

340

341

342

343 processCompileUnit(SP->getUnit());

344 processType(SP->getType());

345 for (auto *Element : SP->getTemplateParams()) {

346 if (auto *TType = dyn_cast(Element)) {

347 processType(TType->getType());

348 } else if (auto *TVal = dyn_cast(Element)) {

349 processType(TVal->getType());

350 }

351 }

352}

353

356 if (!NodesSeen.insert(DV).second)

357 return;

358 processScope(DV->getScope());

359 processType(DV->getType());

360}

361

362bool DebugInfoFinder::addType(DIType *DT) {

363 if (!DT)

364 return false;

365

366 if (!NodesSeen.insert(DT).second)

367 return false;

368

369 TYs.push_back(const_cast<DIType *>(DT));

370 return true;

371}

372

374 if (CU)

375 return false;

376 if (!NodesSeen.insert(CU).second)

377 return false;

378

379 CUs.push_back(CU);

380 return true;

381}

382

384 if (!NodesSeen.insert(DIG).second)

385 return false;

386

387 GVs.push_back(DIG);

388 return true;

389}

390

391bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {

392 if (!SP)

393 return false;

394

395 if (!NodesSeen.insert(SP).second)

396 return false;

397

398 SPs.push_back(SP);

399 return true;

400}

401

402bool DebugInfoFinder::addScope(DIScope *Scope) {

403 if (!Scope)

404 return false;

405

406

407 if (Scope->getNumOperands() == 0)

408 return false;

409 if (!NodesSeen.insert(Scope).second)

410 return false;

411 Scopes.push_back(Scope);

412 return true;

413}

414

418 "Loop ID needs at least one operand");

420 "Loop ID should refer to itself");

421

422

424

425 for (unsigned i = 1; i < OrigLoopID->getNumOperands(); ++i) {

427 if (!MD)

429 else if (Metadata *NewMD = Updater(MD))

431 }

432

434

436 return NewLoopID;

437}

438

441 MDNode *OrigLoopID = I.getMetadata(LLVMContext::MD_loop);

442 if (!OrigLoopID)

443 return;

445 I.setMetadata(LLVMContext::MD_loop, NewLoopID);

446}

447

448

449

453 MDNode *N = dyn_cast_or_null(MD);

454 if (N)

455 return false;

456 if (isa(N) || Reachable.count(N))

457 return true;

458 if (!Visited.insert(N).second)

459 return false;

460 for (auto &OpIt : N->operands()) {

463

464

466 }

467 }

468 return Reachable.count(N);

469}

470

475 MDNode *N = dyn_cast_or_null(MD);

476 if (N)

477 return false;

478 if (isa(N) || AllDILocation.count(N))

479 return true;

480 if (!DIReachable.count(N))

481 return false;

482 if (!Visited.insert(N).second)

483 return false;

484 for (auto &OpIt : N->operands()) {

486 if (Op == MD)

487 continue;

489 return false;

490 }

491 }

493 return true;

494}

495

499 if (isa(MD) || AllDILocation.count(MD))

500 return nullptr;

501

502 if (!DIReachable.count(MD))

503 return MD;

504

505 MDNode *N = dyn_cast_or_null(MD);

506 if (N)

507 return MD;

508

510 bool HasSelfRef = false;

511 for (unsigned i = 0; i < N->getNumOperands(); ++i) {

513 if (A) {

514 Args.push_back(nullptr);

515 } else if (A == MD) {

516 assert(i == 0 && "expected i==0 for self-reference");

517 HasSelfRef = true;

518 Args.push_back(nullptr);

519 } else if (Metadata *NewArg =

521 Args.push_back(NewArg);

522 }

523 }

524 if (Args.empty() || (HasSelfRef && Args.size() == 1))

525 return nullptr;

526

529 if (HasSelfRef)

531 return NewMD;

532}

533

535 assert(N->operands().empty() && "Missing self reference?");

537

538 if (!Visited.insert(N).second)

539 return N;

540

541

542

543

544

546 [&Visited, &DILocationReachable](const MDOperand &Op) {

547 return isDILocationReachable(

548 Visited, DILocationReachable, Op.get());

549 }))

550 return N;

551

553

554

556 [&Visited, &AllDILocation,

557 &DILocationReachable](const MDOperand &Op) {

558 return isAllDILocation(Visited, AllDILocation,

559 DILocationReachable, Op.get());

560 }))

561 return nullptr;

562

564 N, [&AllDILocation, &DILocationReachable](Metadata *MD) -> Metadata * {

565 return stripLoopMDLoc(AllDILocation, DILocationReachable, MD);

566 });

567}

568

570 bool Changed = false;

571 if (F.hasMetadata(LLVMContext::MD_dbg)) {

572 Changed = true;

573 F.setSubprogram(nullptr);

574 }

575

579 if (isa(&I)) {

580 I.eraseFromParent();

581 Changed = true;

582 continue;

583 }

584 if (I.getDebugLoc()) {

585 Changed = true;

587 }

588 if (auto *LoopID = I.getMetadata(LLVMContext::MD_loop)) {

589 auto *NewLoopID = LoopIDsMap.lookup(LoopID);

590 if (!NewLoopID)

592 if (NewLoopID != LoopID)

593 I.setMetadata(LLVMContext::MD_loop, NewLoopID);

594 }

595

596 if (I.hasMetadataOtherThanDebugLoc()) {

597

598 I.setMetadata("heapallocsite", nullptr);

599

600 I.setMetadata(LLVMContext::MD_DIAssignID, nullptr);

601 }

602 I.dropDbgRecords();

603 }

604 }

605 return Changed;

606}

607

609 bool Changed = false;

610

612

613

614 if (NMD.getName().starts_with("llvm.dbg.") ||

615 NMD.getName() == "llvm.gcov") {

616 NMD.eraseFromParent();

617 Changed = true;

618 }

619 }

620

623

624 for (auto &GV : M.globals()) {

625 Changed |= GV.eraseMetadata(LLVMContext::MD_dbg);

626 }

627

628 if (GVMaterializer *Materializer = M.getMaterializer())

629 Materializer->setStripDebugInfo();

630

631 return Changed;

632}

633

634namespace {

635

636

637class DebugTypeInfoRemoval {

639

640public:

641

642 MDNode *EmptySubroutineType;

643

644private:

645

646

647

648

650

651

652

653

654

655

656

657

658public:

662

664 if (!M)

665 return nullptr;

666 auto Replacement = Replacements.find(M);

667 if (Replacement != Replacements.end())

668 return Replacement->second;

669

670 return M;

671 }

672 MDNode *mapNode(Metadata *N) { return dyn_cast_or_null(map(N)); }

673

674

675

676 void traverseAndRemap(MDNode *N) { traverse(N); }

677

678private:

679

681 auto *FileAndScope = cast_or_null(map(MDS->getFile()));

684 auto *Type = cast_or_null(map(MDS->getType()));

685 DIType *ContainingType =

686 cast_or_null(map(MDS->getContainingType()));

687 auto *Unit = cast_or_null(map(MDS->getUnit()));

688 auto Variables = nullptr;

689 auto TemplateParams = nullptr;

690

691

692 auto distinctMDSubprogram = [&]() {

693 return DISubprogram::getDistinct(

695 FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(),

696 ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(),

697 MDS->getFlags(), MDS->getSPFlags(), Unit, TemplateParams, Declaration,

698 Variables);

699 };

700

702 return distinctMDSubprogram();

703

704 auto *NewMDS = DISubprogram::get(

706 FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType,

707 MDS->getVirtualIndex(), MDS->getThisAdjustment(), MDS->getFlags(),

708 MDS->getSPFlags(), Unit, TemplateParams, Declaration, Variables);

709

710 StringRef OldLinkageName = MDS->getLinkageName();

711

712

713 auto OrigLinkage = NewToLinkageName.find(NewMDS);

714 if (OrigLinkage != NewToLinkageName.end()) {

715 if (OrigLinkage->second == OldLinkageName)

716

717 return NewMDS;

718

719

720

721 return distinctMDSubprogram();

722 }

723

724 NewToLinkageName.insert({NewMDS, MDS->getLinkageName()});

725 return NewMDS;

726 }

727

728

730

731 if (CU->getDWOId())

732 return nullptr;

733

734 auto *File = cast_or_null(map(CU->getFile()));

735 MDTuple *EnumTypes = nullptr;

736 MDTuple *RetainedTypes = nullptr;

737 MDTuple *GlobalVariables = nullptr;

738 MDTuple *ImportedEntities = nullptr;

739 return DICompileUnit::getDistinct(

740 CU->getContext(), CU->getSourceLanguage(), File, CU->getProducer(),

741 CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(),

743 RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(),

744 CU->getDWOId(), CU->getSplitDebugInlining(),

745 CU->getDebugInfoForProfiling(), CU->getNameTableKind(),

746 CU->getRangesBaseAddress(), CU->getSysRoot(), CU->getSDK());

747 }

748

750 auto *Scope = map(MLD->getScope());

751 auto *InlinedAt = map(MLD->getInlinedAt());

753 return DILocation::getDistinct(MLD->getContext(), MLD->getLine(),

754 MLD->getColumn(), Scope, InlinedAt);

755 return DILocation::get(MLD->getContext(), MLD->getLine(), MLD->getColumn(),

756 Scope, InlinedAt);

757 }

758

759

762 Ops.reserve(N->getNumOperands());

763 for (auto &I : N->operands())

764 if (I)

767 return Ret;

768 }

769

770

772 if (Replacements.count(N))

773 return;

774

776 if (N)

777 return nullptr;

778 if (auto *MDSub = dyn_cast(N)) {

779 remap(MDSub->getUnit());

780 return getReplacementSubprogram(MDSub);

781 }

782 if (isa(N))

783 return EmptySubroutineType;

784 if (auto *CU = dyn_cast(N))

785 return getReplacementCU(CU);

786 if (isa(N))

787 return N;

788 if (auto *MDLB = dyn_cast(N))

789

790 return mapNode(MDLB->getScope());

791 if (auto *MLD = dyn_cast(N))

792 return getReplacementMDLocation(MLD);

793

794

795

796 if (isa(N))

797 return nullptr;

798

799 return getReplacementMDNode(N);

800 };

801 Replacements[N] = doRemap(N);

802 }

803

804

805 void traverse(MDNode *);

806};

807

808}

809

810void DebugTypeInfoRemoval::traverse(MDNode *N) {

811 if (N || Replacements.count(N))

812 return;

813

814

815

817 if (auto *MDS = dyn_cast(Parent))

818 return Child == MDS->getRetainedNodes().get();

819 return false;

820 };

821

824

825

827 while (!ToVisit.empty()) {

828 auto *N = ToVisit.back();

829 if (!Opened.insert(N).second) {

830

831 remap(N);

833 continue;

834 }

835 for (auto &I : N->operands())

836 if (auto *MDN = dyn_cast_or_null(I))

837 if (!Opened.count(MDN) && !Replacements.count(MDN) && prune(N, MDN) &&

838 !isa(MDN))

840 }

841}

842

844 bool Changed = false;

845

846

848 if (auto *DbgVal = M.getFunction(Name)) {

849 while (!DbgVal->use_empty())

850 cast(DbgVal->user_back())->eraseFromParent();

851 DbgVal->eraseFromParent();

852 Changed = true;

853 }

854 };

855 RemoveUses("llvm.dbg.declare");

856 RemoveUses("llvm.dbg.label");

857 RemoveUses("llvm.dbg.value");

858

859

860 for (auto NMI = M.named_metadata_begin(), NME = M.named_metadata_end();

861 NMI != NME;) {

863 ++NMI;

864

865 if (NMD->getName() == "llvm.dbg.cu")

866 continue;

867 }

868

869

870 for (auto &GV : M.globals())

871 GV.eraseMetadata(LLVMContext::MD_dbg);

872

873 DebugTypeInfoRemoval Mapper(M.getContext());

875 if (!Node)

876 return nullptr;

877 Mapper.traverseAndRemap(Node);

878 auto *NewNode = Mapper.mapNode(Node);

879 Changed |= Node != NewNode;

880 Node = NewNode;

881 return NewNode;

882 };

883

884

885

886 for (auto &F : M) {

887 if (auto *SP = F.getSubprogram()) {

888 Mapper.traverseAndRemap(SP);

889 auto *NewSP = cast(Mapper.mapNode(SP));

890 Changed |= SP != NewSP;

891 F.setSubprogram(NewSP);

892 }

893 for (auto &BB : F) {

894 for (auto &I : BB) {

896 auto *Scope = DL.getScope();

897 MDNode *InlinedAt = DL.getInlinedAt();

898 Scope = remap(Scope);

899 InlinedAt = remap(InlinedAt);

901 Scope, InlinedAt);

902 };

903

904 if (I.getDebugLoc() != DebugLoc())

905 I.setDebugLoc(remapDebugLoc(I.getDebugLoc()));

906

907

909 if (auto *Loc = dyn_cast_or_null(MD))

910 return remapDebugLoc(Loc).get();

911 return MD;

912 });

913

914

915 if (I.hasMetadataOtherThanDebugLoc())

916 I.setMetadata("heapallocsite", nullptr);

917

918

919 I.dropDbgRecords();

920 }

921 }

922 }

923

924

925

926 for (auto &NMD : M.named_metadata()) {

928 for (MDNode *Op : NMD.operands())

930

931 if (!Changed)

932 continue;

933

934 NMD.clearOperands();

935 for (auto *Op : Ops)

936 if (Op)

937 NMD.addOperand(Op);

938 }

939 return Changed;

940}

941

943 if (auto *Val = mdconst::dyn_extract_or_null(

944 M.getModuleFlag("Debug Info Version")))

945 return Val->getZExtValue();

946 return 0;

947}

948

951}

952

955

956

958

960 for (const Instruction *I : SourceInstructions) {

961 if (auto *MD = I->getMetadata(LLVMContext::MD_DIAssignID))

962 IDs.push_back(cast(MD));

964 "Merging with instruction from another function not allowed");

965 }

966

967

968 if (auto *MD = getMetadata(LLVMContext::MD_DIAssignID))

969 IDs.push_back(cast(MD));

970

972 return;

973

975 for (auto It = std::next(IDs.begin()), End = IDs.end(); It != End; ++It) {

976 if (*It != MergeID)

978 }

979 setMetadata(LLVMContext::MD_DIAssignID, MergeID);

980}

981

983

986 if (DL)

987 return;

988

989

990

991 bool MayLowerToCall = false;

992 if (isa(this)) {

993 auto *II = dyn_cast(this);

994 MayLowerToCall =

996 }

997

998 if (!MayLowerToCall) {

1000 return;

1001 }

1002

1003

1004

1006 if (SP)

1007

1008

1009

1011 else

1012

1013

1014

1015

1016

1017

1019}

1020

1021

1022

1023

1024

1026 switch (lang) {

1027#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \

1028 case LLVMDWARFSourceLanguage##NAME: \

1029 return ID;

1030#include "llvm/BinaryFormat/Dwarf.def"

1031#undef HANDLE_DW_LANG

1032 }

1034}

1035

1037 return (DIT *)(Ref ? unwrap(Ref) : nullptr);

1038}

1039

1042}

1043

1046}

1047

1051}

1052

1055}

1056

1059}

1060

1063}

1064

1067}

1068

1071}

1072

1074 delete unwrap(Builder);

1075}

1076

1078 unwrap(Builder)->finalize();

1079}

1080

1083 unwrap(Builder)->finalizeSubprogram(unwrapDI(subprogram));

1084}

1085

1088 LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,

1089 LLVMBool isOptimized, const char *Flags, size_t FlagsLen,

1090 unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,

1092 LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen,

1093 const char *SDK, size_t SDKLen) {

1094 auto File = unwrapDI(FileRef);

1095

1096 return wrap(unwrap(Builder)->createCompileUnit(

1098 StringRef(Producer, ProducerLen), isOptimized, StringRef(Flags, FlagsLen),

1099 RuntimeVer, StringRef(SplitName, SplitNameLen),

1101 SplitDebugInlining, DebugInfoForProfiling,

1104}

1105

1108 size_t FilenameLen, const char *Directory,

1109 size_t DirectoryLen) {

1110 return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen),

1111 StringRef(Directory, DirectoryLen)));

1112}

1113

1116 const char *Name, size_t NameLen,

1117 const char *ConfigMacros, size_t ConfigMacrosLen,

1118 const char *IncludePath, size_t IncludePathLen,

1119 const char *APINotesFile, size_t APINotesFileLen) {

1120 return wrap(unwrap(Builder)->createModule(

1121 unwrapDI(ParentScope), StringRef(Name, NameLen),

1122 StringRef(ConfigMacros, ConfigMacrosLen),

1123 StringRef(IncludePath, IncludePathLen),

1124 StringRef(APINotesFile, APINotesFileLen)));

1125}

1126

1129 const char *Name, size_t NameLen,

1131 return wrap(unwrap(Builder)->createNameSpace(

1132 unwrapDI(ParentScope), StringRef(Name, NameLen), ExportSymbols));

1133}

1134

1137 size_t NameLen, const char *LinkageName, size_t LinkageNameLen,

1141 return wrap(unwrap(Builder)->createFunction(

1142 unwrapDI(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen},

1143 unwrapDI(File), LineNo, unwrapDI(Ty), ScopeLine,

1146 nullptr, nullptr));

1147}

1148

1149

1153 return wrap(unwrap(Builder)->createLexicalBlock(unwrapDI(Scope),

1154 unwrapDI(File),

1155 Line, Col));

1156}

1157

1162 unsigned Discriminator) {

1163 return wrap(unwrap(Builder)->createLexicalBlockFile(unwrapDI(Scope),

1164 unwrapDI(File),

1165 Discriminator));

1166}

1167

1173 unsigned Line) {

1175 unwrapDI(NS),

1176 unwrapDI(File),

1177 Line));

1178}

1179

1184 auto Elts =

1185 (NumElements > 0)

1186 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})

1187 : nullptr;

1189 unwrapDI(Scope), unwrapDI(ImportedEntity),

1190 unwrapDI(File), Line, Elts));

1191}

1192

1196 unsigned NumElements) {

1197 auto Elts =

1198 (NumElements > 0)

1199 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})

1200 : nullptr;

1202 unwrapDI(Scope), unwrapDI(M), unwrapDI(File),

1203 Line, Elts));

1204}

1205

1210 auto Elts =

1211 (NumElements > 0)

1212 ? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})

1213 : nullptr;

1214 return wrap(unwrap(Builder)->createImportedDeclaration(

1215 unwrapDI(Scope), unwrapDI(Decl), unwrapDI(File),

1216 Line, {Name, NameLen}, Elts));

1217}

1218

1224 unwrap(InlinedAt)));

1225}

1226

1228 return unwrapDI(Location)->getLine();

1229}

1230

1232 return unwrapDI(Location)->getColumn();

1233}

1234

1236 return wrap(unwrapDI(Location)->getScope());

1237}

1238

1240 return wrap(unwrapDI(Location)->getInlinedAt());

1241}

1242

1244 return wrap(unwrapDI(Scope)->getFile());

1245}

1246

1248 auto Dir = unwrapDI(File)->getDirectory();

1249 *Len = Dir.size();

1250 return Dir.data();

1251}

1252

1254 auto Name = unwrapDI(File)->getFilename();

1255 *Len = Name.size();

1256 return Name.data();

1257}

1258

1260 if (auto Src = unwrapDI(File)->getSource()) {

1261 *Len = Src->size();

1262 return Src->data();

1263 }

1264 *Len = 0;

1265 return "";

1266}

1267

1270 unsigned Line,

1272 const char *Name, size_t NameLen,

1273 const char *Value, size_t ValueLen) {

1274 return wrap(

1275 unwrap(Builder)->createMacro(unwrapDI(ParentMacroFile), Line,

1277 {Name, NameLen}, {Value, ValueLen}));

1278}

1279

1284 return wrap(unwrap(Builder)->createTempMacroFile(

1285 unwrapDI(ParentMacroFile), Line, unwrapDI(File)));

1286}

1287

1289 const char *Name, size_t NameLen,

1293 IsUnsigned != 0));

1294}

1295

1298 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,

1301auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),

1302 NumElements});

1303return wrap(unwrap(Builder)->createEnumerationType(

1304 unwrapDI(Scope), {Name, NameLen}, unwrapDI(File),

1305 LineNumber, SizeInBits, AlignInBits, Elts, unwrapDI(ClassTy)));

1306}

1307

1310 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,

1312 LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang,

1313 const char *UniqueId, size_t UniqueIdLen) {

1314 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),

1315 NumElements});

1316 return wrap(unwrap(Builder)->createUnionType(

1317 unwrapDI(Scope), {Name, NameLen}, unwrapDI(File),

1319 Elts, RunTimeLang, {UniqueId, UniqueIdLen}));

1320}

1321

1322

1327 unsigned NumSubscripts) {

1328 auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),

1329 NumSubscripts});

1330 return wrap(unwrap(Builder)->createArrayType(Size, AlignInBits,

1331 unwrapDI(Ty), Subs));

1332}

1333

1338 unsigned NumSubscripts) {

1339 auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts),

1340 NumSubscripts});

1341 return wrap(unwrap(Builder)->createVectorType(Size, AlignInBits,

1342 unwrapDI(Ty), Subs));

1343}

1344

1347 size_t NameLen, uint64_t SizeInBits,

1350 return wrap(unwrap(Builder)->createBasicType({Name, NameLen},

1351 SizeInBits, Encoding,

1353}

1354

1358 const char *Name, size_t NameLen) {

1359 return wrap(unwrap(Builder)->createPointerType(

1360 unwrapDI(PointeeTy), SizeInBits, AlignInBits, AddressSpace,

1361 {Name, NameLen}));

1362}

1363

1366 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,

1369 unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder,

1370 const char *UniqueId, size_t UniqueIdLen) {

1371 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),

1372 NumElements});

1373 return wrap(unwrap(Builder)->createStructType(

1374 unwrapDI(Scope), {Name, NameLen}, unwrapDI(File),

1376 unwrapDI(DerivedFrom), Elts, RunTimeLang,

1377 unwrapDI(VTableHolder), {UniqueId, UniqueIdLen}));

1378}

1379

1385 return wrap(unwrap(Builder)->createMemberType(unwrapDI(Scope),

1386 {Name, NameLen}, unwrapDI(File), LineNo, SizeInBits, AlignInBits,

1388}

1389

1392 size_t NameLen) {

1393 return wrap(unwrap(Builder)->createUnspecifiedType({Name, NameLen}));

1394}

1395

1398 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,

1401 return wrap(unwrap(Builder)->createStaticMemberType(

1402 unwrapDI(Scope), {Name, NameLen}, unwrapDI(File),

1404 unwrap(ConstantVal), DW_TAG_member, AlignInBits));

1405}

1406

1409 const char *Name, size_t NameLen,

1414 return wrap(unwrap(Builder)->createObjCIVar(

1415 {Name, NameLen}, unwrapDI(File), LineNo,

1416 SizeInBits, AlignInBits, OffsetInBits,

1418 unwrapDI(PropertyNode)));

1419}

1420

1423 const char *Name, size_t NameLen,

1425 const char *GetterName, size_t GetterNameLen,

1426 const char *SetterName, size_t SetterNameLen,

1427 unsigned PropertyAttributes,

1429 return wrap(unwrap(Builder)->createObjCProperty(

1430 {Name, NameLen}, unwrapDI(File), LineNo,

1431 {GetterName, GetterNameLen}, {SetterName, SetterNameLen},

1432 PropertyAttributes, unwrapDI(Ty)));

1433}

1434

1438 return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI(Type),

1439 Implicit));

1440}

1441

1444 const char *Name, size_t NameLen,

1447 return wrap(unwrap(Builder)->createTypedef(

1448 unwrapDI(Type), {Name, NameLen}, unwrapDI(File), LineNo,

1449 unwrapDI(Scope), AlignInBits));

1450}

1451

1457 return wrap(unwrap(Builder)->createInheritance(

1458 unwrapDI(Ty), unwrapDI(BaseTy),

1460}

1461

1466 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,

1467 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {

1468 return wrap(unwrap(Builder)->createForwardDecl(

1469 Tag, {Name, NameLen}, unwrapDI(Scope),

1470 unwrapDI(File), Line, RuntimeLang, SizeInBits,

1471 AlignInBits, {UniqueIdentifier, UniqueIdentifierLen}));

1472}

1473

1478 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,

1479 LLVMDIFlags Flags, const char *UniqueIdentifier,

1480 size_t UniqueIdentifierLen) {

1481 return wrap(unwrap(Builder)->createReplaceableCompositeType(

1482 Tag, {Name, NameLen}, unwrapDI(Scope),

1483 unwrapDI(File), Line, RuntimeLang, SizeInBits,

1485 {UniqueIdentifier, UniqueIdentifierLen}));

1486}

1487

1491 return wrap(unwrap(Builder)->createQualifiedType(Tag,

1492 unwrapDI(Type)));

1493}

1494

1498 return wrap(unwrap(Builder)->createReferenceType(Tag,

1499 unwrapDI(Type)));

1500}

1501

1504 return wrap(unwrap(Builder)->createNullPtrType());

1505}

1506

1514 return wrap(unwrap(Builder)->createMemberPointerType(

1515 unwrapDI(PointeeType),

1516 unwrapDI(ClassType), AlignInBits, SizeInBits,

1518}

1519

1523 const char *Name, size_t NameLen,

1527 uint64_t StorageOffsetInBits,

1529 return wrap(unwrap(Builder)->createBitFieldMemberType(

1530 unwrapDI(Scope), {Name, NameLen},

1531 unwrapDI(File), LineNumber,

1532 SizeInBits, OffsetInBits, StorageOffsetInBits,

1534}

1535

1543 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {

1544 auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements),

1545 NumElements});

1546 return wrap(unwrap(Builder)->createClassType(

1547 unwrapDI(Scope), {Name, NameLen}, unwrapDI(File),

1548 LineNumber, SizeInBits, AlignInBits, OffsetInBits,

1550 0, unwrapDI(VTableHolder),

1551 unwrapDI(TemplateParamsNode),

1552 {UniqueIdentifier, UniqueIdentifierLen}));

1553}

1554

1558 return wrap(unwrap(Builder)->createArtificialType(unwrapDI(Type)));

1559}

1560

1562 return unwrapDI(MD)->getTag();

1563}

1564

1566 StringRef Str = unwrapDI(DType)->getName();

1567 *Length = Str.size();

1568 return Str.data();

1569}

1570

1572 return unwrapDI(DType)->getSizeInBits();

1573}

1574

1576 return unwrapDI(DType)->getOffsetInBits();

1577}

1578

1580 return unwrapDI(DType)->getAlignInBits();

1581}

1582

1584 return unwrapDI(DType)->getLine();

1585}

1586

1589}

1590

1594 return wrap(

1596}

1597

1602 unsigned NumParameterTypes,

1604 auto Elts = unwrap(Builder)->getOrCreateTypeArray({unwrap(ParameterTypes),

1605 NumParameterTypes});

1606 return wrap(unwrap(Builder)->createSubroutineType(

1608}

1609

1612 return wrap(

1614}

1615

1619 return wrap(unwrap(Builder)->createConstantValueExpression(Value));

1620}

1621

1624 size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,

1627 return wrap(unwrap(Builder)->createGlobalVariableExpression(

1628 unwrapDI(Scope), {Name, NameLen}, {Linkage, LinkLen},

1629 unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit,

1630 true, unwrap(Expr), unwrapDI(Decl),

1631 nullptr, AlignInBits));

1632}

1633

1635 return wrap(unwrapDI(GVE)->getVariable());

1636}

1637

1640 return wrap(unwrapDI(GVE)->getExpression());

1641}

1642

1644 return wrap(unwrapDI(Var)->getFile());

1645}

1646

1648 return wrap(unwrapDI(Var)->getScope());

1649}

1650

1652 return unwrapDI(Var)->getLine();

1653}

1654

1656 size_t Count) {

1657 return wrap(

1659}

1660

1663}

1664

1667 auto *Node = unwrapDI(TargetMetadata);

1668 Node->replaceAllUsesWith(unwrap(Replacement));

1670}

1671

1674 size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,

1677 return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl(

1678 unwrapDI(Scope), {Name, NameLen}, {Linkage, LnkLen},

1679 unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit,

1680 unwrapDI(Decl), nullptr, AlignInBits));

1681}

1682

1687 unwrap(Storage), unwrap(VarInfo),

1688 unwrap(Expr), unwrap(DL),

1689 unwrap(Instr));

1690

1691

1692

1693

1694

1695 assert(isa<DbgRecord *>(DbgInst) &&

1696 "Function unexpectedly in old debug info format");

1697 return wrap(cast<DbgRecord *>(DbgInst));

1698}

1699

1704 unwrap(Storage), unwrap(VarInfo),

1705 unwrap(Expr), unwrap(DL), unwrap(Block));

1706

1707

1708

1709

1710

1711 assert(isa<DbgRecord *>(DbgInst) &&

1712 "Function unexpectedly in old debug info format");

1713 return wrap(cast<DbgRecord *>(DbgInst));

1714}

1715

1719 DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic(

1720 unwrap(Val), unwrap(VarInfo), unwrap(Expr),

1721 unwrap(DebugLoc), unwrap(Instr));

1722

1723

1724

1725

1726

1727 assert(isa<DbgRecord *>(DbgInst) &&

1728 "Function unexpectedly in old debug info format");

1729 return wrap(cast<DbgRecord *>(DbgInst));

1730}

1731

1735 DbgInstPtr DbgInst = unwrap(Builder)->insertDbgValueIntrinsic(

1736 unwrap(Val), unwrap(VarInfo), unwrap(Expr),

1738

1739

1740

1741

1742

1743 assert(isa<DbgRecord *>(DbgInst) &&

1744 "Function unexpectedly in old debug info format");

1745 return wrap(cast<DbgRecord *>(DbgInst));

1746}

1747

1752 return wrap(unwrap(Builder)->createAutoVariable(

1753 unwrap(Scope), {Name, NameLen}, unwrap(File),

1754 LineNo, unwrap(Ty), AlwaysPreserve,

1756}

1757

1760 size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo,

1762 return wrap(unwrap(Builder)->createParameterVariable(

1763 unwrap(Scope), {Name, NameLen}, ArgNo, unwrap(File),

1764 LineNo, unwrap(Ty), AlwaysPreserve,

1766}

1767

1769 int64_t Lo, int64_t Count) {

1770 return wrap(unwrap(Builder)->getOrCreateSubrange(Lo, Count));

1771}

1772

1777 return wrap(unwrap(Builder)->getOrCreateArray({DataValue, Length}).get());

1778}

1779

1782}

1783

1785 unwrap(Func)->setSubprogram(unwrap(SP));

1786}

1787

1789 return unwrapDI(Subprogram)->getLine();

1790}

1791

1793 return wrap(unwrap(Inst)->getDebugLoc().getAsMDNode());

1794}

1795

1797 if (Loc)

1798 unwrap(Inst)->setDebugLoc(DebugLoc(unwrap(Loc)));

1799 else

1800 unwrap(Inst)->setDebugLoc(DebugLoc());

1801}

1802

1807 return wrap(unwrap(Builder)->createLabel(

1808 unwrapDI(Context), StringRef(Name, NameLen),

1809 unwrapDI(File), LineNo, AlwaysPreserve));

1810}

1811

1816 unwrapDI(LabelInfo), unwrapDI(Location),

1817 unwrap(InsertBefore));

1818

1819

1820

1821

1822

1823 assert(isa<DbgRecord *>(DbgInst) &&

1824 "Function unexpectedly in old debug info format");

1825 return wrap(cast<DbgRecord *>(DbgInst));

1826}

1827

1832 unwrapDI(LabelInfo), unwrapDI(Location),

1833 unwrap(InsertAtEnd));

1834

1835

1836

1837

1838

1839 assert(isa<DbgRecord *>(DbgInst) &&

1840 "Function unexpectedly in old debug info format");

1841 return wrap(cast<DbgRecord *>(DbgInst));

1842}

1843

1846#define HANDLE_METADATA_LEAF(CLASS) \

1847 case Metadata::CLASS##Kind: \

1848 return (LLVMMetadataKind)LLVM##CLASS##MetadataKind;

1849#include "llvm/IR/Metadata.def"

1850 default:

1852 }

1853}

1854

1856 assert(ID && "Expected non-null ID");

1859

1860 auto MapIt = Map.find(ID);

1861 if (MapIt == Map.end())

1862 return make_range(nullptr, nullptr);

1863

1864 return make_range(MapIt->second.begin(), MapIt->second.end());

1865}

1866

1868 assert(ID && "Expected non-null ID");

1870

1872

1873

1874

1875 if (!IDAsValue)

1877

1878 return make_range(IDAsValue->user_begin(), IDAsValue->user_end());

1879}

1880

1884 if (Range.empty() && DVRAssigns.empty())

1885 return;

1887 for (auto *DAI : ToDelete)

1888 DAI->eraseFromParent();

1889 for (auto *DVR : DVRAssigns)

1890 DVR->eraseFromParent();

1891}

1892

1894

1896

1897

1898

1900 for (auto *I : InstVec)

1901 I->setMetadata(LLVMContext::MD_DIAssignID, New);

1902

1904}

1905

1912 if (DVR.isDbgAssign())

1914 if (auto *DAI = dyn_cast(&I))

1916 else

1917 I.setMetadata(LLVMContext::MD_DIAssignID, nullptr);

1918 }

1919 }

1920 for (auto *DAI : ToDelete)

1921 DAI->eraseFromParent();

1922 for (auto *DVR : DPToDelete)

1923 DVR->eraseFromParent();

1924}

1925

1926

1927

1928template

1931 uint64_t SliceSizeInBits, const T *AssignRecord,

1932 std::optionalDIExpression::FragmentInfo &Result) {

1933

1934 if (AssignRecord->isKillAddress())

1935 return false;

1936

1937 int64_t AddrOffsetInBits;

1938 {

1939 int64_t AddrOffsetInBytes;

1941

1942 if (!AssignRecord->getAddressExpression()->extractLeadingOffset(

1943 AddrOffsetInBytes, PostOffsetOps))

1944 return false;

1945 AddrOffsetInBits = AddrOffsetInBytes * 8;

1946 }

1947

1948 Value *Addr = AssignRecord->getAddress();

1949

1950 int64_t BitExtractOffsetInBits = 0;

1952 AssignRecord->getFragmentOrEntireVariable();

1953

1954 int64_t OffsetFromLocationInBits;

1956 DL, Dest, SliceOffsetInBits, SliceSizeInBits, Addr, AddrOffsetInBits,

1957 BitExtractOffsetInBits, VarFrag, Result, OffsetFromLocationInBits);

1958}

1959

1960

1961

1965 std::optionalDIExpression::FragmentInfo &Result) {

1967 SliceSizeInBits, DbgAssign, Result);

1968}

1969

1970

1971

1975 std::optionalDIExpression::FragmentInfo &Result) {

1977 SliceSizeInBits, DVRAssign, Result);

1978}

1979

1980

1981

1982

1985 auto GetNewID = [&Map](Metadata *Old) {

1986 DIAssignID *OldID = cast(Old);

1987 if (DIAssignID *NewID = Map.lookup(OldID))

1988 return NewID;

1990 Map[OldID] = NewID;

1991 return NewID;

1992 };

1993

1995 if (DVR.isDbgAssign())

1996 DVR.setAssignId(GetNewID(DVR.getAssignID()));

1997 }

1998 if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID))

1999 I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID));

2000 else if (auto *DAI = dyn_cast(&I))

2001 DAI->setAssignId(GetNewID(DAI->getAssignID()));

2002}

2003

2004

2005

2006

2007static std::optional

2011 return std::nullopt;

2012 APInt GEPOffset(DL.getIndexTypeSizeInBits(StoreDest->getType()), 0);

2014 DL, GEPOffset, true);

2015

2017 return std::nullopt;

2018

2020

2022 return std::nullopt;

2023 if (const auto *Alloca = dyn_cast(Base))

2024 return AssignmentInfo(DL, Alloca, OffsetInBytes * 8, SizeInBits);

2025 return std::nullopt;

2026}

2027

2030 const Value *StoreDest = I->getRawDest();

2031

2032 auto *ConstLengthInBytes = dyn_cast(I->getLength());

2033 if (!ConstLengthInBytes)

2034

2035 return std::nullopt;

2036 uint64_t SizeInBits = 8 * ConstLengthInBytes->getZExtValue();

2038}

2039

2042 TypeSize SizeInBits = DL.getTypeSizeInBits(SI->getValueOperand()->getType());

2044}

2045

2050}

2051

2052

2056 auto *ID = StoreLikeInst.getMetadata(LLVMContext::MD_DIAssignID);

2057 assert(ID && "Store instruction must have DIAssignID metadata");

2058 (void)ID;

2059

2060 const uint64_t StoreStartBit = Info.OffsetInBits;

2061 const uint64_t StoreEndBit = Info.OffsetInBits + Info.SizeInBits;

2062

2063 uint64_t FragStartBit = StoreStartBit;

2064 uint64_t FragEndBit = StoreEndBit;

2065

2066 bool StoreToWholeVariable = Info.StoreToWholeAlloca;

2068

2069

2070

2071 const uint64_t VarStartBit = 0;

2073

2074

2075 FragEndBit = std::min(FragEndBit, VarEndBit);

2076

2077

2078 if (FragStartBit >= FragEndBit)

2079 return;

2080

2081 StoreToWholeVariable = FragStartBit <= VarStartBit && FragEndBit >= *Size;

2082 }

2083

2085 if (!StoreToWholeVariable) {

2087 FragEndBit - FragStartBit);

2088 assert(R.has_value() && "failed to create fragment expression");

2089 Expr = *R;

2090 }

2092 if (StoreLikeInst.getParent()->IsNewDbgInfoFormat) {

2094 &StoreLikeInst, Val, VarRec.Var, Expr, Dest, AddrExpr, VarRec.DL);

2095 (void)Assign;

2096 LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");

2097 return;

2098 }

2099 auto Assign = DIB.insertDbgAssign(&StoreLikeInst, Val, VarRec.Var, Expr, Dest,

2100 AddrExpr, VarRec.DL);

2101 (void)Assign;

2103 if (const auto *Record = dyn_cast<DbgRecord *>(Assign))

2104 errs() << " > INSERT: " << *Record << "\n";

2105 else

2106 errs() << " > INSERT: " << *cast<Instruction *>(Assign) << "\n";

2107 });

2108}

2109

2110#undef DEBUG_TYPE

2111#define DEBUG_TYPE "assignment-tracking"

2112

2115 bool DebugPrints) {

2116

2117 if (Vars.empty())

2118 return;

2119

2120 auto &Ctx = Start->getContext();

2121 auto &Module = *Start->getModule();

2122

2123

2126

2127

2129 for (auto BBI = Start; BBI != End; ++BBI) {

2131

2132 std::optional Info;

2133 Value *ValueComponent = nullptr;

2134 Value *DestComponent = nullptr;

2135 if (auto *AI = dyn_cast(&I)) {

2136

2137

2138

2140 ValueComponent = Undef;

2141 DestComponent = AI;

2142 } else if (auto *SI = dyn_cast(&I)) {

2144 ValueComponent = SI->getValueOperand();

2145 DestComponent = SI->getPointerOperand();

2146 } else if (auto *MI = dyn_cast(&I)) {

2148

2149 ValueComponent = Undef;

2150 DestComponent = MI->getOperand(0);

2151 } else if (auto *MI = dyn_cast(&I)) {

2153

2154

2155 auto *ConstValue = dyn_cast(MI->getOperand(1));

2156 if (ConstValue && ConstValue->isZero())

2157 ValueComponent = ConstValue;

2158 else

2159 ValueComponent = Undef;

2160 DestComponent = MI->getOperand(0);

2161 } else {

2162

2163 continue;

2164 }

2165

2166 assert(ValueComponent && DestComponent);

2167 LLVM_DEBUG(errs() << "SCAN: Found store-like: " << I << "\n");

2168

2169

2170 if (Info.has_value()) {

2173 << " | SKIP: Untrackable store (e.g. through non-const gep)\n");

2174 continue;

2175 }

2177

2178

2179 auto LocalIt = Vars.find(Info->Base);

2180 if (LocalIt == Vars.end()) {

2183 << " | SKIP: Base address not associated with local variable\n");

2184 continue;

2185 }

2186

2188 cast_or_null(I.getMetadata(LLVMContext::MD_DIAssignID));

2189 if (ID) {

2191 I.setMetadata(LLVMContext::MD_DIAssignID, ID);

2192 }

2193

2194 for (const VarRecord &R : LocalIt->second)

2196 }

2197 }

2198}

2199

2200bool AssignmentTrackingPass::runOnFunction(Function &F) {

2201

2202 if (F.hasFnAttribute(Attribute::OptimizeNone))

2203 return false;

2204

2205 bool Changed = false;

2206 auto *DL = &F.getDataLayout();

2207

2208

2209

2212

2213

2215 auto ProcessDeclare = [&](auto *Declare, auto &DeclareList) {

2216

2217

2218

2219 if (Declare->getExpression()->getNumElements() != 0)

2220 return;

2221 if (!Declare->getAddress())

2222 return;

2224 dyn_cast(Declare->getAddress()->stripPointerCasts())) {

2225

2226 if (!Alloca->isStaticAlloca())

2227 return;

2228

2229 if (auto Sz = Alloca->getAllocationSize(*DL); Sz && Sz->isScalable())

2230 return;

2231 DeclareList[Alloca].insert(Declare);

2233 }

2234 };

2235 for (auto &BB : F) {

2236 for (auto &I : BB) {

2238 if (DVR.isDbgDeclare())

2239 ProcessDeclare(&DVR, DVRDeclares);

2240 }

2242 ProcessDeclare(DDI, DbgDeclares);

2243 }

2244 }

2245

2246

2247

2248

2249

2250

2251

2252

2253

2254

2256

2257

2258 auto DeleteSubsumedDeclare = [&](const auto &Markers, auto &Declares) {

2260 for (auto *Declare : Declares) {

2261

2262

2263

2264

2265

2266

2267

2271 }));

2272

2273

2274 Declare->eraseFromParent();

2275 Changed = true;

2276 }

2277 };

2278 for (auto &P : DbgDeclares)

2280 for (auto &P : DVRDeclares)

2282 return Changed;

2283}

2284

2286 "debug-info-assignment-tracking";

2287

2292}

2293

2296 return Value && !cast(Value)->getValue()->isZeroValue();

2297}

2298

2301}

2302

2305 if (!runOnFunction(F))

2307

2308

2309

2310

2312

2313

2314

2317 return PA;

2318}

2319

2322 bool Changed = false;

2323 for (auto &F : M)

2324 Changed |= runOnFunction(F);

2325

2326 if (!Changed)

2328

2329

2331

2332

2333

2336 return PA;

2337}

2338

2339#undef DEBUG_TYPE

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

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

Analysis containing CSE Info

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)

static DIImportedEntity * createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, Metadata *NS, DIFile *File, unsigned Line, StringRef Name, DINodeArray Elements, SmallVectorImpl< TrackingMDNodeRef > &ImportedModules)

static void setAssignmentTrackingModuleFlag(Module &M)

static DISubprogram::DISPFlags pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized)

static Metadata * stripLoopMDLoc(const SmallPtrSetImpl< Metadata * > &AllDILocation, const SmallPtrSetImpl< Metadata * > &DIReachable, Metadata *MD)

static MDNode * updateLoopMetadataDebugLocationsImpl(MDNode *OrigLoopID, function_ref< Metadata *(Metadata *)> Updater)

static MDNode * stripDebugLocFromLoopID(MDNode *N)

bool calculateFragmentIntersectImpl(const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const T *AssignRecord, std::optional< DIExpression::FragmentInfo > &Result)

FIXME: Remove this wrapper function and call DIExpression::calculateFragmentIntersect directly.

static const char * AssignmentTrackingModuleFlag

static DINode::DIFlags map_from_llvmDIFlags(LLVMDIFlags Flags)

static unsigned map_from_llvmDWARFsourcelanguage(LLVMDWARFSourceLanguage lang)

static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest, Instruction &StoreLikeInst, const VarRecord &VarRec, DIBuilder &DIB)

Returns nullptr if the assignment shouldn't be attributed to this variable.

static LLVMDIFlags map_to_llvmDIFlags(DINode::DIFlags Flags)

static void findDbgIntrinsics(SmallVectorImpl< IntrinsicT * > &Result, Value *V, SmallVectorImpl< DbgVariableRecord * > *DbgVariableRecords)

static bool getAssignmentTrackingModuleFlag(const Module &M)

static bool isAllDILocation(SmallPtrSetImpl< Metadata * > &Visited, SmallPtrSetImpl< Metadata * > &AllDILocation, const SmallPtrSetImpl< Metadata * > &DIReachable, Metadata *MD)

static bool isDILocationReachable(SmallPtrSetImpl< Metadata * > &Visited, SmallPtrSetImpl< Metadata * > &Reachable, Metadata *MD)

Return true if a node is a DILocation or if a DILocation is indirectly referenced by one of the node'...

DIT * unwrapDI(LLVMMetadataRef Ref)

static std::optional< AssignmentInfo > getAssignmentInfoImpl(const DataLayout &DL, const Value *StoreDest, TypeSize SizeInBits)

Collect constant properies (base, size, offset) of StoreDest.

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

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.

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

uint64_t IntrinsicInst * II

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

This file defines the SmallPtrSet class.

This file defines the SmallVector class.

static uint32_t getFlags(const Symbol *Sym)

Class for arbitrary precision integers.

bool isNegative() const

Determine sign of this APInt.

uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const

If this value is smaller than the specified limit, return it, otherwise return the limit value.

an instruction to allocate memory on the stack

Type * getAllocatedType() const

Return the type that is being allocated by the instruction.

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

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

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

LLVM Basic Block Representation.

Represents analyses that only rely on functions' control flow.

List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.

SmallVector< DbgVariableRecord * > getAllDbgVariableRecordUsers()

static DIAssignID * getDistinct(LLVMContext &Context)

DbgInstPtr insertDbgAssign(Instruction *LinkedInstr, Value *Val, DILocalVariable *SrcVar, DIExpression *ValExpr, Value *Addr, DIExpression *AddrExpr, const DILocation *DL)

Insert a new llvm.dbg.assign intrinsic call.

static bool calculateFragmentIntersect(const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits, int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag, std::optional< DIExpression::FragmentInfo > &Result, int64_t &OffsetFromLocationInBits)

Computes a fragment, bit-extract operation if needed, and new constant offset to describe a part of a...

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

A pair of DIGlobalVariable and DIExpression.

DISubprogram * getSubprogram() const

Get the subprogram for this scope.

DILocalScope * getScope() const

Get the local scope for this variable.

static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)

When two instructions are combined into a single instruction we also need to combine the original loc...

Tagged DWARF-like metadata node.

Base class for scope-like contexts.

StringRef getName() const

DIScope * getScope() const

static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)

DISPFlags

Debug info subprogram flags.

Type array for a subprogram.

std::optional< uint64_t > getSizeInBits() const

Determines the size of the variable's type.

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

This represents the llvm.dbg.assign instruction.

This represents the llvm.dbg.declare instruction.

Base class for non-instruction debug metadata records that have positions within IR.

DebugLoc getDebugLoc() const

LLVMContext & getContext()

This represents the llvm.dbg.value instruction.

This is the common base class for debug info intrinsics for variables.

Record of a variable value-assignment, aka a non instruction representation of the dbg....

static DbgVariableRecord * createLinkedDVRAssign(Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable, DIExpression *Expression, Value *Address, DIExpression *AddressExpression, const DILocation *DI)

void processInstruction(const Module &M, const Instruction &I)

Process a single instruction and collect debug info anchors.

void processModule(const Module &M)

Process entire module and collect debug info anchors.

void processVariable(const Module &M, const DILocalVariable *DVI)

Process a DILocalVariable.

void processSubprogram(DISubprogram *SP)

Process subprogram.

void processLocation(const Module &M, const DILocation *Loc)

Process debug info location.

void reset()

Clear all lists.

void processDbgRecord(const Module &M, const DbgRecord &DR)

Process a DbgRecord (e.g, treat a DbgVariableRecord like a DbgVariableIntrinsic).

DILocation * get() const

Get the underlying DILocation.

MDNode * getScope() const

DILocation * getInlinedAt() const

Identifies a unique instance of a whole variable (discards/ignores fragment information).

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

iterator find(const_arg_type_t< KeyT > Val)

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

Implements a dense probed hash-table based set.

BasicBlockListType::iterator iterator

DISubprogram * getSubprogram() const

Get the attached subprogram.

void mergeDIAssignID(ArrayRef< const Instruction * > SourceInstructions)

Merge the DIAssignID metadata from this instruction and those attached to instructions in SourceInstr...

void dropLocation()

Drop the instruction's debug location.

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

const Function * getFunction() const

Return the function this instruction belongs to.

MDNode * getMetadata(unsigned KindID) const

Get the metadata of given kind attached to this Instruction.

void setMetadata(unsigned KindID, MDNode *Node)

Set the metadata of the specified kind to the specified node.

void updateLocationAfterHoist()

Updates the debug location given that the instruction has been hoisted from a block to a predecessor ...

void applyMergedLocation(DILocation *LocA, DILocation *LocB)

Merge 2 debug locations and apply it to the Instruction.

void setDebugLoc(DebugLoc Loc)

Set the debug location information for this instruction.

static bool mayLowerToFunctionCall(Intrinsic::ID IID)

Check if the intrinsic might lower into a regular function call in the course of IR transformations.

DenseMap< DIAssignID *, SmallVector< Instruction *, 1 > > AssignmentIDToInstrs

Map DIAssignID -> Instructions with that attachment.

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

LLVMContextImpl *const pImpl

void replaceOperandWith(unsigned I, Metadata *New)

Replace a specific operand.

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

void replaceAllUsesWith(Metadata *MD)

RAUW a temporary.

static void deleteTemporary(MDNode *N)

Deallocate a node created by getTemporary.

const MDOperand & getOperand(unsigned I) const

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

unsigned getNumOperands() const

Return number of MDNode operands.

LLVMContext & getContext() const

Tracking metadata reference owned by Metadata.

static TempMDTuple getTemporary(LLVMContext &Context, ArrayRef< Metadata * > MDs)

Return a temporary node.

This is the common base class for memset/memcpy/memmove.

A Module instance is used to store all the information related to an LLVM module.

@ Max

Takes the max of the two values, which are required to be integers.

StringRef getName() const

A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...

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.

void preserveSet()

Mark an analysis set as preserved.

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

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

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

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

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

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

void reserve(size_type N)

void push_back(const T &Elt)

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

An instruction for storing to memory.

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

constexpr bool empty() const

empty - Check if the string is empty.

TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...

void push_back(EltTy NewVal)

static constexpr TypeSize getFixed(ScalarTy ExactSize)

The instances of the Type class are immutable: once they are created, they are never changed.

static IntegerType * getInt1Ty(LLVMContext &C)

static UndefValue * get(Type *T)

Static factory methods - Return an 'undef' object of the specified type.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const

Accumulate the constant offset this value has compared to a base pointer.

LLVMContext & getContext() const

All values hold a context through their type.

user_iterator_impl< User > user_iterator

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

size_type count(const_arg_type_t< ValueT > V) const

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

constexpr bool isScalable() const

Returns whether the quantity is scaled by a runtime quantity (vscale).

An efficient, type-erasing, non-owning reference to a callable.

const ParentTy * getParent() const

A range adaptor for a pair of iterators.

LLVMMetadataRef LLVMDIBuilderCreateObjCIVar(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, LLVMMetadataRef Ty, LLVMMetadataRef PropertyNode)

Create debugging information entry for Objective-C instance variable.

LLVMMetadataRef LLVMDILocationGetInlinedAt(LLVMMetadataRef Location)

Get the "inline at" location associated with this debug location.

LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder, LLVMMetadataRef *Data, size_t NumElements)

Create an array of DI Nodes.

LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef *Elements, unsigned NumElements, LLVMMetadataRef ClassTy)

Create debugging information entry for an enumeration.

LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements, unsigned NumElements)

Create a descriptor for an imported module.

uint64_t LLVMDITypeGetSizeInBits(LLVMMetadataRef DType)

Get the size of this DIType in bits.

LLVMDWARFMacinfoRecordType

Describes the kind of macro declaration used for LLVMDIBuilderCreateMacro.

LLVMMetadataRef LLVMDIBuilderCreateFunction(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool IsLocalToUnit, LLVMBool IsDefinition, unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized)

Create a new descriptor for the specified subprogram.

LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block)

Only use in "new debug format" (LLVMIsNewDbgInfoFormat() is true).

LLVMMetadataRef LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits, LLVMDIFlags Flags, LLVMMetadataRef Type)

Create debugging information entry for a bit field member.

LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE)

Retrieves the DIVariable associated with this global variable expression.

LLVMMetadataRef LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder, LLVMMetadataRef Type)

Create a uniqued DIType* clone with FlagArtificial set.

LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, LLVMBool Implicit)

Create a uniqued DIType* clone with FlagObjectPointer.

void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder)

Construct any deferred debug info descriptors.

LLVMMetadataRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Discriminator)

Create a descriptor for a lexical block with a new file attached.

unsigned LLVMDISubprogramGetLine(LLVMMetadataRef Subprogram)

Get the line associated with a given subprogram.

LLVMMetadataRef LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen)

Create a DWARF unspecified type.

LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope, const char *Name, size_t NameLen, LLVMBool ExportSymbols)

Creates a new descriptor for a namespace with the specified parent scope.

LLVMMetadataRef LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line, unsigned Column, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt)

Creates a new DebugLocation that describes a source location.

uint32_t LLVMDITypeGetAlignInBits(LLVMMetadataRef DType)

Get the alignment of this DIType in bits.

LLVMMetadataRef LLVMDIGlobalVariableExpressionGetExpression(LLVMMetadataRef GVE)

Retrieves the DIExpression associated with this global variable expression.

LLVMMetadataRef LLVMDIVariableGetScope(LLVMMetadataRef Var)

Get the metadata of the scope associated with a given variable.

LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst)

Get the debug location for the given instruction.

LLVMMetadataRef LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Type)

Create debugging information entry for a c++ style reference or rvalue reference type.

LLVMMetadataRef LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope, const char *Name, size_t NameLen, const char *ConfigMacros, size_t ConfigMacrosLen, const char *IncludePath, size_t IncludePathLen, const char *APINotesFile, size_t APINotesFileLen)

Creates a new descriptor for a module with the specified parent scope.

LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M)

Construct a builder for a module, and do not allow for unresolved nodes attached to the module.

void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP)

Set the subprogram attached to a function.

LLVMDWARFSourceLanguage

Source languages known by DWARF.

LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, int64_t LowerBound, int64_t Count)

Create a descriptor for a value range.

LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M)

Construct a builder for a module and collect unresolved nodes attached to the module in order to reso...

void LLVMDisposeTemporaryMDNode(LLVMMetadataRef TempNode)

Deallocate a temporary node.

LLVMMetadataRef LLVMDILocationGetScope(LLVMMetadataRef Location)

Get the local scope associated with this debug location.

LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef NS, LLVMMetadataRef File, unsigned Line)

Create a descriptor for an imported namespace.

LLVMMetadataRef LLVMDIBuilderCreateTempMacroFile(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentMacroFile, unsigned Line, LLVMMetadataRef File)

Create debugging information temporary entry for a macro file.

void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc)

Set the debug location for the given instruction.

LLVMMetadataRef LLVMDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, int64_t Value, LLVMBool IsUnsigned)

Create debugging information entry for an enumerator.

LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder, uint64_t *Addr, size_t Length)

Create a new descriptor for the specified variable which has a complex address expression for its add...

LLVMMetadataRef LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size, uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts)

Create debugging information entry for a vector type.

LLVMMetadataRef LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeType, LLVMMetadataRef ClassType, uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags)

Create debugging information entry for a pointer to member.

unsigned LLVMDILocationGetColumn(LLVMMetadataRef Location)

Get the column number of this debug location.

LLVMDIFlags

Debug info flags.

LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits)

Create a new descriptor for a local auto variable.

LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data, size_t NumElements)

Create a new temporary MDNode.

LLVMDIFlags LLVMDITypeGetFlags(LLVMMetadataRef DType)

Get the flags associated with this DIType.

const char * LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len)

Get the directory of a given file.

void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TempTargetMetadata, LLVMMetadataRef Replacement)

Replace all uses of temporary metadata.

const char * LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len)

Get the name of a given file.

LLVMMetadataRef LLVMDIBuilderCreateLabel(LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMBool AlwaysPreserve)

Create a new descriptor for a label.

unsigned LLVMDebugMetadataVersion(void)

The current debug metadata version number.

unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef Module)

The version of debug metadata that's present in the provided Module.

unsigned LLVMDITypeGetLine(LLVMMetadataRef DType)

Get the source line where this DIType is declared.

LLVMMetadataRef LLVMDIVariableGetFile(LLVMMetadataRef Var)

Get the metadata of the file associated with a given variable.

LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements, unsigned NumElements)

Create a descriptor for an imported module that aliases another imported entity descriptor.

LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal, uint32_t AlignInBits)

Create debugging information entry for a C++ static data member.

uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD)

Get the dwarf::Tag of a DINode.

LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits)

Create a new descriptor for the specified variable.

LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, LLVMMetadataRef Decl, uint32_t AlignInBits)

Create a new descriptor for the specified global variable that is temporary and meant to be RAUWed.

LLVMMetadataRef LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Type)

Create debugging information entry for a qualified type, e.g.

LLVMMetadataKind LLVMGetMetadataKind(LLVMMetadataRef Metadata)

Obtain the enumerated type of a Metadata instance.

LLVMMetadataRef LLVMDIBuilderCreateUnionType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen)

Create debugging information entry for a union.

LLVMMetadataRef LLVMDIBuilderCreateForwardDecl(LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, const char *UniqueIdentifier, size_t UniqueIdentifierLen)

Create a permanent forward-declared type.

LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags)

Create a new descriptor for a function parameter variable.

LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, LLVMMetadataRef File, LLVMMetadataRef *ParameterTypes, unsigned NumParameterTypes, LLVMDIFlags Flags)

Create subroutine type.

LLVMMetadataRef LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, const char *GetterName, size_t GetterNameLen, const char *SetterName, size_t SetterNameLen, unsigned PropertyAttributes, LLVMMetadataRef Ty)

Create debugging information entry for Objective-C property.

LLVMMetadataRef LLVMDIBuilderCreateMacro(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentMacroFile, unsigned Line, LLVMDWARFMacinfoRecordType RecordType, const char *Name, size_t NameLen, const char *Value, size_t ValueLen)

Create debugging information entry for a macro.

LLVMDWARFEmissionKind

The amount of debug information to emit.

LLVMDbgRecordRef LLVMDIBuilderInsertLabelAtEnd(LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo, LLVMMetadataRef Location, LLVMBasicBlockRef InsertAtEnd)

Insert a new llvm.dbg.label intrinsic call.

LLVMMetadataRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts)

Create debugging information entry for an array.

LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordAtEnd(LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block)

Only use in "new debug format" (LLVMIsNewDbgInfoFormat() is true).

LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope)

Get the metadata of the file associated with a given scope.

void LLVMDIBuilderFinalizeSubprogram(LLVMDIBuilderRef Builder, LLVMMetadataRef Subprogram)

Finalize a specific subprogram.

LLVMMetadataRef LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder, uint64_t Value)

Create a new descriptor for the specified variable that does not have an address, but does have a con...

LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements, unsigned NumElements, LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode, const char *UniqueIdentifier, size_t UniqueIdentifierLen)

Create debugging information entry for a class.

LLVMMetadataRef LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags, LLVMMetadataRef Ty)

Create debugging information entry for a member.

unsigned LLVMDILocationGetLine(LLVMMetadataRef Location)

Get the line number of this debug location.

LLVMMetadataRef LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder)

Create C++11 nullptr type.

LLVMMetadataRef LLVMDIBuilderCreateInheritance(LLVMDIBuilderRef Builder, LLVMMetadataRef Ty, LLVMMetadataRef BaseTy, uint64_t BaseOffset, uint32_t VBPtrOffset, LLVMDIFlags Flags)

Create debugging information entry to establish inheritance relationship between two types.

LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang, LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen, LLVMBool isOptimized, const char *Flags, size_t FlagsLen, unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen, LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining, LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen, const char *SDK, size_t SDKLen)

A CompileUnit provides an anchor for all debugging information generated during this instance of comp...

LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef Module)

Strip debug info in the module if it exists.

LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore(LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr)

Only use in "new debug format" (LLVMIsNewDbgInfoFormat() is true).

LLVMDbgRecordRef LLVMDIBuilderInsertLabelBefore(LLVMDIBuilderRef Builder, LLVMMetadataRef LabelInfo, LLVMMetadataRef Location, LLVMValueRef InsertBefore)

Insert a new llvm.dbg.label intrinsic call.

LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, size_t NameLen, uint64_t SizeInBits, LLVMDWARFTypeEncoding Encoding, LLVMDIFlags Flags)

Create debugging information entry for a basic type.

unsigned LLVMDIVariableGetLine(LLVMMetadataRef Var)

Get the source line where this DIVariable is declared.

LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore(LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo, LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr)

Only use in "new debug format" (LLVMIsNewDbgInfoFormat() is true).

unsigned LLVMDWARFTypeEncoding

An LLVM DWARF type encoding.

LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, unsigned Column)

Create a descriptor for a lexical block with the specified parent context.

LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder, LLVMMetadataRef *Data, size_t NumElements)

Create a type array.

LLVMMetadataRef LLVMDIBuilderCreateReplaceableCompositeType(LLVMDIBuilderRef Builder, unsigned Tag, const char *Name, size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, const char *UniqueIdentifier, size_t UniqueIdentifierLen)

Create a temporary forward-declared type.

const char * LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len)

Get the source of a given file.

uint64_t LLVMDITypeGetOffsetInBits(LLVMMetadataRef DType)

Get the offset of this DIType in bits.

LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl, LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen, LLVMMetadataRef *Elements, unsigned NumElements)

Create a descriptor for an imported function, type, or variable.

LLVMMetadataRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen)

Create a file descriptor to hold debugging information for a file.

const char * LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length)

Get the name of this DIType.

unsigned LLVMMetadataKind

LLVMMetadataRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope, uint32_t AlignInBits)

Create debugging information entry for a typedef.

LLVMMetadataRef LLVMDIBuilderCreateStructType(LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder, const char *UniqueId, size_t UniqueIdLen)

Create debugging information entry for a struct.

void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder)

Deallocates the DIBuilder and everything it owns.

LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, const char *Name, size_t NameLen)

Create debugging information entry for a pointer.

LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func)

Get the metadata of the subprogram attached to a function.

@ LLVMGenericDINodeMetadataKind

struct LLVMOpaqueValue * LLVMValueRef

Represents an individual value in LLVM IR.

struct LLVMOpaqueDbgRecord * LLVMDbgRecordRef

struct LLVMOpaqueContext * LLVMContextRef

The top-level container for all LLVM global data.

struct LLVMOpaqueBasicBlock * LLVMBasicBlockRef

Represents a basic block of instructions in LLVM IR.

struct LLVMOpaqueMetadata * LLVMMetadataRef

Represents an LLVM Metadata.

struct LLVMOpaqueModule * LLVMModuleRef

The top-level container for all other LLVM Intermediate Representation (IR) objects.

struct LLVMOpaqueDIBuilder * LLVMDIBuilderRef

Represents an LLVM debug info builder.

#define llvm_unreachable(msg)

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

@ C

The default llvm calling convention, compatible with C.

Assignment Tracking (at).

void deleteAll(Function *F)

Remove all Assignment Tracking related intrinsics and metadata from F.

AssignmentInstRange getAssignmentInsts(DIAssignID *ID)

Return a range of instructions (typically just one) that have ID as an attachment.

AssignmentMarkerRange getAssignmentMarkers(DIAssignID *ID)

Return a range of dbg.assign intrinsics which use \ID as an operand.

void trackAssignments(Function::iterator Start, Function::iterator End, const StorageToVarsMap &Vars, const DataLayout &DL, bool DebugPrints=false)

Track assignments to Vars between Start and End.

void remapAssignID(DenseMap< DIAssignID *, DIAssignID * > &Map, Instruction &I)

Replace DIAssignID uses and attachments with IDs from Map.

SmallVector< DbgVariableRecord * > getDVRAssignmentMarkers(const Instruction *Inst)

void deleteAssignmentMarkers(const Instruction *Inst)

Delete the llvm.dbg.assign intrinsics linked to Inst.

std::optional< AssignmentInfo > getAssignmentInfo(const DataLayout &DL, const MemIntrinsic *I)

bool calculateFragmentIntersect(const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DbgAssign, std::optional< DIExpression::FragmentInfo > &Result)

Calculate the fragment of the variable in DAI covered from (Dest + SliceOffsetInBits) to to (Dest + S...

void RAUW(DIAssignID *Old, DIAssignID *New)

Replace all uses (and attachments) of Old with New.

Calculates the starting offsets for various sections within the .debug_names section.

void prune(LinkGraph &G)

Removes dead symbols/blocks/addressables.

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 drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

bool all_of(R &&range, UnaryPredicate P)

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

TinyPtrVector< DbgDeclareInst * > findDbgDeclares(Value *V)

Finds dbg.declare intrinsics declaring local variables as living in the memory that 'V' points to.

bool stripDebugInfo(Function &F)

void findDbgUsers(SmallVectorImpl< DbgVariableIntrinsic * > &DbgInsts, Value *V, SmallVectorImpl< DbgVariableRecord * > *DbgVariableRecords=nullptr)

Finds the debug info intrinsics describing a value.

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

Convenience function for iterating over sub-ranges.

@ Import

Import information from summary.

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

void findDbgValues(SmallVectorImpl< DbgValueInst * > &DbgValues, Value *V, SmallVectorImpl< DbgVariableRecord * > *DbgVariableRecords=nullptr)

Finds the llvm.dbg.value intrinsics describing a value.

bool any_of(R &&range, UnaryPredicate P)

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

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

bool stripNonLineTableDebugInfo(Module &M)

Downgrade the debug info in a module to contain only line table information.

DebugLoc getDebugValueLoc(DbgVariableIntrinsic *DII)

Produce a DebugLoc to use for each dbg.declare that is promoted to a dbg.value.

TinyPtrVector< DbgVariableRecord * > findDVRValues(Value *V)

As above, for DVRValues.

unsigned getDebugMetadataVersionFromModule(const Module &M)

Return Debug Info Metadata Version by checking module flags.

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

bool StripDebugInfo(Module &M)

Strip debug info in the module if it exists.

@ Ref

The access may reference the value stored in memory.

Attribute unwrap(LLVMAttributeRef Attr)

bool isAssignmentTrackingEnabled(const Module &M)

Return true if assignment tracking is enabled for module M.

auto count_if(R &&Range, UnaryPredicate P)

Wrapper function around std::count_if to count the number of times an element satisfying a given pred...

LLVMAttributeRef wrap(Attribute Attr)

TinyPtrVector< DbgVariableRecord * > findDVRDeclares(Value *V)

As above, for DVRDeclares.

static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)

Filter the DbgRecord range to DbgVariableRecord types only and downcast.

void updateLoopMetadataDebugLocations(Instruction &I, function_ref< Metadata *(Metadata *)> Updater)

Update the debug locations contained within the MD_loop metadata attached to the instruction I,...

DISubprogram * getDISubprogram(const MDNode *Scope)

Find subprogram that is enclosing this scope.

Helper object to track which of three possible relocation mechanisms are used for a particular value ...

Describes properties of a store that has a static size and offset into a some base storage.

Helper struct for trackAssignments, below.