LLVM: lib/DWARFLinker/Parallel/DependencyTracker.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

11

12using namespace llvm;

15

16

17

25

26

27

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

31 Worklist.push_back(CU.getOrigUnit().getUnitDIE());

32

33

35

36 while (!Worklist.empty()) {

39

41 continue;

42

47

50

52 CU.getDIEInfo(Child.getDebugInfoEntry());

55

56 if (!ParentPlainDieIsKept && ChildPlainDieIsKept)

58 "Found invalid link in keep chain");

59

60 if (Child.getTag() == dwarf::DW_TAG_subprogram) {

62 &CU, Child.getDebugInfoEntry()))) {

64 "Live subprogram is not marked as kept");

65 }

66 }

67

68 if (!ChildInfo.getODRAvailable()) {

69 assert(!ChildTypeDieIsKept);

70 continue;

71 }

72

73 if (!ParentTypeDieIsKept && ChildTypeDieIsKept)

75 "Found invalid link in keep chain");

76

77 if (CurrentInfo.getIsInAnonNamespaceScope() &&

80 "Found invalid placement marking for member "

81 "of anonymous namespace");

82 }

83 }

84 }

85

86 if (!BrokenLinks.empty()) {

88 errs() << "\n=================================\n";

90 Link.Parent.getOffset(),

91 Link.Child.getOffset());

92

93 errs() << "\nParent:";

94 Link.Parent.dump(errs(), 0, {});

95 errs() << "\n";

96 CU.getDIEInfo(Link.Parent).dump();

97

98 errs() << "\nChild:";

99 Link.Child.dump(errs(), 2, {});

100 errs() << "\n";

101 CU.getDIEInfo(Link.Child).dump();

102 }

104 }

105#endif

106}

107

109 bool InterCUProcessingStarted, std::atomic &HasNewInterconnectedCUs) {

111

112

116 std::nullopt, false);

117

118

120 HasNewInterconnectedCUs);

121}

122

125 std::optional ReferencedBy) {

126 if (ReferencedBy) {

128 return;

129 }

130

132}

133

135 const UnitEntryPairTy &Entry, std::optional ReferencedBy,

136 bool IsLiveParent) {

138 Entry.CU->getFirstChildEntry(Entry.DieEntry);

140 CurChild = Entry.CU->getSiblingEntry(CurChild)) {

143

144 bool IsLiveChild = false;

145

146 switch (CurChild->getTag()) {

147 case dwarf::DW_TAG_label: {

149

150

151

152 if (IsLiveChild || (IsLiveParent && ChildInfo.getHasAnAddress())) {

155 ReferencedBy);

156 }

157 } break;

158 case dwarf::DW_TAG_subprogram: {

160

161

162 if (IsLiveChild) {

163

164

166 (ChildInfo.getIsInMouduleScope() && ChildInfo.getODRAvailable())

169

171 }

172 } break;

173 case dwarf::DW_TAG_constant:

174 case dwarf::DW_TAG_variable: {

176

177

178 if (IsLiveChild) {

179

180

181

183 (ChildInfo.getIsInMouduleScope() && ChildInfo.getODRAvailable())

186

188 }

189 } break;

190 case dwarf::DW_TAG_base_type: {

191

194 ReferencedBy);

195 } break;

196 case dwarf::DW_TAG_imported_module:

197 case dwarf::DW_TAG_imported_declaration:

198 case dwarf::DW_TAG_imported_unit: {

199

200 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_compile_unit) {

203 ReferencedBy);

204 break;

205 }

206

209 ReferencedBy);

210 } break;

211 case dwarf::DW_TAG_type_unit:

212 case dwarf::DW_TAG_partial_unit:

213 case dwarf::DW_TAG_compile_unit: {

215 } break;

216 default:

217

218 break;

219 }

220

221 collectRootsToKeep(ChildEntry, ReferencedBy, IsLiveChild || IsLiveParent);

222 }

223}

224

226 bool InterCUProcessingStarted, std::atomic &HasNewInterconnectedCUs) {

227 bool Res = true;

228

229

232

234 Root.getRootEntry(), InterCUProcessingStarted,

235 HasNewInterconnectedCUs)) {

238 } else

239 Res = false;

240 }

241

242 return Res;

243}

244

246 bool HasNewDependency = false;

248 assert(Root.hasReferencedByOtherEntry() &&

249 "Root entry without dependency inside the dependencies list");

250

254

255 UnitEntryPairTy ReferencedByEntry = Root.getReferencedByEntry();

258

261 HasNewDependency = true;

263

264

265

266 }

267 }

268

269 return HasNewDependency;

270}

271

276 !Info.getKeepTypeChildren())

277 return;

278

280 Info.unsetKeepTypeChildren();

282

284 Entry.CU->getFirstChildEntry(Entry.DieEntry);

286 CurChild = Entry.CU->getSiblingEntry(CurChild))

288}

289

291 switch (Entry->getTag()) {

292 case dwarf::DW_TAG_compile_unit:

293 case dwarf::DW_TAG_module:

294 case dwarf::DW_TAG_namespace:

295 return true;

296

297 default:

298 return false;

299 }

300}

301

304 if (Info.getKeep())

305 return false;

306

307 switch (NewPlacement) {

309 return Info.needToPlaceInTypeTable();

310

312 return Info.needToKeepInPlainDwarf();

313

315 return Info.needToPlaceInTypeTable() && Info.needToKeepInPlainDwarf();

316

319 };

320

321 llvm_unreachable("Unknown CompileUnit::DieOutputPlacement enum");

322}

323

326 return isAlreadyMarked(Entry.CU->getDIEInfo(Entry.DieEntry), NewPlacement);

327}

328

331 if (Entry.DieEntry->getAbbreviationDeclarationPtr() == nullptr)

332 return;

333

336 bool NeedKeepPlainChildren = Info.needToKeepInPlainDwarf();

337

338 bool AreTypeParentsDone = !NeedKeepTypeChildren;

339 bool ArePlainParentsDone = !NeedKeepPlainChildren;

340

341

342 std::optional<uint32_t> ParentIdx = Entry.DieEntry->getParentIdx();

343 while (ParentIdx) {

345 Entry.CU->getDebugInfoEntry(*ParentIdx);

347

348 if (!AreTypeParentsDone && NeedKeepTypeChildren) {

349 if (ParentInfo.getKeepTypeChildren())

350 AreTypeParentsDone = true;

351 else {

354 ParentInfo.setKeepTypeChildren();

359 }

360 }

361 }

362

363 if (!ArePlainParentsDone && NeedKeepPlainChildren) {

364 if (ParentInfo.getKeepPlainChildren())

365 ArePlainParentsDone = true;

366 else {

369 ParentInfo.setKeepPlainChildren();

374 }

375 }

376 }

377

378 if (AreTypeParentsDone && ArePlainParentsDone)

379 break;

380

382 }

383}

384

385

386

387

388

389

395

396 if (!EntryInfo.getODRAvailable())

398

399 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_variable) {

400

401

405

408 }

409

410 switch (EntryInfo.getPlacement()) {

413

416

419

422 };

423

426}

427

430 const UnitEntryPairTy &Entry, bool InterCUProcessingStarted,

431 std::atomic &HasNewInterconnectedCUs) {

432 if (Entry.DieEntry->getAbbreviationDeclarationPtr() == nullptr)

433 return true;

434

436

437

439 Entry,

443 "Wrong kind of placement for ODR unavailable entry");

444

447 return true;

448

449

450 Info.setKeep();

452

453

455

457 Entry.DieEntry->getTag() == dwarf::DW_TAG_subprogram ? Entry : RootEntry;

458

459

460 bool Res = true;

462 InterCUProcessingStarted,

463 HasNewInterconnectedCUs))

464 Res = false;

465

466

467 if (isSingleAction(Action))

468 return Res;

469

470

471

472 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_subprogram &&

473 Info.getODRAvailable()) {

474

475

476

477

478

479

480

481

482

484 Entry.CU->getFirstChildEntry(Entry.DieEntry);

486 CurChild = Entry.CU->getSiblingEntry(CurChild)) {

488

489 switch (CurChild->getTag()) {

490 case dwarf::DW_TAG_variable:

491 case dwarf::DW_TAG_constant:

492 case dwarf::DW_TAG_subprogram:

493 case dwarf::DW_TAG_label: {

494 if (ChildInfo.getHasAnAddress())

495 continue;

496 } break;

497

498

499 case dwarf::DW_TAG_lexical_block:

500 case dwarf::DW_TAG_friend:

501 case dwarf::DW_TAG_inheritance:

502 case dwarf::DW_TAG_formal_parameter:

503 case dwarf::DW_TAG_unspecified_parameters:

504 case dwarf::DW_TAG_template_type_parameter:

505 case dwarf::DW_TAG_template_value_parameter:

506 case dwarf::DW_TAG_GNU_template_parameter_pack:

507 case dwarf::DW_TAG_GNU_formal_parameter_pack:

508 case dwarf::DW_TAG_GNU_template_template_param:

509 case dwarf::DW_TAG_thrown_type: {

510

511 } break;

512

513 default: {

515

516

517 if (isLiveAction(Action) && ChildIsTypeTableCandidate)

518 continue;

519

520

521 if (isTypeAction(Action) && !ChildIsTypeTableCandidate)

522 continue;

523

524

525 } break;

526 }

527

529 Action, FinalRootEntry, UnitEntryPairTy{Entry.CU, CurChild},

530 InterCUProcessingStarted, HasNewInterconnectedCUs))

531 Res = false;

532 }

533

534 return Res;

535 }

536

537

539 Entry.CU->getFirstChildEntry(Entry.DieEntry);

541 CurChild = Entry.CU->getSiblingEntry(CurChild)) {

543 switch (CurChild->getTag()) {

544 case dwarf::DW_TAG_variable:

545 case dwarf::DW_TAG_constant:

546 case dwarf::DW_TAG_subprogram:

547 case dwarf::DW_TAG_label: {

548 if (ChildInfo.getHasAnAddress())

549 continue;

550 } break;

551 default:

552 break;

553 };

554

556 Action, FinalRootEntry, UnitEntryPairTy{Entry.CU, CurChild},

557 InterCUProcessingStarted, HasNewInterconnectedCUs))

558 Res = false;

559 }

560

561 return Res;

562}

563

566 switch (DIEEntry->getTag()) {

567 default:

568 return false;

569

570 case dwarf::DW_TAG_imported_module:

571 case dwarf::DW_TAG_imported_declaration:

572 case dwarf::DW_TAG_imported_unit:

573 case dwarf::DW_TAG_array_type:

574 case dwarf::DW_TAG_class_type:

575 case dwarf::DW_TAG_enumeration_type:

576 case dwarf::DW_TAG_pointer_type:

577 case dwarf::DW_TAG_reference_type:

578 case dwarf::DW_TAG_string_type:

579 case dwarf::DW_TAG_structure_type:

580 case dwarf::DW_TAG_subroutine_type:

581 case dwarf::DW_TAG_typedef:

582 case dwarf::DW_TAG_union_type:

583 case dwarf::DW_TAG_variant:

584 case dwarf::DW_TAG_module:

585 case dwarf::DW_TAG_ptr_to_member_type:

586 case dwarf::DW_TAG_set_type:

587 case dwarf::DW_TAG_subrange_type:

588 case dwarf::DW_TAG_base_type:

589 case dwarf::DW_TAG_const_type:

590 case dwarf::DW_TAG_enumerator:

591 case dwarf::DW_TAG_file_type:

592 case dwarf::DW_TAG_packed_type:

593 case dwarf::DW_TAG_thrown_type:

594 case dwarf::DW_TAG_volatile_type:

595 case dwarf::DW_TAG_dwarf_procedure:

596 case dwarf::DW_TAG_restrict_type:

597 case dwarf::DW_TAG_interface_type:

598 case dwarf::DW_TAG_namespace:

599 case dwarf::DW_TAG_unspecified_type:

600 case dwarf::DW_TAG_shared_type:

601 case dwarf::DW_TAG_rvalue_reference_type:

602 case dwarf::DW_TAG_coarray_type:

603 case dwarf::DW_TAG_dynamic_type:

604 case dwarf::DW_TAG_atomic_type:

605 case dwarf::DW_TAG_immutable_type:

606 case dwarf::DW_TAG_function_template:

607 case dwarf::DW_TAG_class_template:

608 return true;

609 }

610}

611

614 const UnitEntryPairTy &Entry, bool InterCUProcessingStarted,

615 std::atomic &HasNewInterconnectedCUs) {

616 const auto *Abbrev = Entry.DieEntry->getAbbreviationDeclarationPtr();

617 if (Abbrev == nullptr)

618 return true;

619

620 DWARFUnit &Unit = Entry.CU->getOrigUnit();

623 Entry.DieEntry->getOffset() + getULEB128Size(Abbrev->getCode());

624

625

626 for (const auto &AttrSpec : Abbrev->attributes()) {

629 AttrSpec.Attr == dwarf::DW_AT_sibling) {

631 Unit.getFormParams());

632 continue;

633 }

635

636

637 std::optional RefDie = Entry.CU->resolveDIEReference(

638 Val, InterCUProcessingStarted

641 if (!RefDie) {

642 Entry.CU->warn("cann't find referenced DIE", Entry.DieEntry);

643 continue;

644 }

645

646 if (!RefDie->DieEntry) {

647

648 RefDie->CU->setInterconnectedCU();

649 Entry.CU->setInterconnectedCU();

650 HasNewInterconnectedCUs = true;

651 return false;

652 }

653

654 assert((Entry.CU->getUniqueID() == RefDie->CU->getUniqueID() ||

655 InterCUProcessingStarted) &&

656 "Inter-CU reference while inter-CU processing is not started");

657

659 if (!RefInfo.getODRAvailable())

661 else if (RefInfo.getODRAvailable() &&

663

664

665

669 else

671

672 if (AttrSpec.Attr == dwarf::DW_AT_import) {

678 *RefDie, RootEntry);

679 continue;

680 }

681

683 continue;

684 }

685

688 }

689

690 return true;

691}

692

696

697 do {

698 switch (Entry.DieEntry->getTag()) {

699 case dwarf::DW_TAG_subprogram:

700 case dwarf::DW_TAG_label:

701 case dwarf::DW_TAG_variable:

702 case dwarf::DW_TAG_constant: {

703 return Result;

704 } break;

705

706 default: {

707

708 }

709 }

710

711 std::optional<uint32_t> ParentIdx = Result.DieEntry->getParentIdx();

712 if (!ParentIdx)

713 return Result;

714

716 Result.CU->getDebugInfoEntry(*ParentIdx);

718 break;

719 Result.DieEntry = ParentEntry;

720 } while (true);

721

722 return Result;

723}

724

726 bool IsLiveParent) {

727 DWARFDie DIE = Entry.CU->getDIE(Entry.DieEntry);

729

730 if (Info.getTrackLiveness()) {

731 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();

732

733 if (!Info.getIsInFunctionScope() &&

734 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) {

735

736 } else {

737

738

739

740

741

742 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =

743 Entry.CU->getContaingFile().Addresses->getVariableRelocAdjustment(

744 DIE, Entry.CU->getGlobalData().getOptions().Verbose);

745

746 if (LocExprAddrAndRelocAdjustment.first)

747 Info.setHasAnAddress();

748

749 if (!LocExprAddrAndRelocAdjustment.second)

750 return false;

751

752 if (!IsLiveParent && Info.getIsInFunctionScope() &&

753 !Entry.CU->getGlobalData().getOptions().KeepFunctionForStatic)

754 return false;

755 }

756 }

757 Info.setHasAnAddress();

758

759 if (Entry.CU->getGlobalData().getOptions().Verbose) {

760 outs() << "Keeping variable DIE:";

763 DumpOpts.Verbose = Entry.CU->getGlobalData().getOptions().Verbose;

764 DIE.dump(outs(), 8 , DumpOpts);

765 }

766

767 return true;

768}

769

771 DWARFDie DIE = Entry.CU->getDIE(Entry.DieEntry);

773 std::optional LowPCVal = DIE.find(dwarf::DW_AT_low_pc);

774

775 std::optional<uint64_t> LowPc;

776 std::optional<uint64_t> HighPc;

777 std::optional<int64_t> RelocAdjustment;

778 if (Info.getTrackLiveness()) {

780 if (!LowPc)

781 return false;

782

783 Info.setHasAnAddress();

784

785 RelocAdjustment =

786 Entry.CU->getContaingFile().Addresses->getSubprogramRelocAdjustment(

787 DIE, Entry.CU->getGlobalData().getOptions().Verbose);

788 if (!RelocAdjustment)

789 return false;

790

791 if (DIE.getTag() == dwarf::DW_TAG_subprogram) {

792

793

794 HighPc = DIE.getHighPC(*LowPc);

795 if (!HighPc) {

796 Entry.CU->warn("function without high_pc. Range will be discarded.",

798 return false;

799 }

800

801 if (*LowPc > *HighPc) {

802 Entry.CU->warn("low_pc greater than high_pc. Range will be discarded.",

804 return false;

805 }

806 } else if (DIE.getTag() == dwarf::DW_TAG_label) {

807 if (Entry.CU->hasLabelAt(*LowPc))

808 return false;

809

810

811

812

813

814

815 if (dwarf::toAddress(Entry.CU->find(Entry.DieEntry, dwarf::DW_AT_high_pc))

817 return false;

818

819 Entry.CU->addLabelLowPc(*LowPc, *RelocAdjustment);

820 }

821 } else

822 Info.setHasAnAddress();

823

824 if (Entry.CU->getGlobalData().getOptions().Verbose) {

825 outs() << "Keeping subprogram DIE:";

828 DumpOpts.Verbose = Entry.CU->getGlobalData().getOptions().Verbose;

829 DIE.dump(outs(), 8 , DumpOpts);

830 }

831

832 if (!Info.getTrackLiveness() || DIE.getTag() == dwarf::DW_TAG_label)

833 return true;

834

835 Entry.CU->addFunctionRange(*LowPc, *HighPc, *RelocAdjustment);

836 return true;

837}

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

Analysis containing CSE Info

bool isAlreadyMarked(const CompileUnit::DIEInfo &Info, CompileUnit::DieOutputPlacement NewPlacement)

Definition DependencyTracker.cpp:302

static bool isNamespaceLikeEntry(const DWARFDebugInfoEntry *Entry)

Definition DependencyTracker.cpp:290

static CompileUnit::DieOutputPlacement getFinalPlacementForEntry(const UnitEntryPairTy &Entry, CompileUnit::DieOutputPlacement Placement)

Definition DependencyTracker.cpp:391

Branch Probability Basic Block Placement

A pointer to another debug information entry.

A structured debug information entry.

dwarf::Tag getTag() const

LLVM_ABI void dump() const

DWARFDebugInfoEntry - A DIE with only the minimum required data.

dwarf::Tag getTag() const

std::optional< uint32_t > getParentIdx() const

Returns index of the parent die.

const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const

Utility class that carries the DWARF compile/type unit and the debug info entry in an object.

iterator_range< iterator > children() const

const DWARFDebugInfoEntry * getDebugInfoEntry() const

LLVM_ABI bool isFormClass(FormClass FC) const

LLVM_ABI bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context=nullptr, const DWARFUnit *Unit=nullptr)

Extracts a value in Data at offset *OffsetPtr.

bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const

Skip a form's value in DebugInfoData at the offset specified by OffsetPtr.

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

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

static LLVM_ABI raw_ostream & error()

Convenience method for printing "error: " to stderr.

DieOutputPlacement

Kinds of placement for the output die.

@ Both

Corresponding DIE goes to type table and to plain dwarf.

@ TypeTable

Corresponding DIE goes to the type table only.

@ PlainDwarf

Corresponding DIE goes to the plain dwarf only.

Class keeping live worklist item data.

UnitEntryPairTy getRootEntry() const

LiveRootWorklistActionTy getAction() const

bool hasReferencedByOtherEntry() const

void verifyKeepChain()

Recursively walk the DIE tree and check "keepness" and "placement" information.

Definition DependencyTracker.cpp:28

RootEntriesListTy Dependencies

List of entries dependencies.

void markParentsAsKeepingChildren(const UnitEntryPairTy &Entry)

Mark parents as keeping children.

Definition DependencyTracker.cpp:329

UnitEntryPairTy getRootForSpecifiedEntry(UnitEntryPairTy Entry)

Definition DependencyTracker.cpp:694

bool markCollectedLiveRootsAsKept(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)

Examine worklist and mark all 'root DIE's as kept and set "Placement" property.

Definition DependencyTracker.cpp:225

bool maybeAddReferencedRoots(LiveRootWorklistActionTy Action, const UnitEntryPairTy &RootEntry, const UnitEntryPairTy &Entry, bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)

Check referenced DIEs and add them into the worklist.

Definition DependencyTracker.cpp:612

bool isLiveAction(LiveRootWorklistActionTy Action)

bool isChildrenAction(LiveRootWorklistActionTy Action)

bool isTypeAction(LiveRootWorklistActionTy Action)

bool markDIEEntryAsKeptRec(LiveRootWorklistActionTy Action, const UnitEntryPairTy &RootEntry, const UnitEntryPairTy &Entry, bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)

Mark whole DIE tree as kept recursively.

Definition DependencyTracker.cpp:428

bool isTypeTableCandidate(const DWARFDebugInfoEntry *DIEEntry)

Definition DependencyTracker.cpp:564

void setPlainDwarfPlacementRec(const UnitEntryPairTy &Entry)

Mark whole DIE tree as placed in "PlainDwarf".

Definition DependencyTracker.cpp:272

RootEntriesListTy RootEntriesWorkList

List of entries which are 'root DIE's.

void addActionToRootEntriesWorkList(LiveRootWorklistActionTy Action, const UnitEntryPairTy &Entry, std::optional< UnitEntryPairTy > ReferencedBy)

Add action item to the work list.

Definition DependencyTracker.cpp:123

static bool isLiveSubprogramEntry(const UnitEntryPairTy &Entry)

Returns true if specified subprogram references live code section.

Definition DependencyTracker.cpp:770

bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)

Recursively walk the DIE tree and look for DIEs to keep.

Definition DependencyTracker.cpp:108

static bool isLiveVariableEntry(const UnitEntryPairTy &Entry, bool IsLiveParent)

Returns true if specified variable references live code section.

Definition DependencyTracker.cpp:725

@ MarkSingleTypeEntry

Mark current item as type entry.

@ MarkSingleLiveEntry

Mark current item as live entry.

@ MarkTypeEntryRec

Mark current item and all its children as type entry.

@ MarkLiveChildrenRec

Mark all children of current item as live entry.

@ MarkLiveEntryRec

Mark current item and all its children as live entry.

@ MarkTypeChildrenRec

Mark all children of current item as type entry.

void collectRootsToKeep(const UnitEntryPairTy &Entry, std::optional< UnitEntryPairTy > ReferencedBy, bool IsLiveParent)

This function navigates DIEs tree starting from specified Entry.

Definition DependencyTracker.cpp:134

bool updateDependenciesCompleteness()

Check if dependencies have incompatible placement.

Definition DependencyTracker.cpp:245

DIEInfo & getDIEInfo(unsigned Idx)

Idx index of the DIE.

#define llvm_unreachable(msg)

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

ArrayRef< dwarf::Attribute > getODRAttributes()

std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)

Take an optional DWARFFormValue and try to extract an address.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI raw_fd_ostream & outs()

This returns a reference to a raw_fd_ostream for standard output.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

auto reverse(ContainerTy &&C)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

LLVM_ABI unsigned getULEB128Size(uint64_t Value)

Utility function to get the size of the ULEB128-encoded value.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

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

Returns true if Element is found in Range.

std::string Message

Definition DependencyTracker.cpp:23

DWARFDie Parent

Definition DependencyTracker.cpp:21

BrokenLink(DWARFDie Parent, DWARFDie Child, const char *Message)

Definition DependencyTracker.cpp:19

DWARFDie Child

Definition DependencyTracker.cpp:22

A broken link in the keep chain.

Container for dump options that control which debug information will be dumped.

unsigned ChildRecurseDepth

Information gathered about a DIE in the object file.

Information gathered about source DIEs.

void setPlacement(DieOutputPlacement Placement)

Sets Placement kind for the corresponding die.

bool needToKeepInPlainDwarf() const

bool needToPlaceInTypeTable() const

This is a helper structure which keeps a debug info entry with it's containing compilation unit.

const DWARFDebugInfoEntry * DieEntry