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