aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
downloadsrc-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.h215
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.