1 //===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This utility provides a simple wrapper around the LLVM Execution Engines,
10 // which allow the direct execution of LLVM programs through a Just-In-Time
11 // compiler, or through an interpreter if no JIT is available for this platform.
13 //===----------------------------------------------------------------------===//
15 #include "RemoteJITUtils.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/Triple.h"
18 #include "llvm/Bitcode/BitcodeReader.h"
19 #include "llvm/CodeGen/CommandFlags.inc"
20 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
21 #include "llvm/Config/llvm-config.h"
22 #include "llvm/ExecutionEngine/GenericValue.h"
23 #include "llvm/ExecutionEngine/Interpreter.h"
24 #include "llvm/ExecutionEngine/JITEventListener.h"
25 #include "llvm/ExecutionEngine/MCJIT.h"
26 #include "llvm/ExecutionEngine/ObjectCache.h"
27 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
28 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
29 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
30 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
31 #include "llvm/ExecutionEngine/OrcMCJITReplacement.h"
32 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
33 #include "llvm/IR/IRBuilder.h"
34 #include "llvm/IR/LLVMContext.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/IR/Type.h"
37 #include "llvm/IR/Verifier.h"
38 #include "llvm/IRReader/IRReader.h"
39 #include "llvm/Object/Archive.h"
40 #include "llvm/Object/ObjectFile.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/DynamicLibrary.h"
44 #include "llvm/Support/Format.h"
45 #include "llvm/Support/InitLLVM.h"
46 #include "llvm/Support/ManagedStatic.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/Memory.h"
49 #include "llvm/Support/MemoryBuffer.h"
50 #include "llvm/Support/Path.h"
51 #include "llvm/Support/PluginLoader.h"
52 #include "llvm/Support/Process.h"
53 #include "llvm/Support/Program.h"
54 #include "llvm/Support/SourceMgr.h"
55 #include "llvm/Support/TargetSelect.h"
56 #include "llvm/Support/WithColor.h"
57 #include "llvm/Support/raw_ostream.h"
58 #include "llvm/Transforms/Instrumentation.h"
62 #include <cygwin/version.h>
63 #if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
64 #define DO_NOTHING_ATEXIT 1
70 #define DEBUG_TYPE "lli"
74 enum class JITKind
{ MCJIT
, OrcMCJITReplacement
, OrcLazy
};
77 InputFile(cl::desc("<input bitcode>"), cl::Positional
, cl::init("-"));
80 InputArgv(cl::ConsumeAfter
, cl::desc("<program arguments>..."));
82 cl::opt
<bool> ForceInterpreter("force-interpreter",
83 cl::desc("Force interpretation: disable JIT"),
86 cl::opt
<JITKind
> UseJITKind("jit-kind",
87 cl::desc("Choose underlying JIT kind."),
88 cl::init(JITKind::MCJIT
),
90 clEnumValN(JITKind::MCJIT
, "mcjit",
92 clEnumValN(JITKind::OrcMCJITReplacement
,
94 "Orc-based MCJIT replacement"),
95 clEnumValN(JITKind::OrcLazy
,
97 "Orc-based lazy JIT.")));
100 LazyJITCompileThreads("compile-threads",
101 cl::desc("Choose the number of compile threads "
102 "(jit-kind=orc-lazy only)"),
105 cl::list
<std::string
>
106 ThreadEntryPoints("thread-entry",
107 cl::desc("calls the given entry-point on a new thread "
108 "(jit-kind=orc-lazy only)"));
110 cl::opt
<bool> PerModuleLazy(
112 cl::desc("Performs lazy compilation on whole module boundaries "
113 "rather than individual functions"),
116 cl::list
<std::string
>
118 cl::desc("Specifies the JITDylib to be used for any subsequent "
119 "-extra-module arguments."));
121 // The MCJIT supports building for a target address space separate from
122 // the JIT compilation process. Use a forked process and a copying
123 // memory manager with IPC to execute using this functionality.
124 cl::opt
<bool> RemoteMCJIT("remote-mcjit",
125 cl::desc("Execute MCJIT'ed code in a separate process."),
128 // Manually specify the child process for remote execution. This overrides
129 // the simulated remote execution that allocates address space for child
130 // execution. The child process will be executed and will communicate with
131 // lli via stdin/stdout pipes.
133 ChildExecPath("mcjit-remote-process",
134 cl::desc("Specify the filename of the process to launch "
135 "for remote MCJIT execution. If none is specified,"
136 "\n\tremote execution will be simulated in-process."),
137 cl::value_desc("filename"), cl::init(""));
139 // Determine optimization level.
142 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
143 "(default = '-O2')"),
149 TargetTriple("mtriple", cl::desc("Override target triple for module"));
152 EntryFunc("entry-function",
153 cl::desc("Specify the entry function (default = 'main') "
154 "of the executable"),
155 cl::value_desc("function"),
158 cl::list
<std::string
>
159 ExtraModules("extra-module",
160 cl::desc("Extra modules to be loaded"),
161 cl::value_desc("input bitcode"));
163 cl::list
<std::string
>
164 ExtraObjects("extra-object",
165 cl::desc("Extra object files to be loaded"),
166 cl::value_desc("input object"));
168 cl::list
<std::string
>
169 ExtraArchives("extra-archive",
170 cl::desc("Extra archive files to be loaded"),
171 cl::value_desc("input archive"));
174 EnableCacheManager("enable-cache-manager",
175 cl::desc("Use cache manager to save/load mdoules"),
179 ObjectCacheDir("object-cache-dir",
180 cl::desc("Directory to store cached object files "
181 "(must be user writable)"),
185 FakeArgv0("fake-argv0",
186 cl::desc("Override the 'argv[0]' value passed into the executing"
187 " program"), cl::value_desc("executable"));
190 DisableCoreFiles("disable-core-files", cl::Hidden
,
191 cl::desc("Disable emission of core files if possible"));
194 NoLazyCompilation("disable-lazy-compilation",
195 cl::desc("Disable JIT lazy compilation"),
199 GenerateSoftFloatCalls("soft-float",
200 cl::desc("Generate software floating point library calls"),
203 enum class DumpKind
{
210 cl::opt
<DumpKind
> OrcDumpKind(
211 "orc-lazy-debug", cl::desc("Debug dumping for the orc-lazy JIT."),
212 cl::init(DumpKind::NoDump
),
213 cl::values(clEnumValN(DumpKind::NoDump
, "no-dump",
214 "Don't dump anything."),
215 clEnumValN(DumpKind::DumpFuncsToStdOut
, "funcs-to-stdout",
216 "Dump function names to stdout."),
217 clEnumValN(DumpKind::DumpModsToStdOut
, "mods-to-stdout",
218 "Dump modules to stdout."),
219 clEnumValN(DumpKind::DumpModsToDisk
, "mods-to-disk",
220 "Dump modules to the current "
221 "working directory. (WARNING: "
222 "will overwrite existing files).")),
225 ExitOnError ExitOnErr
;
228 //===----------------------------------------------------------------------===//
231 // This object cache implementation writes cached objects to disk to the
232 // directory specified by CacheDir, using a filename provided in the module
233 // descriptor. The cache tries to load a saved object using that path if the
234 // file exists. CacheDir defaults to "", in which case objects are cached
235 // alongside their originating bitcodes.
237 class LLIObjectCache
: public ObjectCache
{
239 LLIObjectCache(const std::string
& CacheDir
) : CacheDir(CacheDir
) {
240 // Add trailing '/' to cache dir if necessary.
241 if (!this->CacheDir
.empty() &&
242 this->CacheDir
[this->CacheDir
.size() - 1] != '/')
243 this->CacheDir
+= '/';
245 ~LLIObjectCache() override
{}
247 void notifyObjectCompiled(const Module
*M
, MemoryBufferRef Obj
) override
{
248 const std::string
&ModuleID
= M
->getModuleIdentifier();
249 std::string CacheName
;
250 if (!getCacheFilename(ModuleID
, CacheName
))
252 if (!CacheDir
.empty()) { // Create user-defined cache dir.
253 SmallString
<128> dir(sys::path::parent_path(CacheName
));
254 sys::fs::create_directories(Twine(dir
));
257 raw_fd_ostream
outfile(CacheName
, EC
, sys::fs::F_None
);
258 outfile
.write(Obj
.getBufferStart(), Obj
.getBufferSize());
262 std::unique_ptr
<MemoryBuffer
> getObject(const Module
* M
) override
{
263 const std::string
&ModuleID
= M
->getModuleIdentifier();
264 std::string CacheName
;
265 if (!getCacheFilename(ModuleID
, CacheName
))
267 // Load the object from the cache filename
268 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> IRObjectBuffer
=
269 MemoryBuffer::getFile(CacheName
, -1, false);
270 // If the file isn't there, that's OK.
273 // MCJIT will want to write into this buffer, and we don't want that
274 // because the file has probably just been mmapped. Instead we make
275 // a copy. The filed-based buffer will be released when it goes
277 return MemoryBuffer::getMemBufferCopy(IRObjectBuffer
.get()->getBuffer());
281 std::string CacheDir
;
283 bool getCacheFilename(const std::string
&ModID
, std::string
&CacheName
) {
284 std::string
Prefix("file:");
285 size_t PrefixLength
= Prefix
.length();
286 if (ModID
.substr(0, PrefixLength
) != Prefix
)
288 std::string CacheSubdir
= ModID
.substr(PrefixLength
);
290 // Transform "X:\foo" => "/X\foo" for convenience.
291 if (isalpha(CacheSubdir
[0]) && CacheSubdir
[1] == ':') {
292 CacheSubdir
[1] = CacheSubdir
[0];
293 CacheSubdir
[0] = '/';
296 CacheName
= CacheDir
+ CacheSubdir
;
297 size_t pos
= CacheName
.rfind('.');
298 CacheName
.replace(pos
, CacheName
.length() - pos
, ".o");
303 // On Mingw and Cygwin, an external symbol named '__main' is called from the
304 // generated 'main' function to allow static initialization. To avoid linking
305 // problems with remote targets (because lli's remote target support does not
306 // currently handle external linking) we add a secondary module which defines
307 // an empty '__main' function.
308 static void addCygMingExtraModule(ExecutionEngine
&EE
, LLVMContext
&Context
,
309 StringRef TargetTripleStr
) {
310 IRBuilder
<> Builder(Context
);
311 Triple
TargetTriple(TargetTripleStr
);
313 // Create a new module.
314 std::unique_ptr
<Module
> M
= make_unique
<Module
>("CygMingHelper", Context
);
315 M
->setTargetTriple(TargetTripleStr
);
317 // Create an empty function named "__main".
319 if (TargetTriple
.isArch64Bit())
320 ReturnTy
= Type::getInt64Ty(Context
);
322 ReturnTy
= Type::getInt32Ty(Context
);
324 Function::Create(FunctionType::get(ReturnTy
, {}, false),
325 GlobalValue::ExternalLinkage
, "__main", M
.get());
327 BasicBlock
*BB
= BasicBlock::Create(Context
, "__main", Result
);
328 Builder
.SetInsertPoint(BB
);
329 Value
*ReturnVal
= ConstantInt::get(ReturnTy
, 0);
330 Builder
.CreateRet(ReturnVal
);
332 // Add this new module to the ExecutionEngine.
333 EE
.addModule(std::move(M
));
336 CodeGenOpt::Level
getOptLevel() {
339 WithColor::error(errs(), "lli") << "invalid optimization level.\n";
341 case '0': return CodeGenOpt::None
;
342 case '1': return CodeGenOpt::Less
;
344 case '2': return CodeGenOpt::Default
;
345 case '3': return CodeGenOpt::Aggressive
;
347 llvm_unreachable("Unrecognized opt level.");
350 LLVM_ATTRIBUTE_NORETURN
351 static void reportError(SMDiagnostic Err
, const char *ProgName
) {
352 Err
.print(ProgName
, errs());
356 int runOrcLazyJIT(const char *ProgName
);
357 void disallowOrcOptions();
359 //===----------------------------------------------------------------------===//
360 // main Driver function
362 int main(int argc
, char **argv
, char * const *envp
) {
363 InitLLVM
X(argc
, argv
);
366 ExitOnErr
.setBanner(std::string(argv
[0]) + ": ");
368 // If we have a native target, initialize it to ensure it is linked in and
369 // usable by the JIT.
370 InitializeNativeTarget();
371 InitializeNativeTargetAsmPrinter();
372 InitializeNativeTargetAsmParser();
374 cl::ParseCommandLineOptions(argc
, argv
,
375 "llvm interpreter & dynamic compiler\n");
377 // If the user doesn't want core files, disable them.
378 if (DisableCoreFiles
)
379 sys::Process::PreventCoreFiles();
381 if (UseJITKind
== JITKind::OrcLazy
)
382 return runOrcLazyJIT(argv
[0]);
384 disallowOrcOptions();
388 // Load the bitcode...
390 std::unique_ptr
<Module
> Owner
= parseIRFile(InputFile
, Err
, Context
);
391 Module
*Mod
= Owner
.get();
393 reportError(Err
, argv
[0]);
395 if (EnableCacheManager
) {
396 std::string
CacheName("file:");
397 CacheName
.append(InputFile
);
398 Mod
->setModuleIdentifier(CacheName
);
401 // If not jitting lazily, load the whole bitcode file eagerly too.
402 if (NoLazyCompilation
) {
403 // Use *argv instead of argv[0] to work around a wrong GCC warning.
404 ExitOnError
ExitOnErr(std::string(*argv
) +
405 ": bitcode didn't read correctly: ");
406 ExitOnErr(Mod
->materializeAll());
409 std::string ErrorMsg
;
410 EngineBuilder
builder(std::move(Owner
));
411 builder
.setMArch(MArch
);
412 builder
.setMCPU(getCPUStr());
413 builder
.setMAttrs(getFeatureList());
414 if (RelocModel
.getNumOccurrences())
415 builder
.setRelocationModel(RelocModel
);
416 if (CMModel
.getNumOccurrences())
417 builder
.setCodeModel(CMModel
);
418 builder
.setErrorStr(&ErrorMsg
);
419 builder
.setEngineKind(ForceInterpreter
420 ? EngineKind::Interpreter
422 builder
.setUseOrcMCJITReplacement(UseJITKind
== JITKind::OrcMCJITReplacement
);
424 // If we are supposed to override the target triple, do so now.
425 if (!TargetTriple
.empty())
426 Mod
->setTargetTriple(Triple::normalize(TargetTriple
));
428 // Enable MCJIT if desired.
429 RTDyldMemoryManager
*RTDyldMM
= nullptr;
430 if (!ForceInterpreter
) {
432 RTDyldMM
= new ForwardingMemoryManager();
434 RTDyldMM
= new SectionMemoryManager();
436 // Deliberately construct a temp std::unique_ptr to pass in. Do not null out
437 // RTDyldMM: We still use it below, even though we don't own it.
438 builder
.setMCJITMemoryManager(
439 std::unique_ptr
<RTDyldMemoryManager
>(RTDyldMM
));
440 } else if (RemoteMCJIT
) {
441 WithColor::error(errs(), argv
[0])
442 << "remote process execution does not work with the interpreter.\n";
446 builder
.setOptLevel(getOptLevel());
448 TargetOptions Options
= InitTargetOptionsFromCodeGenFlags();
449 if (FloatABIForCalls
!= FloatABI::Default
)
450 Options
.FloatABIType
= FloatABIForCalls
;
452 builder
.setTargetOptions(Options
);
454 std::unique_ptr
<ExecutionEngine
> EE(builder
.create());
456 if (!ErrorMsg
.empty())
457 WithColor::error(errs(), argv
[0])
458 << "error creating EE: " << ErrorMsg
<< "\n";
460 WithColor::error(errs(), argv
[0]) << "unknown error creating EE!\n";
464 std::unique_ptr
<LLIObjectCache
> CacheManager
;
465 if (EnableCacheManager
) {
466 CacheManager
.reset(new LLIObjectCache(ObjectCacheDir
));
467 EE
->setObjectCache(CacheManager
.get());
470 // Load any additional modules specified on the command line.
471 for (unsigned i
= 0, e
= ExtraModules
.size(); i
!= e
; ++i
) {
472 std::unique_ptr
<Module
> XMod
= parseIRFile(ExtraModules
[i
], Err
, Context
);
474 reportError(Err
, argv
[0]);
475 if (EnableCacheManager
) {
476 std::string
CacheName("file:");
477 CacheName
.append(ExtraModules
[i
]);
478 XMod
->setModuleIdentifier(CacheName
);
480 EE
->addModule(std::move(XMod
));
483 for (unsigned i
= 0, e
= ExtraObjects
.size(); i
!= e
; ++i
) {
484 Expected
<object::OwningBinary
<object::ObjectFile
>> Obj
=
485 object::ObjectFile::createObjectFile(ExtraObjects
[i
]);
487 // TODO: Actually report errors helpfully.
488 consumeError(Obj
.takeError());
489 reportError(Err
, argv
[0]);
491 object::OwningBinary
<object::ObjectFile
> &O
= Obj
.get();
492 EE
->addObjectFile(std::move(O
));
495 for (unsigned i
= 0, e
= ExtraArchives
.size(); i
!= e
; ++i
) {
496 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> ArBufOrErr
=
497 MemoryBuffer::getFileOrSTDIN(ExtraArchives
[i
]);
499 reportError(Err
, argv
[0]);
500 std::unique_ptr
<MemoryBuffer
> &ArBuf
= ArBufOrErr
.get();
502 Expected
<std::unique_ptr
<object::Archive
>> ArOrErr
=
503 object::Archive::create(ArBuf
->getMemBufferRef());
506 raw_string_ostream
OS(Buf
);
507 logAllUnhandledErrors(ArOrErr
.takeError(), OS
);
512 std::unique_ptr
<object::Archive
> &Ar
= ArOrErr
.get();
514 object::OwningBinary
<object::Archive
> OB(std::move(Ar
), std::move(ArBuf
));
516 EE
->addArchive(std::move(OB
));
519 // If the target is Cygwin/MingW and we are generating remote code, we
520 // need an extra module to help out with linking.
521 if (RemoteMCJIT
&& Triple(Mod
->getTargetTriple()).isOSCygMing()) {
522 addCygMingExtraModule(*EE
, Context
, Mod
->getTargetTriple());
525 // The following functions have no effect if their respective profiling
526 // support wasn't enabled in the build configuration.
527 EE
->RegisterJITEventListener(
528 JITEventListener::createOProfileJITEventListener());
529 EE
->RegisterJITEventListener(
530 JITEventListener::createIntelJITEventListener());
532 EE
->RegisterJITEventListener(
533 JITEventListener::createPerfJITEventListener());
535 if (!NoLazyCompilation
&& RemoteMCJIT
) {
536 WithColor::warning(errs(), argv
[0])
537 << "remote mcjit does not support lazy compilation\n";
538 NoLazyCompilation
= true;
540 EE
->DisableLazyCompilation(NoLazyCompilation
);
542 // If the user specifically requested an argv[0] to pass into the program,
544 if (!FakeArgv0
.empty()) {
545 InputFile
= static_cast<std::string
>(FakeArgv0
);
547 // Otherwise, if there is a .bc suffix on the executable strip it off, it
548 // might confuse the program.
549 if (StringRef(InputFile
).endswith(".bc"))
550 InputFile
.erase(InputFile
.length() - 3);
553 // Add the module's name to the start of the vector of arguments to main().
554 InputArgv
.insert(InputArgv
.begin(), InputFile
);
556 // Call the main function from M as if its signature were:
557 // int main (int argc, char **argv, const char **envp)
558 // using the contents of Args to determine argc & argv, and the contents of
559 // EnvVars to determine envp.
561 Function
*EntryFn
= Mod
->getFunction(EntryFunc
);
563 WithColor::error(errs(), argv
[0])
564 << '\'' << EntryFunc
<< "\' function not found in module.\n";
568 // Reset errno to zero on entry to main.
573 // Sanity check use of remote-jit: LLI currently only supports use of the
574 // remote JIT on Unix platforms.
577 WithColor::warning(errs(), argv
[0])
578 << "host does not support external remote targets.\n";
579 WithColor::note() << "defaulting to local execution\n";
582 if (ChildExecPath
.empty()) {
583 WithColor::error(errs(), argv
[0])
584 << "-remote-mcjit requires -mcjit-remote-process.\n";
586 } else if (!sys::fs::can_execute(ChildExecPath
)) {
587 WithColor::error(errs(), argv
[0])
588 << "unable to find usable child executable: '" << ChildExecPath
596 // If the program doesn't explicitly call exit, we will need the Exit
597 // function later on to make an explicit call, so get the function now.
598 FunctionCallee Exit
= Mod
->getOrInsertFunction(
599 "exit", Type::getVoidTy(Context
), Type::getInt32Ty(Context
));
601 // Run static constructors.
602 if (!ForceInterpreter
) {
603 // Give MCJIT a chance to apply relocations and set page permissions.
604 EE
->finalizeObject();
606 EE
->runStaticConstructorsDestructors(false);
608 // Trigger compilation separately so code regions that need to be
609 // invalidated will be known.
610 (void)EE
->getPointerToFunction(EntryFn
);
611 // Clear instruction cache before code will be executed.
613 static_cast<SectionMemoryManager
*>(RTDyldMM
)->invalidateInstructionCache();
616 Result
= EE
->runFunctionAsMain(EntryFn
, InputArgv
, envp
);
618 // Run static destructors.
619 EE
->runStaticConstructorsDestructors(true);
621 // If the program didn't call exit explicitly, we should call it now.
622 // This ensures that any atexit handlers get called correctly.
623 if (Function
*ExitF
=
624 dyn_cast
<Function
>(Exit
.getCallee()->stripPointerCasts())) {
625 if (ExitF
->getFunctionType() == Exit
.getFunctionType()) {
626 std::vector
<GenericValue
> Args
;
627 GenericValue ResultGV
;
628 ResultGV
.IntVal
= APInt(32, Result
);
629 Args
.push_back(ResultGV
);
630 EE
->runFunction(ExitF
, Args
);
631 WithColor::error(errs(), argv
[0])
632 << "exit(" << Result
<< ") returned!\n";
636 WithColor::error(errs(), argv
[0]) << "exit defined with wrong prototype!\n";
639 // else == "if (RemoteMCJIT)"
641 // Remote target MCJIT doesn't (yet) support static constructors. No reason
642 // it couldn't. This is a limitation of the LLI implementation, not the
643 // MCJIT itself. FIXME.
645 // Lanch the remote process and get a channel to it.
646 std::unique_ptr
<FDRawChannel
> C
= launchRemote();
648 WithColor::error(errs(), argv
[0]) << "failed to launch remote JIT.\n";
652 // Create a remote target client running over the channel.
653 llvm::orc::ExecutionSession ES
;
654 ES
.setErrorReporter([&](Error Err
) { ExitOnErr(std::move(Err
)); });
655 typedef orc::remote::OrcRemoteTargetClient MyRemote
;
656 auto R
= ExitOnErr(MyRemote::Create(*C
, ES
));
658 // Create a remote memory manager.
659 auto RemoteMM
= ExitOnErr(R
->createRemoteMemoryManager());
661 // Forward MCJIT's memory manager calls to the remote memory manager.
662 static_cast<ForwardingMemoryManager
*>(RTDyldMM
)->setMemMgr(
663 std::move(RemoteMM
));
665 // Forward MCJIT's symbol resolution calls to the remote.
666 static_cast<ForwardingMemoryManager
*>(RTDyldMM
)->setResolver(
667 orc::createLambdaResolver(
668 [](const std::string
&Name
) { return nullptr; },
669 [&](const std::string
&Name
) {
670 if (auto Addr
= ExitOnErr(R
->getSymbolAddress(Name
)))
671 return JITSymbol(Addr
, JITSymbolFlags::Exported
);
672 return JITSymbol(nullptr);
675 // Grab the target address of the JIT'd main function on the remote and call
677 // FIXME: argv and envp handling.
678 JITTargetAddress Entry
= EE
->getFunctionAddress(EntryFn
->getName().str());
679 EE
->finalizeObject();
680 LLVM_DEBUG(dbgs() << "Executing '" << EntryFn
->getName() << "' at 0x"
681 << format("%llx", Entry
) << "\n");
682 Result
= ExitOnErr(R
->callIntVoid(Entry
));
684 // Like static constructors, the remote target MCJIT support doesn't handle
685 // this yet. It could. FIXME.
687 // Delete the EE - we need to tear it down *before* we terminate the session
688 // with the remote, otherwise it'll crash when it tries to release resources
689 // on a remote that has already been disconnected.
692 // Signal the remote target that we're done JITing.
693 ExitOnErr(R
->terminateSession());
699 static orc::IRTransformLayer::TransformFunction
createDebugDumper() {
700 switch (OrcDumpKind
) {
701 case DumpKind::NoDump
:
702 return [](orc::ThreadSafeModule TSM
,
703 const orc::MaterializationResponsibility
&R
) { return TSM
; };
705 case DumpKind::DumpFuncsToStdOut
:
706 return [](orc::ThreadSafeModule TSM
,
707 const orc::MaterializationResponsibility
&R
) {
710 for (const auto &F
: *TSM
.getModule()) {
711 if (F
.isDeclaration())
715 std::string
Name(F
.getName());
716 printf("%s ", Name
.c_str());
725 case DumpKind::DumpModsToStdOut
:
726 return [](orc::ThreadSafeModule TSM
,
727 const orc::MaterializationResponsibility
&R
) {
728 outs() << "----- Module Start -----\n"
729 << *TSM
.getModule() << "----- Module End -----\n";
734 case DumpKind::DumpModsToDisk
:
735 return [](orc::ThreadSafeModule TSM
,
736 const orc::MaterializationResponsibility
&R
) {
738 raw_fd_ostream
Out(TSM
.getModule()->getModuleIdentifier() + ".ll", EC
,
741 errs() << "Couldn't open " << TSM
.getModule()->getModuleIdentifier()
742 << " for dumping.\nError:" << EC
.message() << "\n";
745 Out
<< *TSM
.getModule();
749 llvm_unreachable("Unknown DumpKind");
752 static void exitOnLazyCallThroughFailure() { exit(1); }
754 int runOrcLazyJIT(const char *ProgName
) {
755 // Start setting up the JIT environment.
757 // Parse the main module.
758 orc::ThreadSafeContext
TSCtx(llvm::make_unique
<LLVMContext
>());
760 auto MainModule
= orc::ThreadSafeModule(
761 parseIRFile(InputFile
, Err
, *TSCtx
.getContext()), TSCtx
);
763 reportError(Err
, ProgName
);
765 const auto &TT
= MainModule
.getModule()->getTargetTriple();
766 orc::JITTargetMachineBuilder JTMB
=
767 TT
.empty() ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())
768 : orc::JITTargetMachineBuilder(Triple(TT
));
771 JTMB
.getTargetTriple().setArchName(MArch
);
773 JTMB
.setCPU(getCPUStr())
774 .addFeatures(getFeatureList())
775 .setRelocationModel(RelocModel
.getNumOccurrences()
776 ? Optional
<Reloc::Model
>(RelocModel
)
778 .setCodeModel(CMModel
.getNumOccurrences()
779 ? Optional
<CodeModel::Model
>(CMModel
)
782 DataLayout DL
= ExitOnErr(JTMB
.getDefaultDataLayoutForTarget());
784 auto J
= ExitOnErr(orc::LLLazyJIT::Create(
786 pointerToJITTargetAddress(exitOnLazyCallThroughFailure
),
787 LazyJITCompileThreads
));
790 J
->setPartitionFunction(orc::CompileOnDemandLayer::compileWholeModule
);
792 auto Dump
= createDebugDumper();
794 J
->setLazyCompileTransform([&](orc::ThreadSafeModule TSM
,
795 const orc::MaterializationResponsibility
&R
) {
796 if (verifyModule(*TSM
.getModule(), &dbgs())) {
797 dbgs() << "Bad module: " << *TSM
.getModule() << "\n";
800 return Dump(std::move(TSM
), R
);
802 J
->getMainJITDylib().setGenerator(
803 ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(DL
)));
805 orc::MangleAndInterner
Mangle(J
->getExecutionSession(), DL
);
806 orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides
;
807 ExitOnErr(CXXRuntimeOverrides
.enable(J
->getMainJITDylib(), Mangle
));
809 // Add the main module.
810 ExitOnErr(J
->addLazyIRModule(std::move(MainModule
)));
812 // Create JITDylibs and add any extra modules.
814 // Create JITDylibs, keep a map from argument index to dylib. We will use
815 // -extra-module argument indexes to determine what dylib to use for each
817 std::map
<unsigned, orc::JITDylib
*> IdxToDylib
;
818 IdxToDylib
[0] = &J
->getMainJITDylib();
819 for (auto JDItr
= JITDylibs
.begin(), JDEnd
= JITDylibs
.end();
820 JDItr
!= JDEnd
; ++JDItr
) {
821 IdxToDylib
[JITDylibs
.getPosition(JDItr
- JITDylibs
.begin())] =
822 &J
->createJITDylib(*JDItr
);
825 for (auto EMItr
= ExtraModules
.begin(), EMEnd
= ExtraModules
.end();
826 EMItr
!= EMEnd
; ++EMItr
) {
827 auto M
= parseIRFile(*EMItr
, Err
, *TSCtx
.getContext());
829 reportError(Err
, ProgName
);
831 auto EMIdx
= ExtraModules
.getPosition(EMItr
- ExtraModules
.begin());
832 assert(EMIdx
!= 0 && "ExtraModule should have index > 0");
833 auto JDItr
= std::prev(IdxToDylib
.lower_bound(EMIdx
));
834 auto &JD
= *JDItr
->second
;
836 J
->addLazyIRModule(JD
, orc::ThreadSafeModule(std::move(M
), TSCtx
)));
841 for (auto &ObjPath
: ExtraObjects
) {
842 auto Obj
= ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(ObjPath
)));
843 ExitOnErr(J
->addObjectFile(std::move(Obj
)));
846 // Generate a argument string.
847 std::vector
<std::string
> Args
;
848 Args
.push_back(InputFile
);
849 for (auto &Arg
: InputArgv
)
852 // Run any static constructors.
853 ExitOnErr(J
->runConstructors());
855 // Run any -thread-entry points.
856 std::vector
<std::thread
> AltEntryThreads
;
857 for (auto &ThreadEntryPoint
: ThreadEntryPoints
) {
858 auto EntryPointSym
= ExitOnErr(J
->lookup(ThreadEntryPoint
));
859 typedef void (*EntryPointPtr
)();
861 reinterpret_cast<EntryPointPtr
>(static_cast<uintptr_t>(EntryPointSym
.getAddress()));
862 AltEntryThreads
.push_back(std::thread([EntryPoint
]() { EntryPoint(); }));
865 J
->getExecutionSession().dump(llvm::dbgs());
868 auto MainSym
= ExitOnErr(J
->lookup("main"));
869 typedef int (*MainFnPtr
)(int, const char *[]);
870 std::vector
<const char *> ArgV
;
871 for (auto &Arg
: Args
)
872 ArgV
.push_back(Arg
.c_str());
873 ArgV
.push_back(nullptr);
875 int ArgC
= ArgV
.size() - 1;
877 reinterpret_cast<MainFnPtr
>(static_cast<uintptr_t>(MainSym
.getAddress()));
878 auto Result
= Main(ArgC
, (const char **)ArgV
.data());
880 // Wait for -entry-point threads.
881 for (auto &AltEntryThread
: AltEntryThreads
)
882 AltEntryThread
.join();
885 ExitOnErr(J
->runDestructors());
886 CXXRuntimeOverrides
.runDestructors();
891 void disallowOrcOptions() {
892 // Make sure nobody used an orc-lazy specific option accidentally.
894 if (LazyJITCompileThreads
!= 0) {
895 errs() << "-compile-threads requires -jit-kind=orc-lazy\n";
899 if (!ThreadEntryPoints
.empty()) {
900 errs() << "-thread-entry requires -jit-kind=orc-lazy\n";
905 errs() << "-per-module-lazy requires -jit-kind=orc-lazy\n";
910 std::unique_ptr
<FDRawChannel
> launchRemote() {
912 llvm_unreachable("launchRemote not supported on non-Unix platforms");
918 if (pipe(PipeFD
[0]) != 0 || pipe(PipeFD
[1]) != 0)
919 perror("Error creating pipe: ");
926 // Close the parent ends of the pipes
931 // Execute the child process.
932 std::unique_ptr
<char[]> ChildPath
, ChildIn
, ChildOut
;
934 ChildPath
.reset(new char[ChildExecPath
.size() + 1]);
935 std::copy(ChildExecPath
.begin(), ChildExecPath
.end(), &ChildPath
[0]);
936 ChildPath
[ChildExecPath
.size()] = '\0';
937 std::string ChildInStr
= utostr(PipeFD
[0][0]);
938 ChildIn
.reset(new char[ChildInStr
.size() + 1]);
939 std::copy(ChildInStr
.begin(), ChildInStr
.end(), &ChildIn
[0]);
940 ChildIn
[ChildInStr
.size()] = '\0';
941 std::string ChildOutStr
= utostr(PipeFD
[1][1]);
942 ChildOut
.reset(new char[ChildOutStr
.size() + 1]);
943 std::copy(ChildOutStr
.begin(), ChildOutStr
.end(), &ChildOut
[0]);
944 ChildOut
[ChildOutStr
.size()] = '\0';
947 char * const args
[] = { &ChildPath
[0], &ChildIn
[0], &ChildOut
[0], nullptr };
948 int rc
= execv(ChildExecPath
.c_str(), args
);
950 perror("Error executing child process: ");
951 llvm_unreachable("Error executing child process");
953 // else we're the parent...
955 // Close the child ends of the pipes
959 // Return an RPC channel connected to our end of the pipes.
960 return llvm::make_unique
<FDRawChannel
>(PipeFD
[1][0], PipeFD
[0][1]);