aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lli/OrcLazyJIT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lli/OrcLazyJIT.cpp')
-rw-r--r--tools/lli/OrcLazyJIT.cpp124
1 files changed, 109 insertions, 15 deletions
diff --git a/tools/lli/OrcLazyJIT.cpp b/tools/lli/OrcLazyJIT.cpp
index 4a8d3b9..ff8baf0 100644
--- a/tools/lli/OrcLazyJIT.cpp
+++ b/tools/lli/OrcLazyJIT.cpp
@@ -9,34 +9,130 @@
#include "OrcLazyJIT.h"
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include <system_error>
using namespace llvm;
-std::unique_ptr<OrcLazyJIT::CompileCallbackMgr>
-OrcLazyJIT::createCallbackMgr(Triple T, LLVMContext &Context) {
+namespace {
+
+ enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdErr,
+ DumpModsToDisk };
+
+ cl::opt<DumpKind> OrcDumpKind("orc-lazy-debug",
+ cl::desc("Debug dumping for the orc-lazy JIT."),
+ cl::init(DumpKind::NoDump),
+ cl::values(
+ clEnumValN(DumpKind::NoDump, "no-dump",
+ "Don't dump anything."),
+ clEnumValN(DumpKind::DumpFuncsToStdOut,
+ "funcs-to-stdout",
+ "Dump function names to stdout."),
+ clEnumValN(DumpKind::DumpModsToStdErr,
+ "mods-to-stderr",
+ "Dump modules to stderr."),
+ clEnumValN(DumpKind::DumpModsToDisk,
+ "mods-to-disk",
+ "Dump modules to the current "
+ "working directory. (WARNING: "
+ "will overwrite existing files)."),
+ clEnumValEnd));
+}
+
+OrcLazyJIT::CallbackManagerBuilder
+OrcLazyJIT::createCallbackManagerBuilder(Triple T) {
switch (T.getArch()) {
- default:
- // Flag error.
- Error = true;
- return nullptr;
+ default: return nullptr;
case Triple::x86_64: {
- typedef orc::JITCompileCallbackManager<CompileLayerT,
+ typedef orc::JITCompileCallbackManager<IRDumpLayerT,
orc::OrcX86_64> CCMgrT;
- return make_unique<CCMgrT>(CompileLayer, Context, 0, 64);
+ return [](IRDumpLayerT &IRDumpLayer, RuntimeDyld::MemoryManager &MemMgr,
+ LLVMContext &Context) {
+ return llvm::make_unique<CCMgrT>(IRDumpLayer, MemMgr, Context, 0,
+ 64);
+ };
}
}
}
+OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() {
+
+ switch (OrcDumpKind) {
+ case DumpKind::NoDump:
+ return [](std::unique_ptr<Module> M) { return std::move(M); };
+
+ case DumpKind::DumpFuncsToStdOut:
+ return [](std::unique_ptr<Module> M) {
+ printf("[ ");
+
+ for (const auto &F : *M) {
+ if (F.isDeclaration())
+ continue;
+
+ if (F.hasName()) {
+ std::string Name(F.getName());
+ printf("%s ", Name.c_str());
+ } else
+ printf("<anon> ");
+ }
+
+ printf("]\n");
+ return std::move(M);
+ };
+
+ case DumpKind::DumpModsToStdErr:
+ return [](std::unique_ptr<Module> M) {
+ dbgs() << "----- Module Start -----\n" << *M
+ << "----- Module End -----\n";
+
+ return std::move(M);
+ };
+
+ case DumpKind::DumpModsToDisk:
+ return [](std::unique_ptr<Module> M) {
+ std::error_code EC;
+ raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC,
+ sys::fs::F_Text);
+ if (EC) {
+ errs() << "Couldn't open " << M->getModuleIdentifier()
+ << " for dumping.\nError:" << EC.message() << "\n";
+ exit(1);
+ }
+ Out << *M;
+ return std::move(M);
+ };
+ }
+ llvm_unreachable("Unknown DumpKind");
+}
+
int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
- OrcLazyJIT J(std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget()),
- getGlobalContext());
+ // Add the program's symbols into the JIT's search space.
+ if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
+ errs() << "Error loading program symbols.\n";
+ return 1;
+ }
+
+ // Grab a target machine and try to build a factory function for the
+ // target-specific Orc callback manager.
+ auto TM = std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget());
+ auto &Context = getGlobalContext();
+ auto CallbackMgrBuilder =
+ OrcLazyJIT::createCallbackManagerBuilder(Triple(TM->getTargetTriple()));
- if (!J.Ok()) {
- errs() << "Could not construct JIT.\n";
+ // If we couldn't build the factory function then there must not be a callback
+ // manager for this target. Bail out.
+ if (!CallbackMgrBuilder) {
+ errs() << "No callback manager available for target '"
+ << TM->getTargetTriple() << "'.\n";
return 1;
}
+ // Everything looks good. Build the JIT.
+ OrcLazyJIT J(std::move(TM), Context, CallbackMgrBuilder);
+
+ // Add the module, look up main and run it.
auto MainHandle = J.addModule(std::move(M));
auto MainSym = J.findSymbolIn(MainHandle, "main");
@@ -46,8 +142,6 @@ int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
}
typedef int (*MainFnPtr)(int, char*[]);
- auto Main = reinterpret_cast<MainFnPtr>(
- static_cast<uintptr_t>(MainSym.getAddress()));
-
+ auto Main = OrcLazyJIT::fromTargetAddress<MainFnPtr>(MainSym.getAddress());
return Main(ArgC, ArgV);
}