Skip to content

Commit 7a0754b

Browse files
committed
[Immediate] Switch immediate mode from MCJIT to LLJIT.
LLJIT is a simple LLVM IR JIT. Its interface is similar to MCJIT, but its implementation is based on LLVM's newer ORC APIs. This initial patch does not make use of any of LLJIT/ORC's advanced features, but will provide better diagnostics when JIT'd code fails to link. Once LLJIT has proven usable in this basic configuration we can start experimenting with more advanced features, including lazy compilation.
1 parent 2f263a9 commit 7a0754b

File tree

3 files changed

+66
-29
lines changed

3 files changed

+66
-29
lines changed

lib/Immediate/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ add_swift_host_library(swiftImmediate STATIC
55
executionengine
66
linker
77
mcjit
8+
orcjit
9+
jitlink
810
transformutils)
911
target_link_libraries(swiftImmediate PRIVATE
1012
swiftFrontend

lib/Immediate/Immediate.cpp

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18-
#define DEBUG_TYPE "swift-immediate"
1918
#include "swift/Immediate/Immediate.h"
2019
#include "ImmediateImpl.h"
2120

@@ -31,7 +30,8 @@
3130
#include "swift/SILOptimizer/PassManager/Passes.h"
3231
#include "llvm/ADT/SmallString.h"
3332
#include "llvm/Config/config.h"
34-
#include "llvm/ExecutionEngine/MCJIT.h"
33+
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
34+
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
3535
#include "llvm/IR/DiagnosticPrinter.h"
3636
#include "llvm/IR/DiagnosticInfo.h"
3737
#include "llvm/IR/LLVMContext.h"
@@ -40,6 +40,8 @@
4040
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
4141
#include "llvm/Support/Path.h"
4242

43+
#define DEBUG_TYPE "swift-immediate"
44+
4345
#if defined(_WIN32)
4446
#define WIN32_LEAN_AND_MEAN
4547
#define NOMINMAX
@@ -246,10 +248,10 @@ int swift::RunImmediately(CompilerInstance &CI,
246248
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary();
247249
// FIXME: We shouldn't need to use the global context here, but
248250
// something is persisting across calls to performIRGeneration.
249-
auto ModuleOwner = performIRGeneration(
251+
auto ModuleCtx = std::make_unique<llvm::LLVMContext>();
252+
auto Module = performIRGeneration(
250253
IRGenOpts, swiftModule, std::move(SM), swiftModule->getName().str(),
251-
PSPs, getGlobalLLVMContext(), ArrayRef<std::string>());
252-
auto *Module = ModuleOwner.get();
254+
PSPs, *ModuleCtx, ArrayRef<std::string>());
253255

254256
if (Context.hadError())
255257
return -1;
@@ -288,7 +290,6 @@ int swift::RunImmediately(CompilerInstance &CI,
288290

289291
(*emplaceProcessArgs)(argBuf.data(), CmdLine.size());
290292

291-
SmallVector<llvm::Function*, 8> InitFns;
292293
if (autolinkImportedModules(swiftModule, IRGenOpts))
293294
return -1;
294295

@@ -297,41 +298,75 @@ int swift::RunImmediately(CompilerInstance &CI,
297298
PMBuilder.Inliner = llvm::createFunctionInliningPass(200);
298299

299300
// Build the ExecutionEngine.
300-
llvm::EngineBuilder builder(std::move(ModuleOwner));
301-
std::string ErrorMsg;
302301
llvm::TargetOptions TargetOpt;
303302
std::string CPU;
304303
std::string Triple;
305304
std::vector<std::string> Features;
306305
std::tie(TargetOpt, CPU, Features, Triple)
307306
= getIRTargetOptions(IRGenOpts, swiftModule->getASTContext());
308-
builder.setRelocationModel(llvm::Reloc::PIC_);
309-
builder.setTargetOptions(TargetOpt);
310-
builder.setMCPU(CPU);
311-
builder.setMAttrs(Features);
312-
builder.setErrorStr(&ErrorMsg);
313-
builder.setEngineKind(llvm::EngineKind::JIT);
314-
llvm::ExecutionEngine *EE = builder.create();
315-
if (!EE) {
316-
llvm::errs() << "Error loading JIT: " << ErrorMsg;
317-
return -1;
307+
308+
std::unique_ptr<llvm::orc::LLJIT> JIT;
309+
310+
{
311+
auto JITOrErr =
312+
llvm::orc::LLJITBuilder()
313+
.setJITTargetMachineBuilder(
314+
llvm::orc::JITTargetMachineBuilder(llvm::Triple(Triple))
315+
.setRelocationModel(llvm::Reloc::PIC_)
316+
.setOptions(std::move(TargetOpt))
317+
.setCPU(std::move(CPU))
318+
.addFeatures(Features))
319+
.create();
320+
321+
if (!JITOrErr) {
322+
llvm::logAllUnhandledErrors(JITOrErr.takeError(), llvm::errs(), "");
323+
return -1;
324+
} else
325+
JIT = std::move(*JITOrErr);
326+
}
327+
328+
{
329+
// Get a generator for the process symbols and attach it to the main
330+
// JITDylib.
331+
if (auto G = llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(Module->getDataLayout().getGlobalPrefix()))
332+
JIT->getMainJITDylib().addGenerator(std::move(*G));
333+
else {
334+
logAllUnhandledErrors(G.takeError(), llvm::errs(), "");
335+
return -1;
336+
}
318337
}
319338

320339
LLVM_DEBUG(llvm::dbgs() << "Module to be executed:\n";
321340
Module->dump());
322341

323-
EE->finalizeObject();
324-
325-
// Run the generated program.
326-
for (auto InitFn : InitFns) {
327-
LLVM_DEBUG(llvm::dbgs() << "Running initialization function "
328-
<< InitFn->getName() << '\n');
329-
EE->runFunctionAsMain(InitFn, CmdLine, nullptr);
342+
{
343+
auto TSM = llvm::orc::ThreadSafeModule(std::move(Module), std::move(ModuleCtx));
344+
if (auto Err = JIT->addIRModule(std::move(TSM))) {
345+
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
346+
return -1;
347+
}
348+
}
349+
350+
using MainFnTy = int(*)(int, char*[]);
351+
352+
if (auto Err = JIT->runConstructors()) {
353+
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
354+
return -1;
355+
}
356+
357+
MainFnTy JITMain = nullptr;
358+
if (auto MainFnOrErr = JIT->lookup("main"))
359+
JITMain = llvm::jitTargetAddressToFunction<MainFnTy>(MainFnOrErr->getAddress());
360+
else {
361+
logAllUnhandledErrors(MainFnOrErr.takeError(), llvm::errs(), "");
362+
return -1;
330363
}
331364

332365
LLVM_DEBUG(llvm::dbgs() << "Running static constructors\n");
333-
EE->runStaticConstructorsDestructors(false);
366+
if (auto Err = JIT->runConstructors()) {
367+
logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
368+
return -1;
369+
}
334370
LLVM_DEBUG(llvm::dbgs() << "Running main\n");
335-
llvm::Function *EntryFn = Module->getFunction("main");
336-
return EE->runFunctionAsMain(EntryFn, CmdLine, nullptr);
371+
return llvm::orc::runAsMain(JITMain, CmdLine);
337372
}

test/Interpreter/SDK/autolinking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// RUN: not %target-jit-run -lLinkMe %s 2>&1
88

99
// RUN: %target-jit-run -lLinkMe -DUSE_DIRECTLY %s -L %t 2>&1
10-
// RUN: not --crash %target-jit-run -DUSE_DIRECTLY -lLinkMe %s 2>&1
10+
// RUN: not %target-jit-run -DUSE_DIRECTLY -lLinkMe %s 2>&1
1111
// REQUIRES: executable_test
1212

1313

0 commit comments

Comments
 (0)