diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
download | src-06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e.tar.gz src-06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e.zip |
Merge llvm-project main llvmorg-17-init-19304-gd0b54bb50e51
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvm-project main llvmorg-17-init-19304-gd0b54bb50e51, the
last commit before the upstream release/17.x branch was created.
PR: 273753
MFC after: 1 month
Diffstat (limited to 'contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h')
-rw-r--r-- | contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h | 215 |
1 files changed, 149 insertions, 66 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h index 0f0fa6cae316..568c9cf87f80 100644 --- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h +++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h @@ -16,9 +16,10 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" +#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h" #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryStreamReader.h" @@ -28,6 +29,8 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/TargetParser/SubtargetFeature.h" +#include "llvm/TargetParser/Triple.h" #include <optional> #include <map> @@ -163,7 +166,7 @@ private: assert(AlignmentOffset <= MaxAlignmentOffset && "Alignment offset exceeds maximum"); ContentMutable = false; - P2Align = Alignment ? countTrailingZeros(Alignment) : 0; + P2Align = Alignment ? llvm::countr_zero(Alignment) : 0; this->AlignmentOffset = AlignmentOffset; } @@ -180,7 +183,7 @@ private: assert(AlignmentOffset <= MaxAlignmentOffset && "Alignment offset exceeds maximum"); ContentMutable = false; - P2Align = Alignment ? countTrailingZeros(Alignment) : 0; + P2Align = Alignment ? llvm::countr_zero(Alignment) : 0; this->AlignmentOffset = AlignmentOffset; } @@ -199,7 +202,7 @@ private: assert(AlignmentOffset <= MaxAlignmentOffset && "Alignment offset exceeds maximum"); ContentMutable = true; - P2Align = Alignment ? countTrailingZeros(Alignment) : 0; + P2Align = Alignment ? llvm::countr_zero(Alignment) : 0; this->AlignmentOffset = AlignmentOffset; } @@ -289,7 +292,7 @@ public: /// Set the alignment for this content. void setAlignment(uint64_t Alignment) { assert(isPowerOf2_64(Alignment) && "Alignment must be a power of two"); - P2Align = Alignment ? countTrailingZeros(Alignment) : 0; + P2Align = Alignment ? llvm::countr_zero(Alignment) : 0; } /// Get the alignment offset for this content. @@ -352,23 +355,30 @@ private: }; // Align an address to conform with block alignment requirements. -inline uint64_t alignToBlock(uint64_t Addr, Block &B) { +inline uint64_t alignToBlock(uint64_t Addr, const Block &B) { uint64_t Delta = (B.getAlignmentOffset() - Addr) % B.getAlignment(); return Addr + Delta; } // Align a orc::ExecutorAddr to conform with block alignment requirements. -inline orc::ExecutorAddr alignToBlock(orc::ExecutorAddr Addr, Block &B) { +inline orc::ExecutorAddr alignToBlock(orc::ExecutorAddr Addr, const Block &B) { return orc::ExecutorAddr(alignToBlock(Addr.getValue(), B)); } -/// Describes symbol linkage. This can be used to make resolve definition -/// clashes. +// Returns true if the given blocks contains exactly one valid c-string. +// Zero-fill blocks of size 1 count as valid empty strings. Content blocks +// must end with a zero, and contain no zeros before the end. +bool isCStringBlock(Block &B); + +/// Describes symbol linkage. This can be used to resolve definition clashes. enum class Linkage : uint8_t { Strong, Weak, }; +/// Holds target-specific properties for a symbol. +using TargetFlagsType = uint8_t; + /// For errors and debugging output. const char *getLinkageName(Linkage L); @@ -413,6 +423,7 @@ private: setScope(S); setLive(IsLive); setCallable(IsCallable); + setTargetFlags(TargetFlagsType{}); } static Symbol &constructExternal(BumpPtrAllocator &Allocator, @@ -553,6 +564,11 @@ public: /// Returns the offset for this symbol within the underlying addressable. orc::ExecutorAddrDiff getOffset() const { return Offset; } + void setOffset(orc::ExecutorAddrDiff NewOffset) { + assert(NewOffset < getBlock().getSize() && "Offset out of range"); + Offset = NewOffset; + } + /// Returns the address of this symbol. orc::ExecutorAddr getAddress() const { return Base->getAddress() + Offset; } @@ -606,6 +622,17 @@ public: this->S = static_cast<uint8_t>(S); } + /// Check wehther the given target flags are set for this Symbol. + bool hasTargetFlags(TargetFlagsType Flags) const { + return static_cast<TargetFlagsType>(TargetFlags) & Flags; + } + + /// Set the target flags for this Symbol. + void setTargetFlags(TargetFlagsType Flags) { + assert(Flags <= 1 && "Add more bits to store more than single flag"); + TargetFlags = Flags; + } + /// Returns true if this is a weakly referenced external symbol. /// This method may only be called on external symbols. bool isWeaklyReferenced() const { @@ -640,22 +667,18 @@ private: void setBlock(Block &B) { Base = &B; } - void setOffset(orc::ExecutorAddrDiff NewOffset) { - assert(NewOffset <= MaxOffset && "Offset out of range"); - Offset = NewOffset; - } - static constexpr uint64_t MaxOffset = (1ULL << 59) - 1; // FIXME: A char* or SymbolStringPtr may pack better. StringRef Name; Addressable *Base = nullptr; - uint64_t Offset : 58; + uint64_t Offset : 57; uint64_t L : 1; uint64_t S : 2; uint64_t IsLive : 1; uint64_t IsCallable : 1; uint64_t WeakRef : 1; + uint64_t TargetFlags : 1; size_t Size = 0; }; @@ -699,15 +722,18 @@ public: /// Set the protection flags for this section. void setMemProt(orc::MemProt Prot) { this->Prot = Prot; } - /// Get the deallocation policy for this section. - orc::MemDeallocPolicy getMemDeallocPolicy() const { return MDP; } + /// Get the memory lifetime policy for this section. + orc::MemLifetimePolicy getMemLifetimePolicy() const { return MLP; } - /// Set the deallocation policy for this section. - void setMemDeallocPolicy(orc::MemDeallocPolicy MDP) { this->MDP = MDP; } + /// Set the memory lifetime policy for this section. + void setMemLifetimePolicy(orc::MemLifetimePolicy MLP) { this->MLP = MLP; } /// Returns the ordinal for this section. SectionOrdinal getOrdinal() const { return SecOrdinal; } + /// Returns true if this section is empty (contains no blocks or symbols). + bool empty() const { return Blocks.empty(); } + /// Returns an iterator over the blocks defined in this section. iterator_range<block_iterator> blocks() { return make_range(Blocks.begin(), Blocks.end()); @@ -768,7 +794,7 @@ private: StringRef Name; orc::MemProt Prot; - orc::MemDeallocPolicy MDP = orc::MemDeallocPolicy::Standard; + orc::MemLifetimePolicy MLP = orc::MemLifetimePolicy::Standard; SectionOrdinal SecOrdinal = 0; BlockSet Blocks; SymbolSet Symbols; @@ -821,7 +847,7 @@ private: class LinkGraph { private: - using SectionList = std::vector<std::unique_ptr<Section>>; + using SectionMap = DenseMap<StringRef, std::unique_ptr<Section>>; using ExternalSymbolSet = DenseSet<Symbol *>; using BlockSet = DenseSet<Block *>; @@ -860,7 +886,7 @@ private: } static iterator_range<Section::const_block_iterator> - getSectionConstBlocks(Section &S) { + getSectionConstBlocks(const Section &S) { return S.blocks(); } @@ -870,15 +896,27 @@ private: } static iterator_range<Section::const_symbol_iterator> - getSectionConstSymbols(Section &S) { + getSectionConstSymbols(const Section &S) { return S.symbols(); } + struct GetSectionMapEntryValue { + Section &operator()(SectionMap::value_type &KV) const { return *KV.second; } + }; + + struct GetSectionMapEntryConstValue { + const Section &operator()(const SectionMap::value_type &KV) const { + return *KV.second; + } + }; + public: using external_symbol_iterator = ExternalSymbolSet::iterator; - using section_iterator = pointee_iterator<SectionList::iterator>; - using const_section_iterator = pointee_iterator<SectionList::const_iterator>; + using section_iterator = + mapped_iterator<SectionMap::iterator, GetSectionMapEntryValue>; + using const_section_iterator = + mapped_iterator<SectionMap::const_iterator, GetSectionMapEntryConstValue>; template <typename OuterItrT, typename InnerItrT, typename T, iterator_range<InnerItrT> getInnerRange( @@ -928,18 +966,17 @@ public: }; using defined_symbol_iterator = - nested_collection_iterator<const_section_iterator, - Section::symbol_iterator, Symbol *, - getSectionSymbols>; + nested_collection_iterator<section_iterator, Section::symbol_iterator, + Symbol *, getSectionSymbols>; using const_defined_symbol_iterator = nested_collection_iterator<const_section_iterator, Section::const_symbol_iterator, const Symbol *, getSectionConstSymbols>; - using block_iterator = nested_collection_iterator<const_section_iterator, - Section::block_iterator, - Block *, getSectionBlocks>; + using block_iterator = + nested_collection_iterator<section_iterator, Section::block_iterator, + Block *, getSectionBlocks>; using const_block_iterator = nested_collection_iterator<const_section_iterator, @@ -948,11 +985,18 @@ public: using GetEdgeKindNameFunction = const char *(*)(Edge::Kind); + LinkGraph(std::string Name, const Triple &TT, SubtargetFeatures Features, + unsigned PointerSize, support::endianness Endianness, + GetEdgeKindNameFunction GetEdgeKindName) + : Name(std::move(Name)), TT(TT), Features(std::move(Features)), + PointerSize(PointerSize), Endianness(Endianness), + GetEdgeKindName(std::move(GetEdgeKindName)) {} + LinkGraph(std::string Name, const Triple &TT, unsigned PointerSize, support::endianness Endianness, GetEdgeKindNameFunction GetEdgeKindName) - : Name(std::move(Name)), TT(TT), PointerSize(PointerSize), - Endianness(Endianness), GetEdgeKindName(std::move(GetEdgeKindName)) {} + : LinkGraph(std::move(Name), TT, SubtargetFeatures(), PointerSize, + Endianness, GetEdgeKindName) {} LinkGraph(const LinkGraph &) = delete; LinkGraph &operator=(const LinkGraph &) = delete; @@ -966,6 +1010,9 @@ public: /// Returns the target triple for this Graph. const Triple &getTargetTriple() const { return TT; } + /// Return the subtarget features for this Graph. + const SubtargetFeatures &getFeatures() const { return Features; } + /// Returns the pointer size for use in this graph. unsigned getPointerSize() const { return PointerSize; } @@ -996,7 +1043,7 @@ public: /// Note: This Twine-based overload requires an extra string copy and an /// extra heap allocation for large strings. The ArrayRef<char> overload /// should be preferred where possible. - MutableArrayRef<char> allocateString(Twine Source) { + MutableArrayRef<char> allocateContent(Twine Source) { SmallString<256> TmpBuffer; auto SourceStr = Source.toStringRef(TmpBuffer); auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size()); @@ -1004,16 +1051,41 @@ public: return MutableArrayRef<char>(AllocatedBuffer, SourceStr.size()); } + /// Allocate a copy of the given string using the LinkGraph's allocator. + /// + /// The allocated string will be terminated with a null character, and the + /// returned MutableArrayRef will include this null character in the last + /// position. + MutableArrayRef<char> allocateCString(StringRef Source) { + char *AllocatedBuffer = Allocator.Allocate<char>(Source.size() + 1); + llvm::copy(Source, AllocatedBuffer); + AllocatedBuffer[Source.size()] = '\0'; + return MutableArrayRef<char>(AllocatedBuffer, Source.size() + 1); + } + + /// Allocate a copy of the given string using the LinkGraph's allocator. + /// + /// The allocated string will be terminated with a null character, and the + /// returned MutableArrayRef will include this null character in the last + /// position. + /// + /// Note: This Twine-based overload requires an extra string copy and an + /// extra heap allocation for large strings. The ArrayRef<char> overload + /// should be preferred where possible. + MutableArrayRef<char> allocateCString(Twine Source) { + SmallString<256> TmpBuffer; + auto SourceStr = Source.toStringRef(TmpBuffer); + auto *AllocatedBuffer = Allocator.Allocate<char>(SourceStr.size() + 1); + llvm::copy(SourceStr, AllocatedBuffer); + AllocatedBuffer[SourceStr.size()] = '\0'; + return MutableArrayRef<char>(AllocatedBuffer, SourceStr.size() + 1); + } + /// Create a section with the given name, protection flags, and alignment. Section &createSection(StringRef Name, orc::MemProt Prot) { - assert(llvm::none_of(Sections, - [&](std::unique_ptr<Section> &Sec) { - return Sec->getName() == Name; - }) && - "Duplicate section name"); + assert(!Sections.count(Name) && "Duplicate section name"); std::unique_ptr<Section> Sec(new Section(Name, Prot, Sections.size())); - Sections.push_back(std::move(Sec)); - return *Sections.back(); + return *Sections.insert(std::make_pair(Name, std::move(Sec))).first->second; } /// Create a content block. @@ -1041,7 +1113,7 @@ public: orc::ExecutorAddr Address, uint64_t Alignment, uint64_t AlignmentOffset, bool ZeroInitialize = true) { - auto Content = allocateContent(ContentSize); + auto Content = allocateBuffer(ContentSize); if (ZeroInitialize) memset(Content.data(), 0, Content.size()); return createBlock(Parent, Content, Address, Alignment, AlignmentOffset); @@ -1172,29 +1244,39 @@ public: } iterator_range<section_iterator> sections() { - return make_range(section_iterator(Sections.begin()), - section_iterator(Sections.end())); + return make_range( + section_iterator(Sections.begin(), GetSectionMapEntryValue()), + section_iterator(Sections.end(), GetSectionMapEntryValue())); } - SectionList::size_type sections_size() const { return Sections.size(); } + iterator_range<const_section_iterator> sections() const { + return make_range( + const_section_iterator(Sections.begin(), + GetSectionMapEntryConstValue()), + const_section_iterator(Sections.end(), GetSectionMapEntryConstValue())); + } + + size_t sections_size() const { return Sections.size(); } /// Returns the section with the given name if it exists, otherwise returns /// null. Section *findSectionByName(StringRef Name) { - for (auto &S : sections()) - if (S.getName() == Name) - return &S; - return nullptr; + auto I = Sections.find(Name); + if (I == Sections.end()) + return nullptr; + return I->second.get(); } iterator_range<block_iterator> blocks() { - return make_range(block_iterator(Sections.begin(), Sections.end()), - block_iterator(Sections.end(), Sections.end())); + auto Secs = sections(); + return make_range(block_iterator(Secs.begin(), Secs.end()), + block_iterator(Secs.end(), Secs.end())); } iterator_range<const_block_iterator> blocks() const { - return make_range(const_block_iterator(Sections.begin(), Sections.end()), - const_block_iterator(Sections.end(), Sections.end())); + auto Secs = sections(); + return make_range(const_block_iterator(Secs.begin(), Secs.end()), + const_block_iterator(Secs.end(), Secs.end())); } iterator_range<external_symbol_iterator> external_symbols() { @@ -1206,14 +1288,15 @@ public: } iterator_range<defined_symbol_iterator> defined_symbols() { - return make_range(defined_symbol_iterator(Sections.begin(), Sections.end()), - defined_symbol_iterator(Sections.end(), Sections.end())); + auto Secs = sections(); + return make_range(defined_symbol_iterator(Secs.begin(), Secs.end()), + defined_symbol_iterator(Secs.end(), Secs.end())); } iterator_range<const_defined_symbol_iterator> defined_symbols() const { - return make_range( - const_defined_symbol_iterator(Sections.begin(), Sections.end()), - const_defined_symbol_iterator(Sections.end(), Sections.end())); + auto Secs = sections(); + return make_range(const_defined_symbol_iterator(Secs.begin(), Secs.end()), + const_defined_symbol_iterator(Secs.end(), Secs.end())); } /// Make the given symbol external (must not already be external). @@ -1412,11 +1495,10 @@ public: /// Remove a section. The section reference is defunct after calling this /// function and should no longer be used. void removeSection(Section &Sec) { - auto I = llvm::find_if(Sections, [&Sec](const std::unique_ptr<Section> &S) { - return S.get() == &Sec; - }); - assert(I != Sections.end() && "Section does not appear in this graph"); - Sections.erase(I); + assert(Sections.count(Sec.getName()) && "Section not found"); + assert(Sections.find(Sec.getName())->second.get() == &Sec && + "Section map entry invalid"); + Sections.erase(Sec.getName()); } /// Accessor for the AllocActions object for this graph. This can be used to @@ -1436,10 +1518,11 @@ private: std::string Name; Triple TT; + SubtargetFeatures Features; unsigned PointerSize; support::endianness Endianness; GetEdgeKindNameFunction GetEdgeKindName = nullptr; - SectionList Sections; + DenseMap<StringRef, std::unique_ptr<Section>> Sections; ExternalSymbolSet ExternalSymbols; ExternalSymbolSet AbsoluteSymbols; orc::shared::AllocActions AAs; @@ -1592,7 +1675,7 @@ private: }; /// A function for mutating LinkGraphs. -using LinkGraphPassFunction = std::function<Error(LinkGraph &)>; +using LinkGraphPassFunction = unique_function<Error(LinkGraph &)>; /// A list of LinkGraph passes. using LinkGraphPassList = std::vector<LinkGraphPassFunction>; @@ -1662,7 +1745,7 @@ enum class SymbolLookupFlags { RequiredSymbol, WeaklyReferencedSymbol }; raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF); /// A map of symbol names to resolved addresses. -using AsyncLookupResult = DenseMap<StringRef, JITEvaluatedSymbol>; +using AsyncLookupResult = DenseMap<StringRef, orc::ExecutorSymbolDef>; /// A function object to call with a resolved symbol map (See AsyncLookupResult) /// or an error if resolution failed. |