Skip to content

Reapply "[llvm-jitlink] Use concurrent linking by default." with fixes. #120958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/tools/llvm-jitlink/llvm-jitlink-coff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ static Expected<Symbol &> getCOFFStubTarget(LinkGraph &G, Block &B) {

namespace llvm {
Error registerCOFFGraphInfo(Session &S, LinkGraph &G) {
std::lock_guard<std::mutex> Lock(S.M);

auto FileName = sys::path::filename(G.getName());
if (S.FileInfos.count(FileName)) {
return make_error<StringError>("When -check is passed, file names must be "
Expand Down
2 changes: 2 additions & 0 deletions llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ static Error registerSymbol(LinkGraph &G, Symbol &Sym, Session::FileInfo &FI,
namespace llvm {

Error registerELFGraphInfo(Session &S, LinkGraph &G) {
std::lock_guard<std::mutex> Lock(S.M);

auto FileName = sys::path::filename(G.getName());
if (S.FileInfos.count(FileName)) {
return make_error<StringError>("When -check is passed, file names must be "
Expand Down
2 changes: 2 additions & 0 deletions llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ static Expected<Symbol &> getMachOStubTarget(LinkGraph &G, Block &B) {
namespace llvm {

Error registerMachOGraphInfo(Session &S, LinkGraph &G) {
std::lock_guard<std::mutex> Lock(S.M);

auto FileName = sys::path::filename(G.getName());
if (S.FileInfos.count(FileName)) {
return make_error<StringError>("When -check is passed, file names must be "
Expand Down
56 changes: 48 additions & 8 deletions llvm/tools/llvm-jitlink/llvm-jitlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
cl::desc("input files"),
cl::cat(JITLinkCategory));

static cl::opt<size_t> MaterializationThreads(
"num-threads", cl::desc("Number of materialization threads to use"),
cl::init(std::numeric_limits<size_t>::max()), cl::cat(JITLinkCategory));

static cl::list<std::string>
LibrarySearchPaths("L",
cl::desc("Add dir to the list of library search paths"),
Expand Down Expand Up @@ -400,6 +404,7 @@ bool lazyLinkingRequested() {
}

static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
std::lock_guard<std::mutex> Lock(S.M);

// If this graph is part of the test harness there's nothing to do.
if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName()))
Expand Down Expand Up @@ -450,7 +455,11 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
return Error::success();
}

static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) {
static void dumpSectionContents(raw_ostream &OS, Session &S, LinkGraph &G) {
std::lock_guard<std::mutex> Lock(S.M);

outs() << "Relocated section contents for " << G.getName() << ":\n";

constexpr orc::ExecutorAddrDiff DumpWidth = 16;
static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two");

Expand Down Expand Up @@ -842,7 +851,7 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
S.CreateMemoryManager = createSharedMemoryManager;

return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt),
std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads),
std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
#endif
}
Expand Down Expand Up @@ -984,10 +993,16 @@ Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
auto PageSize = sys::Process::getPageSize();
if (!PageSize)
return PageSize.takeError();
std::unique_ptr<TaskDispatcher> Dispatcher;
if (MaterializationThreads == 0)
Dispatcher = std::make_unique<InPlaceTaskDispatcher>();
else
Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>(
MaterializationThreads);

EPC = std::make_unique<SelfExecutorProcessControl>(
std::make_shared<SymbolStringPool>(),
std::make_unique<InPlaceTaskDispatcher>(), std::move(TT), *PageSize,
createInProcessMemoryManager());
std::make_shared<SymbolStringPool>(), std::move(Dispatcher),
std::move(TT), *PageSize, createInProcessMemoryManager());
}

Error Err = Error::success();
Expand Down Expand Up @@ -1221,6 +1236,7 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {

if (ShowGraphsRegex)
PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
std::lock_guard<std::mutex> Lock(M);
// Print graph if ShowLinkGraphs is specified-but-empty, or if
// it contains the given graph.
if (ShowGraphsRegex->match(G.getName())) {
Expand All @@ -1239,9 +1255,8 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
[this](LinkGraph &G) { return applyHarnessPromotions(*this, G); });

if (ShowRelocatedSectionContents)
PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error {
outs() << "Relocated section contents for " << G.getName() << ":\n";
dumpSectionContents(outs(), G);
PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
dumpSectionContents(outs(), *this, G);
return Error::success();
});

Expand Down Expand Up @@ -1613,6 +1628,31 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
}
}

if (MaterializationThreads == std::numeric_limits<size_t>::max()) {
if (auto HC = std::thread::hardware_concurrency())
MaterializationThreads = HC;
else {
errs() << "Warning: std::thread::hardware_concurrency() returned 0, "
"defaulting to -threads=1.\n";
MaterializationThreads = 1;
}
}

if (!!OutOfProcessExecutor.getNumOccurrences() ||
!!OutOfProcessExecutorConnect.getNumOccurrences()) {
if (NoExec)
return make_error<StringError>("-noexec cannot be used with " +
OutOfProcessExecutor.ArgStr + " or " +
OutOfProcessExecutorConnect.ArgStr,
inconvertibleErrorCode());

if (MaterializationThreads == 0)
return make_error<StringError>("-threads=0 cannot be used with " +
OutOfProcessExecutor.ArgStr + " or " +
OutOfProcessExecutorConnect.ArgStr,
inconvertibleErrorCode());
}

// Only one of -oop-executor and -oop-executor-connect can be used.
if (!!OutOfProcessExecutor.getNumOccurrences() &&
!!OutOfProcessExecutorConnect.getNumOccurrences())
Expand Down
Loading