forked from OSchip/llvm-project
Revert "[JITLink][NFC] Add TableManager to replace PerGraph...Builder pass"
This reverts commit 50a278c2ae
.
This commit is contained in:
parent
f6fa95b77f
commit
b384736b20
|
@ -1688,30 +1688,6 @@ Error markAllSymbolsLive(LinkGraph &G);
|
|||
Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
|
||||
const Edge &E);
|
||||
|
||||
static void visitEdge(LinkGraph &G, Block *B, Edge &E) {}
|
||||
|
||||
template <typename FixerT, typename... FixerTs>
|
||||
static void visitEdge(LinkGraph &G, Block *B, Edge &E, FixerT &&Fixer,
|
||||
FixerTs &&...Fixers) {
|
||||
if (!Fixer.visitEdge(G, B, E))
|
||||
visitEdge(G, B, E, std::forward<FixerTs>(Fixers)...);
|
||||
}
|
||||
|
||||
/// Visits edges exist in graph by Fixers.
|
||||
///
|
||||
/// Note: that if a fixer fixes the edge successfully,
|
||||
/// the rest of the fixers will not visit this edge.
|
||||
template <typename... FixerTs>
|
||||
void visitExistingEdges(LinkGraph &G, FixerTs &&...Fixers) {
|
||||
// We're going to be adding new blocks, but we don't want to iterate over
|
||||
// the new ones, so build a worklist.
|
||||
std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
|
||||
|
||||
for (auto *B : Worklist)
|
||||
for (auto &E : B->edges())
|
||||
visitEdge(G, B, E, std::forward<FixerTs>(Fixers)...);
|
||||
}
|
||||
|
||||
/// Create a LinkGraph from the given object buffer.
|
||||
///
|
||||
/// Note: The graph does not take ownership of the underlying buffer, nor copy
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "ELFLinkGraphBuilder.h"
|
||||
#include "JITLinkGeneric.h"
|
||||
#include "PerGraphGOTAndPLTStubsBuilder.h"
|
||||
#include "TableManager.h"
|
||||
#include "PerGraphTLSInfoEntryBuilder.h"
|
||||
|
||||
#define DEBUG_TYPE "jitlink"
|
||||
|
||||
|
@ -35,109 +35,148 @@ constexpr StringRef ELFGOTSectionName = "$__GOT";
|
|||
constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
|
||||
constexpr StringRef ELFTLSInfoSectionName = "$__TLSINFO";
|
||||
|
||||
class GOTTableManager_ELF_x86_64
|
||||
: public TableManager<GOTTableManager_ELF_x86_64> {
|
||||
class PerGraphTLSInfoBuilder_ELF_x86_64
|
||||
: public PerGraphTLSInfoEntryBuilder<PerGraphTLSInfoBuilder_ELF_x86_64> {
|
||||
public:
|
||||
static const uint8_t NullGOTEntryContent[8];
|
||||
static const uint8_t TLSInfoEntryContent[16];
|
||||
using PerGraphTLSInfoEntryBuilder<
|
||||
PerGraphTLSInfoBuilder_ELF_x86_64>::PerGraphTLSInfoEntryBuilder;
|
||||
|
||||
// Nice name for table
|
||||
StringRef getTableName() { return "GOT"; }
|
||||
|
||||
bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
|
||||
Edge::Kind KindToSet = E.getKind();
|
||||
switch (E.getKind()) {
|
||||
case x86_64::Delta64FromGOT: {
|
||||
// we need to make sure that the GOT section exists, but don't otherwise
|
||||
// need to fix up this edge
|
||||
getGOTSection(G);
|
||||
return false;
|
||||
}
|
||||
case x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable:
|
||||
KindToSet = x86_64::PCRel32GOTLoadREXRelaxable;
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable:
|
||||
KindToSet = x86_64::PCRel32GOTLoadRelaxable;
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta64:
|
||||
KindToSet = x86_64::Delta64;
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta64FromGOT:
|
||||
KindToSet = x86_64::Delta64FromGOT;
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta32:
|
||||
KindToSet = x86_64::Delta32;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
|
||||
<< formatv("{0:x}", B->getFixupAddress(E)) << " ("
|
||||
<< formatv("{0:x}", B->getAddress()) << " + "
|
||||
<< formatv("{0:x}", E.getOffset()) << ")\n";
|
||||
});
|
||||
E.setKind(KindToSet);
|
||||
return true;
|
||||
bool isTLSEdgeToFix(Edge &E) {
|
||||
return E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32;
|
||||
}
|
||||
|
||||
Symbol &createEntry(LinkGraph &G, Symbol &Target) {
|
||||
Symbol &createTLSInfoEntry(Symbol &Target) {
|
||||
// the TLS Info entry's key value will be written by the fixTLVSectionByName
|
||||
// pass, so create mutable content.
|
||||
auto &TLSInfoEntry = G.createMutableContentBlock(
|
||||
getTLSInfoSection(), G.allocateContent(getTLSInfoEntryContent()), 0, 8,
|
||||
0);
|
||||
TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0);
|
||||
return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
|
||||
}
|
||||
|
||||
void fixTLSEdge(Edge &E, Symbol &Target) {
|
||||
if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
|
||||
E.setTarget(Target);
|
||||
E.setKind(x86_64::Delta32);
|
||||
}
|
||||
}
|
||||
|
||||
Section &getTLSInfoSection() const {
|
||||
if (!TLSInfoSection)
|
||||
TLSInfoSection =
|
||||
&G.createSection(ELFTLSInfoSectionName, sys::Memory::MF_READ);
|
||||
return *TLSInfoSection;
|
||||
}
|
||||
|
||||
private:
|
||||
ArrayRef<char> getTLSInfoEntryContent() {
|
||||
return {reinterpret_cast<const char *>(TLSInfoEntryContent),
|
||||
sizeof(TLSInfoEntryContent)};
|
||||
}
|
||||
|
||||
mutable Section *TLSInfoSection = nullptr;
|
||||
};
|
||||
|
||||
const uint8_t PerGraphTLSInfoBuilder_ELF_x86_64::TLSInfoEntryContent[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/
|
||||
};
|
||||
|
||||
class PerGraphGOTAndPLTStubsBuilder_ELF_x86_64
|
||||
: public PerGraphGOTAndPLTStubsBuilder<
|
||||
PerGraphGOTAndPLTStubsBuilder_ELF_x86_64> {
|
||||
public:
|
||||
static const uint8_t NullGOTEntryContent[8];
|
||||
static const uint8_t StubContent[6];
|
||||
|
||||
using PerGraphGOTAndPLTStubsBuilder<
|
||||
PerGraphGOTAndPLTStubsBuilder_ELF_x86_64>::PerGraphGOTAndPLTStubsBuilder;
|
||||
|
||||
bool isGOTEdgeToFix(Edge &E) const {
|
||||
if (E.getKind() == x86_64::Delta64FromGOT) {
|
||||
// We need to make sure that the GOT section exists, but don't otherwise
|
||||
// need to fix up this edge.
|
||||
getGOTSection();
|
||||
return false;
|
||||
}
|
||||
return E.getKind() == x86_64::RequestGOTAndTransformToDelta32 ||
|
||||
E.getKind() == x86_64::RequestGOTAndTransformToDelta64 ||
|
||||
E.getKind() ==
|
||||
x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable ||
|
||||
E.getKind() == x86_64::RequestGOTAndTransformToDelta64FromGOT ||
|
||||
E.getKind() ==
|
||||
x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable;
|
||||
}
|
||||
|
||||
Symbol &createGOTEntry(Symbol &Target) {
|
||||
auto &GOTEntryBlock = G.createContentBlock(
|
||||
getGOTSection(G), getGOTEntryBlockContent(), 0, 8, 0);
|
||||
getGOTSection(), getGOTEntryBlockContent(), 0, 8, 0);
|
||||
GOTEntryBlock.addEdge(x86_64::Pointer64, 0, Target, 0);
|
||||
return G.addAnonymousSymbol(GOTEntryBlock, 0, 8, false, false);
|
||||
}
|
||||
|
||||
private:
|
||||
Section &getGOTSection(LinkGraph &G) {
|
||||
if (!GOTSection)
|
||||
GOTSection = &G.createSection(ELFGOTSectionName, sys::Memory::MF_READ);
|
||||
return *GOTSection;
|
||||
}
|
||||
ArrayRef<char> getGOTEntryBlockContent() const {
|
||||
return {reinterpret_cast<const char *>(NullGOTEntryContent),
|
||||
sizeof(NullGOTEntryContent)};
|
||||
}
|
||||
Section *GOTSection = nullptr;
|
||||
};
|
||||
const uint8_t GOTTableManager_ELF_x86_64::NullGOTEntryContent[8] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
class PLTTableManager_ELF_x86_64
|
||||
: public TableManager<PLTTableManager_ELF_x86_64> {
|
||||
public:
|
||||
PLTTableManager_ELF_x86_64(GOTTableManager_ELF_x86_64 &GOTTable)
|
||||
: GOTTable(GOTTable) {}
|
||||
|
||||
StringRef getTableName() { return "PLT"; }
|
||||
|
||||
static const uint8_t StubContent[6];
|
||||
bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
|
||||
if (E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined()) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
|
||||
<< formatv("{0:x}", B->getFixupAddress(E)) << " ("
|
||||
<< formatv("{0:x}", B->getAddress()) << " + "
|
||||
<< formatv("{0:x}", E.getOffset()) << ")\n";
|
||||
});
|
||||
// Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to
|
||||
// be optimized when the target is in-range.
|
||||
E.setKind(x86_64::BranchPCRel32ToPtrJumpStubBypassable);
|
||||
return true;
|
||||
void fixGOTEdge(Edge &E, Symbol &GOTEntry) {
|
||||
// If this is a PCRel32GOT/PCRel64GOT then change it to an ordinary
|
||||
// PCRel32/PCRel64. If it is a PCRel32GOTLoad then leave it as-is for now:
|
||||
// We will use the kind to check for GOT optimization opportunities in the
|
||||
// optimizeMachO_x86_64_GOTAndStubs pass below.
|
||||
// If it's a GOT64 leave it as is.
|
||||
switch (E.getKind()) {
|
||||
case x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable:
|
||||
E.setKind(x86_64::PCRel32GOTLoadREXRelaxable);
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable:
|
||||
E.setKind(x86_64::PCRel32GOTLoadRelaxable);
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta64:
|
||||
E.setKind(x86_64::Delta64);
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta64FromGOT:
|
||||
E.setKind(x86_64::Delta64FromGOT);
|
||||
break;
|
||||
case x86_64::RequestGOTAndTransformToDelta32:
|
||||
E.setKind(x86_64::Delta32);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected GOT edge kind");
|
||||
}
|
||||
return false;
|
||||
|
||||
E.setTarget(GOTEntry);
|
||||
// Leave the edge addend as-is.
|
||||
}
|
||||
|
||||
Symbol &createEntry(LinkGraph &G, Symbol &Target) {
|
||||
auto &StubContentBlock = G.createContentBlock(
|
||||
getStubsSection(G), getStubBlockContent(), 0, 1, 0);
|
||||
bool isExternalBranchEdge(Edge &E) {
|
||||
return E.getKind() == x86_64::BranchPCRel32 && !E.getTarget().isDefined();
|
||||
}
|
||||
|
||||
Symbol &createPLTStub(Symbol &Target) {
|
||||
auto &StubContentBlock =
|
||||
G.createContentBlock(getStubsSection(), getStubBlockContent(), 0, 1, 0);
|
||||
// Re-use GOT entries for stub targets.
|
||||
auto &GOTEntrySymbol = GOTTable.getEntryForTarget(G, Target);
|
||||
auto &GOTEntrySymbol = getGOTEntry(Target);
|
||||
StubContentBlock.addEdge(x86_64::Delta32, 2, GOTEntrySymbol, -4);
|
||||
return G.addAnonymousSymbol(StubContentBlock, 0, 6, true, false);
|
||||
}
|
||||
|
||||
void fixPLTEdge(Edge &E, Symbol &Stub) {
|
||||
assert(E.getKind() == x86_64::BranchPCRel32 && "Not a Branch32 edge?");
|
||||
|
||||
// Set the edge kind to Branch32ToPtrJumpStubBypassable to enable it to be
|
||||
// optimized when the target is in-range.
|
||||
E.setKind(x86_64::BranchPCRel32ToPtrJumpStubBypassable);
|
||||
E.setTarget(Stub);
|
||||
}
|
||||
|
||||
private:
|
||||
Section &getStubsSection(LinkGraph &G) {
|
||||
Section &getGOTSection() const {
|
||||
if (!GOTSection)
|
||||
GOTSection = &G.createSection(ELFGOTSectionName, sys::Memory::MF_READ);
|
||||
return *GOTSection;
|
||||
}
|
||||
|
||||
Section &getStubsSection() const {
|
||||
if (!StubsSection) {
|
||||
auto StubsProt = static_cast<sys::Memory::ProtectionFlags>(
|
||||
sys::Memory::MF_READ | sys::Memory::MF_EXEC);
|
||||
|
@ -146,79 +185,26 @@ private:
|
|||
return *StubsSection;
|
||||
}
|
||||
|
||||
ArrayRef<char> getGOTEntryBlockContent() {
|
||||
return {reinterpret_cast<const char *>(NullGOTEntryContent),
|
||||
sizeof(NullGOTEntryContent)};
|
||||
}
|
||||
|
||||
ArrayRef<char> getStubBlockContent() {
|
||||
return {reinterpret_cast<const char *>(StubContent), sizeof(StubContent)};
|
||||
}
|
||||
|
||||
Section *StubsSection = nullptr;
|
||||
GOTTableManager_ELF_x86_64 &GOTTable;
|
||||
};
|
||||
const uint8_t PLTTableManager_ELF_x86_64::StubContent[6] = {0xFF, 0x25, 0x00,
|
||||
0x00, 0x00, 0x00};
|
||||
|
||||
class TLSInfoTableManager_ELF_x86_64
|
||||
: public TableManager<TLSInfoTableManager_ELF_x86_64> {
|
||||
public:
|
||||
static const uint8_t TLSInfoEntryContent[16];
|
||||
|
||||
StringRef getTableName() { return "TLSInfo"; }
|
||||
|
||||
bool fixEdgeKind(LinkGraph &G, Block *B, Edge &E) {
|
||||
if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
|
||||
<< formatv("{0:x}", B->getFixupAddress(E)) << " ("
|
||||
<< formatv("{0:x}", B->getAddress()) << " + "
|
||||
<< formatv("{0:x}", E.getOffset()) << ")\n";
|
||||
});
|
||||
E.setKind(x86_64::Delta32);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Symbol &createEntry(LinkGraph &G, Symbol &Target) {
|
||||
// the TLS Info entry's key value will be written by the fixTLVSectionByName
|
||||
// pass, so create mutable content.
|
||||
auto &TLSInfoEntry = G.createMutableContentBlock(
|
||||
getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()), 0, 8,
|
||||
0);
|
||||
TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0);
|
||||
return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
|
||||
}
|
||||
|
||||
private:
|
||||
Section &getTLSInfoSection(LinkGraph &G) {
|
||||
if (!TLSInfoTable)
|
||||
TLSInfoTable =
|
||||
&G.createSection(ELFTLSInfoSectionName, sys::Memory::MF_READ);
|
||||
return *TLSInfoTable;
|
||||
}
|
||||
|
||||
ArrayRef<char> getTLSInfoEntryContent() const {
|
||||
return {reinterpret_cast<const char *>(TLSInfoEntryContent),
|
||||
sizeof(TLSInfoEntryContent)};
|
||||
}
|
||||
|
||||
Section *TLSInfoTable = nullptr;
|
||||
mutable Section *GOTSection = nullptr;
|
||||
mutable Section *StubsSection = nullptr;
|
||||
};
|
||||
|
||||
const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/
|
||||
};
|
||||
|
||||
Error buildTables_ELF_x86_64(LinkGraph &G) {
|
||||
LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
|
||||
|
||||
GOTTableManager_ELF_x86_64 GOT;
|
||||
PLTTableManager_ELF_x86_64 PLT(GOT);
|
||||
TLSInfoTableManager_ELF_x86_64 TLSInfo;
|
||||
visitExistingEdges(G, GOT, PLT, TLSInfo);
|
||||
return Error::success();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::NullGOTEntryContent[8] =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
const uint8_t PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::StubContent[6] = {
|
||||
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static const char *getELFX86_64RelocName(uint32_t Type) {
|
||||
switch (Type) {
|
||||
#define ELF_RELOC(Name, Number) \
|
||||
|
@ -511,8 +497,11 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
|
|||
else
|
||||
Config.PrePrunePasses.push_back(markAllSymbolsLive);
|
||||
|
||||
// Add an in-place GOT/Stubs/TLSInfoEntry build pass.
|
||||
Config.PostPrunePasses.push_back(buildTables_ELF_x86_64);
|
||||
// Add an in-place GOT/Stubs pass.
|
||||
|
||||
Config.PostPrunePasses.push_back(PerGraphTLSInfoBuilder_ELF_x86_64::asPass);
|
||||
Config.PostPrunePasses.push_back(
|
||||
PerGraphGOTAndPLTStubsBuilder_ELF_x86_64::asPass);
|
||||
|
||||
// Resolve any external section start / end symbols.
|
||||
Config.PostAllocationPasses.push_back(
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
//===---------------- PerGraphTLSInfoEntryBuilder.h -------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Construct Thread local storage info entry for each graph.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHTLSINFOENTRYBUILDER_H
|
||||
#define LLVM_EXECUTIONENGINE_JITLINK_PERGRAPHTLSINFOENTRYBUILDER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
#define DEBUG_TYPE "jitlink"
|
||||
namespace llvm {
|
||||
namespace jitlink {
|
||||
|
||||
template <typename BuilderImplT> class PerGraphTLSInfoEntryBuilder {
|
||||
public:
|
||||
PerGraphTLSInfoEntryBuilder(LinkGraph &G) : G(G) {}
|
||||
static Error asPass(LinkGraph &G) { return BuilderImplT(G).run(); }
|
||||
|
||||
Error run() {
|
||||
LLVM_DEBUG(dbgs() << "Running Per-Graph TLS Info entry builder:\n ");
|
||||
|
||||
std::vector<Block *> Worklist(G.blocks().begin(), G.blocks().end());
|
||||
|
||||
for (auto *B : Worklist)
|
||||
for (auto &E : B->edges()) {
|
||||
if (impl().isTLSEdgeToFix(E)) {
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Fixing " << G.getEdgeKindName(E.getKind())
|
||||
<< " edge at " << formatv("{0:x}", B->getFixupAddress(E))
|
||||
<< " (" << formatv("{0:x}", B->getAddress()) << " + "
|
||||
<< formatv("{0:x}", E.getOffset()) << ")\n";
|
||||
});
|
||||
impl().fixTLSEdge(E, getTLSInfoEntry(E.getTarget()));
|
||||
}
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
protected:
|
||||
LinkGraph &G;
|
||||
|
||||
Symbol &getTLSInfoEntry(Symbol &Target) {
|
||||
assert(Target.hasName() && "TLS edge cannot point to anonymous target");
|
||||
auto TLSInfoEntryI = TLSInfoEntries.find(Target.getName());
|
||||
if (TLSInfoEntryI == TLSInfoEntries.end()) {
|
||||
auto &TLSInfoEntry = impl().createTLSInfoEntry(Target);
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Created TLS Info entry for " << Target.getName() << ": "
|
||||
<< TLSInfoEntry << "\n";
|
||||
});
|
||||
TLSInfoEntryI =
|
||||
TLSInfoEntries.insert(std::make_pair(Target.getName(), &TLSInfoEntry))
|
||||
.first;
|
||||
}
|
||||
assert(TLSInfoEntryI != TLSInfoEntries.end() &&
|
||||
"Could not get TLSInfo symbol");
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Using TLS Info entry" << *TLSInfoEntryI->second << "\n";
|
||||
});
|
||||
return *TLSInfoEntryI->second;
|
||||
}
|
||||
|
||||
private:
|
||||
DenseMap<StringRef, Symbol *> TLSInfoEntries;
|
||||
BuilderImplT &impl() { return static_cast<BuilderImplT &>(*this); }
|
||||
};
|
||||
} // namespace jitlink
|
||||
} // namespace llvm
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
//===---------------------- TableManager.h ----------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Fix edge for edge that needs an entry to reference the target symbol
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_JITLINK_TABLEMANAGER_H
|
||||
#define LLVM_EXECUTIONENGINE_JITLINK_TABLEMANAGER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
#define DEBUG_TYPE "jitlink"
|
||||
|
||||
namespace llvm {
|
||||
namespace jitlink {
|
||||
|
||||
/// Table like section manager
|
||||
template <typename TableManagerImplT> class TableManager {
|
||||
public:
|
||||
/// Visit edge, return true if the edge was dealt with, otherwise return
|
||||
/// false(let other managers to visit).
|
||||
bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
|
||||
if (impl().fixEdgeKind(G, B, E)) {
|
||||
fixTarget(G, E);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return the constructed entry
|
||||
///
|
||||
/// Use parameter G to construct the entry for target symbol
|
||||
Symbol &getEntryForTarget(LinkGraph &G, Symbol &Target) {
|
||||
assert(Target.hasName() && "Edge cannot point to anonymous target");
|
||||
|
||||
auto EntryI = Entries.find(Target.getName());
|
||||
|
||||
// Build the entry if it doesn't exist.
|
||||
if (EntryI == Entries.end()) {
|
||||
auto &Entry = impl().createEntry(G, Target);
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Created" << impl().getTableName() << "entry for "
|
||||
<< Target.getName() << ": " << Entry << "\n";
|
||||
});
|
||||
EntryI = Entries.insert(std::make_pair(Target.getName(), &Entry)).first;
|
||||
}
|
||||
|
||||
assert(EntryI != Entries.end() && "Could not get entry symbol");
|
||||
LLVM_DEBUG({
|
||||
dbgs() << " Using " << impl().getTableName() << " entry "
|
||||
<< *EntryI->second << "\n";
|
||||
});
|
||||
return *EntryI->second;
|
||||
}
|
||||
|
||||
private:
|
||||
void fixTarget(LinkGraph &G, Edge &E) {
|
||||
E.setTarget(getEntryForTarget(G, E.getTarget()));
|
||||
}
|
||||
|
||||
TableManagerImplT &impl() { return static_cast<TableManagerImplT &>(*this); }
|
||||
DenseMap<StringRef, Symbol *> Entries;
|
||||
};
|
||||
|
||||
} // namespace jitlink
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue