9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
10#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
42 std::optional<UnitEntryPairTy>
getParent();
168 bool InterCUProcessingStarted,
169 std::atomic<bool> &HasNewInterconnectedCUs);
214 auto InputData =
Flags.load();
215 while (!
Flags.compare_exchange_weak(InputData,
222 auto InputData =
Flags.load();
223 while (!
Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) {
229 auto InputData =
Flags.load();
230 if ((InputData & 0x7) ==
NotSet)
231 if (
Flags.compare_exchange_strong(InputData, (InputData |
Placement)))
243 auto InputData =
Flags.load();
244 while (!
Flags.compare_exchange_weak(InputData, (InputData |
Placement))) {
255 auto InputData =
Flags.load();
263 Desired = (InputData & ~0x7) | Joined;
264 }
while (!
Flags.compare_exchange_weak(InputData, Desired));
267#define SINGLE_FLAG_METHODS_SET(Name, Value) \
268 bool get##Name() const { return Flags & Value; } \
270 auto InputData = Flags.load(); \
271 while (!Flags.compare_exchange_weak(InputData, InputData | Value)) { \
274 void unset##Name() { \
275 auto InputData = Flags.load(); \
276 while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) { \
308 auto InputData =
Flags.load();
309 while (!
Flags.compare_exchange_weak(
310 InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) {
317#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
324 getKeepTypeChildren();
330 getKeepPlainChildren();
373 return reinterpret_cast<std::atomic<uint64_t> *
>(&OutDieOffsetArray[Idx])
380 return reinterpret_cast<std::atomic<TypeEntry *> *
>(&TypeEntries[Idx])
387 return reinterpret_cast<std::atomic<uint64_t> *
>(
395 return reinterpret_cast<std::atomic<TypeEntry *> *
>(
403 reinterpret_cast<std::atomic<uint64_t> *
>(&OutDieOffsetArray[Idx])
410 reinterpret_cast<std::atomic<TypeEntry *> *
>(&TypeEntries[Idx])
418 reinterpret_cast<std::atomic<TypeEntry *> *
>(
426 std::optional<uint64_t>
getLowPc()
const {
return LowPc; }
442 std::optional<UnitEntryPairTy>
446 std::optional<UnitEntryPairTy>
469 StmtSeqListAttributes.push_back({V, InputStmtSeqOffset});
474 cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,
488 std::pair<DIE *, TypeEntry *>
491 std::optional<int64_t> FuncAddressAdjustment,
492 std::optional<int64_t> VarAddressAdjustment,
494 uint32_t SiblingOrdinal = std::numeric_limits<uint32_t>::max());
503 std::optional<int64_t> VarAddressAdjustment,
508 return DebugAddrIndexMap.getValueIndex(Addr);
512 std::optional<std::pair<StringRef, StringRef>>
516 std::optional<std::pair<StringRef, StringRef>>
525 assert(OrigUnit !=
nullptr);
531 assert(OrigUnit !=
nullptr);
532 return OrigUnit->getFirstChildEntry(Die);
537 assert(OrigUnit !=
nullptr);
538 return OrigUnit->getSiblingEntry(Die);
542 assert(OrigUnit !=
nullptr);
543 return OrigUnit->getParent(Die);
547 assert(OrigUnit !=
nullptr);
548 return OrigUnit->getDIEAtIndex(Index);
552 assert(OrigUnit !=
nullptr);
553 return OrigUnit->getDebugInfoEntry(Index);
557 assert(OrigUnit !=
nullptr);
558 return OrigUnit->getUnitDIE(ExtractUnitDIEOnly);
562 assert(OrigUnit !=
nullptr);
567 assert(OrigUnit !=
nullptr);
568 return OrigUnit->getDIEIndex(Die);
572 assert(OrigUnit !=
nullptr);
573 return OrigUnit->getDIEIndex(Die);
578 assert(OrigUnit !=
nullptr);
579 return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs);
588 for (
auto Attr : Attrs) {
589 if (
auto Value = AbbrevDecl->getAttributeValue(Die->
getOffset(), Attr,
598 return OrigUnit->getDIEIndexForOffset(
Offset);
618 if (DieEntry !=
nullptr) {
641 AcceleratorRecords.add(Info);
647 AcceleratorRecords.forEach(Handler);
676 bool IsODRUnavailableFunctionScope);
678 struct LinkedLocationExpressionsWithOffsetPatches {
682 using LinkedLocationExpressionsVector =
693 const LinkedLocationExpressionsVector &LinkedLocationExpression,
697 Error emitDebugAddrSection();
710 void emitRangeListFragment(
const AddressRanges &LinkedRanges,
720 std::vector<DWARFDebugLine::Row> &Rows,
730 std::vector<DWARFDebugLine::Row> &NewRows,
742 void patchStmtSeqAttributes(
758 uint64_t OffsetToMacroTable,
bool hasDWARFv5Header);
761 DIE *createPlainDIEandCloneAttributes(
763 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
764 std::optional<int64_t> &VarAddressAdjustment);
768 TypeEntry *createTypeDIEandCloneAttributes(
776 bool IsDeclaration,
bool IsParentDeclaration);
789 std::optional<uint16_t> Language;
793 struct PendingSwiftInterface {
797 std::string ResolvedPath;
807 ResolvedPathsMap ResolvedFullPaths;
813 std::unique_ptr<DependencyTracker> Dependencies;
820 std::optional<uint64_t> LowPc;
827 uint64_t Priority = std::numeric_limits<uint64_t>::max();
833 std::mutex RangesMutex;
845 struct StmtSeqPatch {
849 SmallVector<StmtSeqPatch, 4> StmtSeqListAttributes;
850 std::mutex LabelsMutex;
853 std::atomic<Stage>
Stage;
857 SmallVector<uint64_t> OutDieOffsetArray;
861 ArrayList<AccelInfo> AcceleratorRecords;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Branch Probability Basic Block Placement
The AddressRanges class helps normalize address range collections.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A structured debug information entry.
DWARFDebugInfoEntry - A DIE with only the minimum required data.
uint64_t getOffset() const
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
Return the index of a Die entry inside the unit's DIE vector.
Base class for error info classes.
Lightweight error class with error context and mandatory checking.
Class representing an expression and its matching format.
A discriminated union of two or more pointer types, with the discriminator in the low bits of the poi...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
This class represents DWARF information for source file and it's address map.
std::map< std::string, std::string > SwiftInterfacesMapTy
This class stores values sequentually and assigns index to the each value.
TypeUnit * getAsTypeUnit()
Returns TypeUnit if applicable.
DwarfUnit * operator->()
Accessor for common functionality.
PointerUnion< CompileUnit *, TypeUnit * > Ptr
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
OutputUnitVariantPtr(CompileUnit *U)
Stores all information related to a compile unit, be it in its original instance of the object file o...
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset)
Add the low_pc of a label that is relocated by applying offset PCOffset.
Error cloneAndEmitDebugLocations()
Clone and emit debug locations(.debug_loc/.debug_loclists).
void cloneDieAttrExpression(const DWARFExpression &InputExpression, SmallVectorImpl< uint8_t > &OutputExpression, SectionDescriptor &Section, std::optional< int64_t > VarAddressAdjustment, OffsetsPtrVector &PatchesOffsets)
Clone attribute location axpression.
void maybeResetToLoadedStage()
Reset compile units data(results of liveness analysis, clonning) if current stage greater than Stage:...
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset)
Add a function range [LowPC, HighPC) that is relocated by applying offset PCOffset.
void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry)
Collect references to parseable Swift interfaces in imported DW_TAG_module blocks.
std::pair< DIE *, TypeEntry * > cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset, std::optional< int64_t > FuncAddressAdjustment, std::optional< int64_t > VarAddressAdjustment, BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit, uint32_t SiblingOrdinal=std::numeric_limits< uint32_t >::max())
void cleanupDataAfterClonning()
Cleanup unneeded resources after compile unit is cloned.
Error assignTypeNames(TypePool &TypePoolRef)
Search for type entries and assign names.
llvm::Error setPriority(uint64_t ObjFileIdx, uint64_t LocalIdx)
Set deterministic priority for type DIE allocation ordering.
uint64_t getHighPc() const
Returns value of DW_AT_high_pc attribute.
void noteModuleAnchors()
Must run while the output offsets are still available, and once they are final.
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.
Error cloneAndEmitLineTable(const Triple &TargetTriple)
const DWARFFile & getContainingFile() const
Returns DWARFFile containing this compile unit.
void analyzeDWARFStructure()
Navigate DWARF tree and set die properties.
Error cloneAndEmitRanges()
Clone and emit ranges.
void mergeSwiftInterfaces(DWARFLinkerBase::SwiftInterfacesMapTy &Map)
Merge the Swift interface entries collected by analyzeImportedModule into Map, emitting a warning for...
void updateDieRefPatchesWithClonedOffsets()
After cloning stage the output DIEs offsets are deallocated.
uint64_t getDebugAddrIndex(uint64_t Addr)
Returns index(inside .debug_addr) of an address.
bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Search for subprograms and variables referencing live code and discover dependend DIEs.
std::optional< uint16_t > getLanguage() const
Returns raw DW_AT_language of the input compile unit.
bool hasLabelAt(uint64_t Addr) const
Returns true if there is a label corresponding to the specified Addr.
bool updateDependenciesCompleteness()
Check dependend DIEs for incompatible placement.
bool loadInputDIEs()
Load DIEs of input compilation unit.
void noteStmtSeqListAttribute(DIEValue *V, uint64_t InputStmtSeqOffset)
Record that a DW_AT_LLVM_stmt_sequence attribute on this unit references the input line-table sequenc...
const RangesTy & getFunctionRanges() const
Returns function ranges of this unit.
void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info)
Save specified accelerator info Info.
Error cloneAndEmitDebugMacro()
Clone and emit debug macros(.debug_macinfo/.debug_macro).
Error cloneAndEmit(std::optional< std::reference_wrapper< const Triple > > TargetTriple, TypeUnit *ArtificialTypeUnit)
Clone and emit this compilation unit.
void setStage(Stage Stage)
Set stage of overall processing.
Stage getStage() const
Returns stage of overall processing.
CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName, DWARFFile &File, OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, llvm::endianness Endianess)
void verifyDependencies()
Check DIEs to have a consistent marking(keep marking, placement marking).
Stage
The stages of new compile unit processing.
@ Cloned
Output DWARF is generated.
@ TypeNamesAssigned
Type names assigned to DIEs.
@ CreatedNotLoaded
Created, linked with input DWARF file.
@ PatchesUpdated
Offsets inside patch records are updated.
@ Cleaned
Resources(Input DWARF, Output DWARF tree) are released.
@ Loaded
Input DWARF is loaded.
@ LivenessAnalysisDone
Input DWARF is analysed(DIEs pointing to the real code section arediscovered, type names are assigned...
@ UpdateDependenciesCompleteness
Check if dependencies have incompatible placement.
@ Skipped
Compile Unit should be skipped.
void forEachAcceleratorRecord(function_ref< void(AccelInfo &)> Handler) override
Enumerates all units accelerator records.
std::optional< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
void loadLineTable()
Loads unit line table.
bool getModulePath(const DWARFDebugInfoEntry *DieEntry, SmallVectorImpl< char > &Path)
Appends the names of the DW_TAG_module enclosing DieEntry, outermost first.
uint64_t getPriority() const
StringEntry * getFileName(unsigned FileIdx, StringPool &GlobalStrings)
Returns name of the file for the FileIdx from the unit`s line table.
This class is a helper to create output DIE tree.
This class discovers DIEs dependencies: marks "live" DIEs, marks DIE locations (whether DIE should be...
StringRef getUnitName() const
Returns this unit name.
DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName)
std::string ClangModuleName
If this is a Clang module, this holds the module's name.
This class keeps data and services common for the whole linking process.
LinkingGlobalData & GlobalData
The helper class to build type name based on DIE properties.
Keeps cloned data for the type DIE.
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
An efficient, type-erasing, non-owning reference to a callable.
uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry)
InputDieEntry debug info entry.
void rememberDieOutOffset(uint32_t Idx, uint64_t Offset)
Idx index of the DIE.
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
const DIEInfo & getDIEInfo(const DWARFDebugInfoEntry *Entry) const
Idx index of the DIE.
uint64_t getDieOutOffset(uint32_t Idx)
Idx index of the DIE.
const DIEInfo & getDIEInfo(const DWARFDie &Die) const
Die
const DIEInfo & getDIEInfo(unsigned Idx) const
Idx index of the DIE.
DIEInfo & getDIEInfo(const DWARFDebugInfoEntry *Entry)
Idx index of the DIE.
TypeEntry * getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry)
InputDieEntry debug info entry.
void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *Entry)
InputDieEntry debug info entry.
void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry)
Idx index of the DIE.
DIEInfo & getDIEInfo(const DWARFDie &Die)
Die
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
DWARFDie getDIEAtIndex(unsigned Index)
DWARFDie getDIE(const DWARFDebugInfoEntry *Die)
std::optional< DWARFFormValue > find(const DWARFDebugInfoEntry *Die, ArrayRef< dwarf::Attribute > Attrs) const
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
uint32_t getDIEIndex(const DWARFDie &Die) const
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
void error(Error Err, const DWARFDie *DIE=nullptr)
void warn(Error Warning, const DWARFDie *DIE=nullptr)
void warn(const Twine &Warning, const DWARFDie *DIE=nullptr)
void error(const Twine &Err, const DWARFDie *DIE=nullptr)
void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry)
#define SINGLE_FLAG_METHODS_SET(Name, Value)
function_ref< CompileUnit *(uint64_t Offset)> OffsetToUnitTy
SmallVector< uint64_t * > OffsetsPtrVector
Type for list of pointers to patches offsets.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
ArrayRef< dwarf::Attribute > getODRAttributes()
ResolveInterCUReferencesMode
DebugSectionKind
List of tracked debug tables.
LLVM_ABI void buildStmtSeqOffsetToFirstRowIndex(const DWARFDebugLine::LineTable <, ArrayRef< uint64_t > SortedStmtSeqOffsets, DenseMap< uint64_t, uint64_t > &SeqOffToFirstRow)
Build a map from an input DW_AT_LLVM_stmt_sequence byte offset to the first-row index (in LT....
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
AddressRangesMap RangesTy
Mapped value in the address map is the offset to apply to the linked address.
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
static void insertLineSequence(std::vector< TrackedRow > &Seq, std::vector< TrackedRow > &Rows)
Insert the new line info sequence Seq into the current set of already linked line info Rows.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ArrayRef(const T &OneElt) -> ArrayRef< T >
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
@ Keep
No function return thunk.
Represents a single DWARF expression, whose value is location-dependent.
Information gathered and exchanged between the various clone*Attr helpers about the attributes of a p...
Information gathered about source DIEs.
LLVM_DUMP_METHOD void dump()
void setPlacement(DieOutputPlacement Placement)
Sets Placement kind for the corresponding die.
bool needToKeepInPlainDwarf() const
std::atomic< uint16_t > Flags
Data member keeping various flags.
bool needToPlaceInTypeTable() const
void joinVariablePlacement(DieOutputPlacement Placement)
Atomically joins Placement for a DW_TAG_variable, for which PlainDwarf is absorbing because a variabl...
DieOutputPlacement getPlacement() const
void unsetPlacement()
Unsets Placement kind for the corresponding die.
bool setPlacementIfUnset(DieOutputPlacement Placement)
Sets Placement kind for the corresponding die.
DIEInfo & operator=(const DIEInfo &Other)
void joinPlacement(DieOutputPlacement Placement)
Atomically joins Placement into the current placement: the least-upper-bound of the lattice NotSet < ...
void unsetFlagsWhichSetDuringLiveAnalysis()
DIE is a part of the linked output.
DIEInfo(const DIEInfo &Other)
void eraseData()
Erase all flags.
This structure keeps fields which would be used for creating accelerator table.
This structure is used to keep data of the concrete section.
UnitEntryPairTy()=default
UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry)
std::optional< UnitEntryPairTy > getParent()
UnitEntryPairTy getNamespaceOrigin()
const DWARFDebugInfoEntry * DieEntry