#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
-#if LLVM_API_VERSION >= 500
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
-#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
-#else
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
-#endif
#include <cstdlib>
class MonoLLVMJIT {
public:
/* We use our own trampoline infrastructure instead of the Orc one */
-#if LLVM_API_VERSION >= 500
- typedef RTDyldObjectLinkingLayer ObjLayerT;
- typedef IRCompileLayer<ObjLayerT, SimpleCompiler> CompileLayerT;
- typedef CompileLayerT::ModuleHandleT ModuleHandleT;
-#else
typedef ObjectLinkingLayer<> ObjLayerT;
typedef IRCompileLayer<ObjLayerT> CompileLayerT;
typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
-#endif
- MonoLLVMJIT (TargetMachine *TM, MonoJitMemoryManager *mm)
-#if LLVM_API_VERSION >= 500
- : TM(TM), ObjectLayer([=] { return std::shared_ptr<RuntimeDyld::MemoryManager> (mm); }),
-#else
+ MonoLLVMJIT (TargetMachine *TM)
: TM(TM),
-#endif
- CompileLayer (ObjectLayer, SimpleCompiler (*TM)),
- modules() {
+ CompileLayer (ObjectLayer, SimpleCompiler (*TM)) {
}
-#if LLVM_API_VERSION >= 500
- ModuleHandleT addModule(Function *F, std::shared_ptr<Module> M) {
-#else
- ModuleHandleT addModule(Function *F, Module *M) {
-#endif
+ ModuleHandleT addModule(Module *M) {
auto Resolver = createLambdaResolver(
[&](const std::string &Name) {
const char *name = Name.c_str ();
-#if LLVM_API_VERSION >= 500
- JITSymbolFlags flags = JITSymbolFlags ();
-#else
- JITSymbolFlags flags = (JITSymbolFlags)0;
-#endif
- if (!strcmp (name, "___bzero")) {
-#if LLVM_API_VERSION >= 500
- return JITSymbol((uint64_t)(gssize)(void*)bzero, flags);
-#else
- return RuntimeDyld::SymbolInfo((uint64_t)(gssize)(void*)bzero, flags);
-#endif
- }
+ if (!strcmp (name, "___bzero"))
+ return RuntimeDyld::SymbolInfo((uint64_t)(gssize)(void*)bzero, (JITSymbolFlags)0);
MonoDl *current;
char *err;
if (!symbol)
outs () << "R: " << Name << "\n";
assert (symbol);
-#if LLVM_API_VERSION >= 500
- return JITSymbol((uint64_t)(gssize)symbol, flags);
-#else
- return RuntimeDyld::SymbolInfo((uint64_t)(gssize)symbol, flags);
-#endif
+ return RuntimeDyld::SymbolInfo((uint64_t)(gssize)symbol, (JITSymbolFlags)0);
},
[](const std::string &S) {
outs () << "R2: " << S << "\n";
return nullptr;
} );
-#if LLVM_API_VERSION >= 500
- ModuleHandleT m = CompileLayer.addModule(M,
- std::move(Resolver));
- return m;
-#else
return CompileLayer.addModuleSet(singletonSet(M),
make_unique<MonoJitMemoryManager>(),
std::move(Resolver));
-#endif
}
std::string mangle(const std::string &Name) {
gpointer compile (Function *F, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame) {
F->getParent ()->setDataLayout (TM->createDataLayout ());
-#if LLVM_API_VERSION >= 500
- // Orc uses a shared_ptr to refer to modules so we have to save them ourselves to keep a ref
- std::shared_ptr<Module> m (F->getParent ());
- modules.push_back (m);
- auto ModuleHandle = addModule (F, m);
-#else
- auto ModuleHandle = addModule (F, F->getParent ());
-#endif
+ auto ModuleHandle = addModule (F->getParent ());
+
auto BodySym = CompileLayer.findSymbolIn(ModuleHandle, mangle (F), false);
auto BodyAddr = BodySym.getAddress();
assert (BodyAddr);
TargetMachine *TM;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
- std::vector<std::shared_ptr<Module>> modules;
};
static MonoLLVMJIT *jit;
-static MonoJitMemoryManager *mono_mm;
MonoEERef
mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
auto TM = EB.selectTarget ();
assert (TM);
- mono_mm = new MonoJitMemoryManager ();
- jit = new MonoLLVMJIT (TM, mono_mm);
+ jit = new MonoLLVMJIT (TM);
return NULL;
}
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DIBuilder.h>
-#include <llvm/IR/CallSite.h>
#include "mini-llvm-cpp.h"
LLVMValueRef ArraySize,
int alignment, const char *Name)
{
-#if LLVM_API_VERSION >= 500
- return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), 0, unwrap (ArraySize), alignment), Name));
-#else
return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
-#endif
}
LLVMValueRef
#endif
}
-static Attribute::AttrKind
-convert_attr (AttrKind kind)
-{
- switch (kind) {
- case LLVM_ATTR_NO_UNWIND:
- return Attribute::NoUnwind;
- case LLVM_ATTR_NO_INLINE:
- return Attribute::NoInline;
- case LLVM_ATTR_OPTIMIZE_FOR_SIZE:
- return Attribute::OptimizeForSize;
- case LLVM_ATTR_IN_REG:
- return Attribute::InReg;
- case LLVM_ATTR_STRUCT_RET:
- return Attribute::StructRet;
- case LLVM_ATTR_NO_ALIAS:
- return Attribute::NoAlias;
- case LLVM_ATTR_BY_VAL:
- return Attribute::ByVal;
- case LLVM_ATTR_UW_TABLE:
- return Attribute::UWTable;
- default:
- assert (0);
- return Attribute::NoUnwind;
- }
-}
-
-void
-mono_llvm_add_func_attr (LLVMValueRef func, AttrKind kind)
-{
-#if LLVM_API_VERSION > 100
- unwrap<Function> (func)->addAttribute (AttributeList::FunctionIndex, convert_attr (kind));
-#else
- unwrap<Function> (func)->addFnAttr (convert_attr (kind));
-#endif
-}
-
-void
-mono_llvm_add_param_attr (LLVMValueRef param, AttrKind kind)
-{
-#if LLVM_API_VERSION > 100
- Function *func = unwrap<Argument> (param)->getParent ();
- int n = unwrap<Argument> (param)->getArgNo ();
- func->addParamAttr (n, convert_attr (kind));
-#else
- Argument *A = unwrap<Argument>(param);
- AttrBuilder B(convert_attr (kind));
- A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
-#endif
-}
-
-void
-mono_llvm_add_instr_attr (LLVMValueRef val, int index, AttrKind kind)
-{
-#if LLVM_API_VERSION > 100
- CallSite (unwrap<Instruction> (val)).addAttribute (index, convert_attr (kind));
-#else
- CallSite Call = CallSite(unwrap<Instruction>(val));
- AttrBuilder B(convert_attr (kind));
- Call.setAttributes(
- Call.getAttributes().addAttributes(Call->getContext(), index,
- AttributeSet::get(Call->getContext(),
- index, B)));
-#endif
-}
-
#if LLVM_API_VERSION > 100
void*
{
DIBuilder *builder = (DIBuilder*)di_builder;
-#if LLVM_API_VERSION >= 500
- DIFile *di_file;
-
- di_file = builder->createFile (cu_name, dir);
- return builder->createCompileUnit (dwarf::DW_LANG_C99, di_file, producer, true, "", 0);
-#else
return builder->createCompileUnit (dwarf::DW_LANG_C99, cu_name, dir, producer, true, "", 0);
-#endif
}
void*
func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
LLVMSetLinkage (func, LLVMExternalLinkage);
LLVMSetVisibility (func, LLVMHiddenVisibility);
- mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
+ LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
module->get_method = func;
entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
LLVMSetLinkage (func, LLVMExternalLinkage);
LLVMSetVisibility (func, LLVMHiddenVisibility);
- mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
+ LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
module->get_unbox_tramp = func;
entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
LLVMSetLinkage (func, LLVMInternalLinkage);
- mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
+ LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
module->code_start = func;
entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
builder = LLVMCreateBuilder ();
g_assert_not_reached ();
}
LLVMSetLinkage (func, LLVMInternalLinkage);
- mono_llvm_add_func_attr (func, LLVM_ATTR_NO_INLINE);
+ LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
mono_llvm_set_preserveall_cc (func);
entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
builder = LLVMCreateBuilder ();
func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
LLVMSetLinkage (func, LLVMInternalLinkage);
- mono_llvm_add_func_attr (func, LLVM_ATTR_NO_UNWIND);
+ LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
module->code_end = func;
entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
builder = LLVMCreateBuilder ();
tramp_name = g_strdup_printf ("ut_%s", method_name);
tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
LLVMSetLinkage (tramp, LLVMInternalLinkage);
- mono_llvm_add_func_attr (tramp, LLVM_ATTR_OPTIMIZE_FOR_SIZE);
- //mono_llvm_add_func_attr (tramp, LLVM_ATTR_NO_UNWIND);
+ LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
+ //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
linfo = ctx->linfo;
// FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
- mono_llvm_add_param_attr (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVM_ATTR_IN_REG);
+ LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
if (ctx->cfg->vret_addr) {
LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
if (linfo->ret.storage == LLVMArgVtypeByRef) {
- mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
- mono_llvm_add_param_attr (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
+ LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
+ LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
}
}
}
call = LLVMBuildCall (builder, method, args, nargs, "");
if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
- mono_llvm_add_instr_attr (call, 1 + ctx->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
+ LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
if (linfo->ret.storage == LLVMArgVtypeByRef)
- mono_llvm_add_instr_attr (call, 1 + linfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
+ LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
// FIXME: This causes assertions in clang
//mono_llvm_set_must_tail (call);
mono_llvm_set_call_preserveall_cc (lcall);
if (cinfo->ret.storage == LLVMArgVtypeByRef)
- mono_llvm_add_instr_attr (lcall, 1 + cinfo->vret_arg_pindex, LLVM_ATTR_STRUCT_RET);
+ LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
if (!ctx->llvm_only && call->rgctx_arg_reg)
- mono_llvm_add_instr_attr (lcall, 1 + cinfo->rgctx_arg_pindex, LLVM_ATTR_IN_REG);
+ LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
if (call->imt_arg_reg)
- mono_llvm_add_instr_attr (lcall, 1 + cinfo->imt_arg_pindex, LLVM_ATTR_IN_REG);
+ LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
/* Add byval attributes if needed */
for (i = 0; i < sig->param_count; ++i) {
LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
- mono_llvm_add_instr_attr (lcall, 1 + ainfo->pindex, LLVM_ATTR_BY_VAL);
+ LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
}
/*
g_assert (personality);
} else {
#if LLVM_API_VERSION > 100
- /* Can't cache this as each method is in its own llvm module */
- LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
- personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
- mono_llvm_add_func_attr (personality, LLVM_ATTR_NO_UNWIND);
- LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
- LLVMBuilderRef builder2 = LLVMCreateBuilder ();
- LLVMPositionBuilderAtEnd (builder2, entry_bb);
- LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
- LLVMDisposeBuilder (builder2);
+ personality = ctx->module->personality;
+ if (!personality) {
+ LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
+ personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
+ LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
+ LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
+ LLVMBuilderRef builder2 = LLVMCreateBuilder ();
+ LLVMPositionBuilderAtEnd (builder2, entry_bb);
+ LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
+ ctx->module->personality = personality;
+ LLVMDisposeBuilder (builder2);
+ }
#else
static gint32 mapping_inited;
args [0] = lhs;
args [1] = rhs;
/* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
-#if LLVM_API_VERSION >= 500
- args [2] = LLVMConstInt (LLVMInt8Type (), 0xf1, FALSE);
-#else
args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
-#endif
values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
break;
if (cfg->compile_aot)
ctx->lmodule = ctx->module->lmodule;
else
- ctx->lmodule = LLVMModuleCreateWithName (g_strdup_printf ("jit-module-%s", cfg->method->name));
+ ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
#else
ctx->lmodule = ctx->module->lmodule;
#endif
LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
LLVMSetLinkage (method, LLVMPrivateLinkage);
- mono_llvm_add_func_attr (method, LLVM_ATTR_UW_TABLE);
+ LLVMAddFunctionAttr (method, LLVMUWTable);
if (cfg->compile_aot) {
LLVMSetLinkage (method, LLVMInternalLinkage);
}
if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
/* We can't handle inlined methods with clauses */
- mono_llvm_add_func_attr (method, LLVM_ATTR_NO_INLINE);
+ LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
if (linfo->rgctx_arg) {
ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
* CC_X86_64_Mono in X86CallingConv.td.
*/
if (!ctx->llvm_only)
- mono_llvm_add_param_attr (ctx->rgctx_arg, LLVM_ATTR_IN_REG);
+ LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
LLVMSetValueName (ctx->rgctx_arg, "rgctx");
} else {
ctx->rgctx_arg_pindex = -1;
values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
if (linfo->ret.storage == LLVMArgVtypeByRef) {
- mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_STRUCT_RET);
- mono_llvm_add_param_attr (LLVMGetParam (method, linfo->vret_arg_pindex), LLVM_ATTR_NO_ALIAS);
+ LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
+ LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
}
}
LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
g_free (name);
if (ainfo->storage == LLVMArgVtypeByVal)
- mono_llvm_add_param_attr (LLVMGetParam (method, pindex), LLVM_ATTR_BY_VAL);
+ LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
if (ainfo->storage == LLVMArgVtypeByRef) {
/* For OP_LDADDR */
ret_type = type_to_simd_type (MONO_TYPE_R4);
arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
-#if LLVM_API_VERSION >= 500
- arg_types [2] = LLVMInt8Type ();
-#else
arg_types [2] = LLVMInt32Type ();
-#endif
AddFunc (module, name, ret_type, arg_types, 3);
break;
#endif