10 changes: 10 additions & 0 deletions llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
; XFAIL: mips, i686, i386, arm

declare i32 @FB()

define i32 @main() {
%r = call i32 @FB( ) ; <i32> [#uses=1]
ret i32 %r
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null

define i32 @bar() nounwind {
ret i32 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s
; XFAIL: *
; This test should fail until remote symbol resolution is supported.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
; XFAIL: *
; This function should fail until remote symbol resolution is supported.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -O0 -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s

; The intention of this test is to verify that symbols mapped to COMMON in ELF
; work as expected.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target%exeext %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target%exeext %s

; Check that a variable is always aligned as specified.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null

define double @test(double* %DP, double %Arg) nounwind {
%D = load double, double* %DP ; <double> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext %s > /dev/null

@count = global i32 1, align 4

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
; XFAIL: mips, aarch64, arm, i686, i386

@count = global i32 1, align 4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target%exeext %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target%exeext %s

@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
; XFAIL: mips, aarch64, arm, i686, i386

@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/ExecutionEngine/OrcMCJIT/simplesttest.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
ret i32 0
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @bar() {
ret i32 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
; XFAIL: mips, i686, i386, aarch64, arm

define i32 @main() nounwind {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -disable-lazy-compilation=false %s
; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false %s

define i32 @main() nounwind {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
%A = add i8 0, 12 ; <i8> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

; test unconditional branch
define i32 @main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @_Z14func_exit_codev() nounwind uwtable {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

declare void @exit(i32)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @foo() {
ret i32 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -O0 %s
; RUN: %lli -jit-kind=orc-mcjit -O0 %s

; This test checks that common symbols have been allocated addresses honouring
; the alignment requirement.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -O0 -disable-lazy-compilation=false %s
; RUN: %lli -jit-kind=orc-mcjit -O0 -disable-lazy-compilation=false %s

; The intention of this test is to verify that symbols mapped to COMMON in ELF
; work as expected.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

; This tests to make sure that we can evaluate weird constant expressions

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -O0 %s
; RUN: %lli -jit-kind=orc-mcjit -O0 %s

; Check that a variable is always aligned as specified.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define double @test(double* %DP, double %Arg) {
%D = load double, double* %DP ; <double> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define double @test(double* %DP, double %Arg) {
%D = load double, double* %DP ; <double> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null
; XFAIL: darwin
@var = global i32 1, align 4
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @ctor_func }]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -relocation-model=pic -code-model=small %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s > /dev/null
; XFAIL: mips, aarch64, arm, i686, i386

@count = global i32 1, align 4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

@count = global i32 1, align 4

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

@count = global i32 0, align 4

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define void @test(i8* %P, i16* %P.upgrd.1, i32* %P.upgrd.2, i64* %P.upgrd.3) {
%V = load i8, i8* %P ; <i8> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() nounwind uwtable {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
%A = and i8 4, 8 ; <i8> [#uses=2]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
; <label>:0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

; test phi node
@Y = global i32 6 ; <i32*> [#uses=1]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -O0 -relocation-model=pic -code-model=small %s
; RUN: %lli -jit-kind=orc-mcjit -O0 -relocation-model=pic -code-model=small %s
; XFAIL: mips, aarch64, arm, i686, i386

@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit -O0 %s
; RUN: %lli -jit-kind=orc-mcjit -O0 %s

@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

; test return instructions
define void @test1() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() nounwind uwtable {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null


define i32 @main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
%int1 = add i32 0, 0 ; <i32> [#uses=6]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: %lli -use-orcmcjit %s > /dev/null
; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null

define i32 @main() {
%shamt = add i8 0, 1 ; <i8> [#uses=8]
Expand Down
1 change: 1 addition & 0 deletions llvm/tools/lli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ endif( LLVM_USE_INTEL_JITEVENTS )

add_llvm_tool(lli
lli.cpp
OrcLazyJIT.cpp
RemoteMemoryManager.cpp
RemoteTarget.cpp
RemoteTargetExternal.cpp
Expand Down
53 changes: 53 additions & 0 deletions llvm/tools/lli/OrcLazyJIT.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "OrcLazyJIT.h"
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"

using namespace llvm;

std::unique_ptr<OrcLazyJIT::CompileCallbackMgr>
OrcLazyJIT::createCallbackMgr(Triple T, LLVMContext &Context) {
switch (T.getArch()) {
default:
// Flag error.
Error = true;
return nullptr;

case Triple::x86_64: {
typedef orc::JITCompileCallbackManager<CompileLayerT,
orc::OrcX86_64> CCMgrT;
return make_unique<CCMgrT>(CompileLayer, Context, 0, 64);
}
}
}

int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
OrcLazyJIT J(std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget()),
getGlobalContext());

if (!J.Ok()) {
errs() << "Could not construct JIT.\n";
return 1;
}

auto MainHandle = J.addModule(std::move(M));
auto MainSym = J.findSymbolIn(MainHandle, "main");

if (!MainSym) {
errs() << "Could not find main function.\n";
return 1;
}

typedef int (*MainFnPtr)(int, char*[]);
auto Main = reinterpret_cast<MainFnPtr>(
static_cast<uintptr_t>(MainSym.getAddress()));

return Main(ArgC, ArgV);
}
97 changes: 97 additions & 0 deletions llvm/tools/lli/OrcLazyJIT.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Simple Orc-based JIT. Uses the compile-on-demand layer to break up and
// lazily compile modules.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H
#define LLVM_TOOLS_LLI_ORCLAZYJIT_H

#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/IR/LLVMContext.h"

namespace llvm {

class OrcLazyJIT {
public:

typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
typedef orc::ObjectLinkingLayer<> ObjLayerT;
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
typedef orc::LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
typedef orc::CompileOnDemandLayer<LazyEmitLayerT,
CompileCallbackMgr> CODLayerT;
typedef typename CODLayerT::ModuleSetHandleT ModuleHandleT;

OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context)
: Error(false), TM(std::move(TM)),
Mang(this->TM->getDataLayout()),
ObjectLayer([](){ return llvm::make_unique<SectionMemoryManager>(); }),
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
LazyEmitLayer(CompileLayer),
CCMgr(createCallbackMgr(Triple(this->TM->getTargetTriple()), Context)),
CODLayer(LazyEmitLayer, *CCMgr) { }

bool Ok() const { return !Error; }

ModuleHandleT addModule(std::unique_ptr<Module> M) {
// Attach a data-layout if one isn't already present.
if (M->getDataLayout().isDefault())
M->setDataLayout(*TM->getDataLayout());

std::vector<std::unique_ptr<Module>> S;
S.push_back(std::move(M));
return CODLayer.addModuleSet(std::move(S));
}

orc::JITSymbol findSymbol(const std::string &Name) {
return CODLayer.findSymbol(mangle(Name), true);
}

orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
return CODLayer.findSymbolIn(H, mangle(Name), true);
}

private:

std::unique_ptr<CompileCallbackMgr>
createCallbackMgr(Triple T, LLVMContext &Context);

std::string mangle(const std::string &Name) {
std::string MangledName;
{
raw_string_ostream MangledNameStream(MangledName);
Mang.getNameWithPrefix(MangledNameStream, Name);
}
return MangledName;
}

bool Error;
std::unique_ptr<TargetMachine> TM;
Mangler Mang;

ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
LazyEmitLayerT LazyEmitLayer;
std::unique_ptr<CompileCallbackMgr> CCMgr;
CODLayerT CODLayer;
};

int runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]);

} // end namespace llvm

#endif
28 changes: 21 additions & 7 deletions llvm/tools/lli/lli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/IR/LLVMContext.h"
#include "OrcLazyJIT.h"
#include "RemoteMemoryManager.h"
#include "RemoteTarget.h"
#include "RemoteTargetExternal.h"
Expand Down Expand Up @@ -66,6 +67,9 @@ using namespace llvm;
#define DEBUG_TYPE "lli"

namespace {

enum class JITKind { MCJIT, OrcMCJITReplacement, OrcLazy };

cl::opt<std::string>
InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));

Expand All @@ -76,12 +80,19 @@ namespace {
cl::desc("Force interpretation: disable JIT"),
cl::init(false));

cl::opt<bool> UseOrcMCJITReplacement("use-orcmcjit",
cl::desc("Use the experimental "
"OrcMCJITReplacement as a "
"drop-in replacement for "
"MCJIT."),
cl::init(false));
cl::opt<JITKind> UseJITKind("jit-kind",
cl::desc("Choose underlying JIT kind."),
cl::init(JITKind::MCJIT),
cl::values(
clEnumValN(JITKind::MCJIT, "mcjit",
"MCJIT"),
clEnumValN(JITKind::OrcMCJITReplacement,
"orc-mcjit",
"Orc-based MCJIT replacement"),
clEnumValN(JITKind::OrcLazy,
"orc-lazy",
"Orc-based lazy JIT."),
clEnumValEnd));

// The MCJIT supports building for a target address space separate from
// the JIT compilation process. Use a forked process and a copying
Expand Down Expand Up @@ -404,6 +415,9 @@ int main(int argc, char **argv, char * const *envp) {
return 1;
}

if (UseJITKind == JITKind::OrcLazy)
return runOrcLazyJIT(std::move(Owner), argc, argv);

if (EnableCacheManager) {
std::string CacheName("file:");
CacheName.append(InputFile);
Expand All @@ -430,7 +444,7 @@ int main(int argc, char **argv, char * const *envp) {
builder.setEngineKind(ForceInterpreter
? EngineKind::Interpreter
: EngineKind::JIT);
builder.setUseOrcMCJITReplacement(UseOrcMCJITReplacement);
builder.setUseOrcMCJITReplacement(UseJITKind == JITKind::OrcMCJITReplacement);

// If we are supposed to override the target triple, do so now.
if (!TargetTriple.empty())
Expand Down