Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 74 additions & 41 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,16 @@ ThisType (void)
}

static Address*
create_address (MonoLLVMModule *module, LLVMValueRef value, LLVMTypeRef type)
create_address (EmitContext *ctx, LLVMValueRef value, LLVMTypeRef type)
{
Address *res = (Address *)mono_mempool_alloc0 (ctx->mempool, sizeof(Address));
res->value = value;
res->type = type;
return res;
}

static Address*
create_module_address (MonoLLVMModule *module, LLVMValueRef value, LLVMTypeRef type)
{
Address *res = g_new0 (Address, 1);
res->value = value;
Expand All @@ -615,7 +624,7 @@ create_address (MonoLLVMModule *module, LLVMValueRef value, LLVMTypeRef type)
}

static void
address_free (gpointer addr)
free_module_address (gpointer addr)
{
g_free (addr);
}
Expand Down Expand Up @@ -1535,6 +1544,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
{
LLVMTypeRef ret_type;
LLVMTypeRef *param_types = NULL;
LLVMTypeRef *etypes = NULL;
LLVMTypeRef res;
int pindex, vret_arg_pindex = 0;
gboolean vretaddr = FALSE;
Expand Down Expand Up @@ -1618,7 +1628,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *

param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
if (element_types)
*element_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
etypes = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
pindex = 0;
if (cinfo->ret.storage == LLVMArgVtypeByRef) {
/*
Expand All @@ -1630,10 +1640,11 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
if (!ctx_ok (ctx)) {
g_free (param_types);
g_free (etypes);
return NULL;
}
if (element_types)
(*element_types) [pindex] = param_types [pindex];
if (etypes)
etypes [pindex] = param_types [pindex];
param_types [pindex] = pointer_type (param_types [pindex]);
pindex ++;
}
Expand Down Expand Up @@ -1707,8 +1718,8 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
if (!ctx_ok (ctx))
break;
if (element_types)
(*element_types) [pindex] = param_types [pindex];
if (etypes)
etypes [pindex] = param_types [pindex];
param_types [pindex] = pointer_type (param_types [pindex]);
pindex ++;
break;
Expand All @@ -1724,8 +1735,8 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
if (!ctx_ok (ctx))
break;
if (element_types)
(*element_types) [pindex] = param_types [pindex];
if (etypes)
etypes [pindex] = param_types [pindex];
param_types [pindex] = pointer_type (param_types [pindex]);
pindex ++;
break;
Expand All @@ -1746,13 +1757,13 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
break;
case LLVMArgGsharedvtFixed:
case LLVMArgGsharedvtFixedVtype:
if (element_types)
(*element_types) [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
if (etypes)
etypes [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
param_types [pindex ++] = pointer_type (type_to_llvm_arg_type (ctx, ainfo->type));
break;
case LLVMArgGsharedvtVariable:
if (element_types)
(*element_types) [pindex] = IntPtrType ();
if (etypes)
etypes [pindex] = IntPtrType ();
param_types [pindex ++] = pointer_type (IntPtrType ());
break;
default:
Expand All @@ -1762,6 +1773,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
}
if (!ctx_ok (ctx)) {
g_free (param_types);
g_free (etypes);
return NULL;
}
if (vretaddr && vret_arg_pindex == pindex)
Expand All @@ -1781,6 +1793,9 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
g_free (param_types);

if (element_types)
*element_types = etypes;

return res;
}

Expand Down Expand Up @@ -2055,15 +2070,16 @@ get_aotconst_module (MonoLLVMModule *module, LLVMBuilderRef builder, MonoJumpInf
// FIXME:
char *name = get_aotconst_name (ji->type, ji->data.target, got_offset);
char *symbol = g_strdup_printf ("aotconst_%s", name);
g_free (name);
LLVMValueRef v = LLVMAddGlobal (module->lmodule, const_var_type, symbol);
g_free (name);
g_free (symbol);
LLVMSetVisibility (v, LLVMHiddenVisibility);
LLVMSetLinkage (v, LLVMInternalLinkage);
LLVMSetInitializer (v, LLVMConstNull (const_var_type));
// FIXME:
LLVMSetAlignment (v, 8);

addr = create_address (module, v, const_var_type);
addr = create_module_address (module, v, const_var_type);
g_hash_table_insert (module->aotconst_vars, GINT_TO_POINTER (got_offset), addr);
}

Expand Down Expand Up @@ -2264,6 +2280,8 @@ get_callee_module (MonoLLVMModule *module, LLVMTypeRef llvm_sig, MonoJumpInfoTyp
LLVMSetVisibility (callee, LLVMHiddenVisibility);

g_hash_table_insert (module->plt_entries, (char*)callee_name, callee);
} else {
g_free (callee_name);
}

ji = g_new0 (MonoJumpInfo, 1);
Expand Down Expand Up @@ -2349,6 +2367,8 @@ get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gcons
LLVMSetVisibility (callee, LLVMHiddenVisibility);

g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
} else {
g_free (callee_name);
}

if (ctx->cfg->compile_aot) {
Expand Down Expand Up @@ -2956,7 +2976,7 @@ static Address*
build_alloca_address (EmitContext *ctx, MonoType *t)
{
LLVMValueRef v = build_named_alloca (ctx, t, "");
return create_address (ctx->module, v, type_to_llvm_type (ctx, t));
return create_address (ctx, v, type_to_llvm_type (ctx, t));
}

static LLVMValueRef
Expand Down Expand Up @@ -3546,7 +3566,7 @@ emit_init_func (MonoLLVMModule *module, MonoAotInitSubtype subtype)
LLVMDisposeBuilder (builder);
g_free (name);

return create_address (module, func, func_type);
return create_module_address (module, func, func_type);
}

/* Emit a wrapper around the parameterless JIT icall ICALL_ID with a cold calling convention */
Expand Down Expand Up @@ -3989,7 +4009,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
// FIXME: Count only live vregs
LLVMTypeRef pin_area_type = LLVMArrayType (IntPtrType (), ngc_vars);
LLVMValueRef gc_pin_area = build_alloca_llvm_type_name (ctx, pin_area_type, 0, "gc_pin");
ctx->gc_pin_area = create_address (ctx->module, gc_pin_area, pin_area_type);
ctx->gc_pin_area = create_address (ctx, gc_pin_area, pin_area_type);
#endif

/*
Expand All @@ -4012,11 +4032,11 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
// FIXME: Allocate a smaller struct in the deopt case
int size = cfg->deopt ? MONO_ABI_SIZEOF (MonoLMFExt) : MONO_ABI_SIZEOF (MonoLMF);
etype = LLVMArrayType (LLVMInt8Type (), size);
ctx->addresses [var->dreg] = create_address (ctx->module, build_alloca_llvm_type_name (ctx, etype, sizeof (target_mgreg_t), "lmf"), etype);
ctx->addresses [var->dreg] = create_address (ctx, build_alloca_llvm_type_name (ctx, etype, sizeof (target_mgreg_t), "lmf"), etype);
} else {
char *name = g_strdup_printf ("vreg_loc_%d", var->dreg);
etype = type_to_llvm_type (ctx, var->inst_vtype);
ctx->addresses [var->dreg] = create_address (ctx->module, build_named_alloca (ctx, var->inst_vtype, name), etype);
ctx->addresses [var->dreg] = create_address (ctx, build_named_alloca (ctx, var->inst_vtype, name), etype);
g_free (name);
}
}
Expand Down Expand Up @@ -4066,14 +4086,14 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
}
case LLVMArgVtypeByVal: {
g_assert (ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx->module, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
break;
}
case LLVMArgVtypeAddr:
case LLVMArgVtypeByRef: {
/* The argument is passed by ref */
g_assert (ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx->module, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
break;
}
case LLVMArgAsIArgs: {
Expand Down Expand Up @@ -4143,7 +4163,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
/* The IR treats these as variables with addresses */
if (!ctx->addresses [reg]) {
g_assert (ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx->module, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
ctx->addresses [reg] = create_address (ctx, LLVMGetParam (ctx->lmethod, pindex), ctx->param_etypes [pindex]);
}
break;
default: {
Expand Down Expand Up @@ -4286,7 +4306,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)

ctx->il_state = build_alloca_llvm_type_name (ctx, il_state_type, 0, "il_state");
g_assert (cfg->il_state_var);
ctx->addresses [cfg->il_state_var->dreg] = create_address (ctx->module, ctx->il_state, il_state_type);
ctx->addresses [cfg->il_state_var->dreg] = create_address (ctx, ctx->il_state, il_state_type);

/* Set il_state->il_offset = -1 */
index [0] = const_int32 (0);
Expand Down Expand Up @@ -4548,7 +4568,9 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
static int tramp_index;
char *name;

name = g_strdup_printf ("[tramp_%d] %s", tramp_index, mono_method_full_name (call->method, TRUE));
char *full_method_name = mono_method_full_name (call->method, TRUE);
name = g_strdup_printf ("[tramp_%d] %s", tramp_index, full_method_name);
g_free (full_method_name);
tramp_index ++;

/*
Expand All @@ -4571,7 +4593,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, tramp_var_type, name);
LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (const_int64 ((guint64)(size_t)target), tramp_var_type));
LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
tramp_var_addr = create_address (ctx->module, tramp_var, tramp_var_type);
tramp_var_addr = create_address (ctx, tramp_var, tramp_var_type);
g_hash_table_insert (ctx->jit_callees, call->method, tramp_var_addr);
}
callee = LLVMBuildLoad2 (builder, tramp_var_addr->type, tramp_var_addr->value, "");
Expand Down Expand Up @@ -4831,8 +4853,11 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
mono_llvm_set_call_notailcall (lcall);

// Add original method name we are currently emitting as a custom string metadata (the only way to leave comments in LLVM IR)
if (mono_debug_enabled () && call && call->method)
mono_llvm_add_string_metadata (lcall, "managed_name", mono_method_full_name (call->method, TRUE));
if (mono_debug_enabled () && call && call->method) {
char *full_method_name = mono_method_full_name (call->method, TRUE);
mono_llvm_add_string_metadata (lcall, "managed_name", full_method_name);
g_free (full_method_name);
}

// As per the LLVM docs, a function has a noalias return value if and only if
// it is an allocation function. This is an allocation function.
Expand Down Expand Up @@ -4963,6 +4988,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
values [ins->dreg] = LLVMBuildLoad2 (builder, rtype, addr, load_name);
}

g_free (param_etypes);
*builder_ref = ctx->builder;
}

Expand Down Expand Up @@ -7819,7 +7845,7 @@ MONO_RESTORE_WARNING

if (!addresses [ins->dreg]) {
LLVMTypeRef etype = type_to_llvm_type (ctx, m_class_get_byval_arg (klass));
addresses [ins->dreg] = create_address (ctx->module, build_named_alloca (ctx, m_class_get_byval_arg (klass), "vzero"), etype);
addresses [ins->dreg] = create_address (ctx, build_named_alloca (ctx, m_class_get_byval_arg (klass), "vzero"), etype);
}
LLVMValueRef ptr = build_ptr_cast (builder, addresses [ins->dreg]->value, pointer_type (LLVMInt8Type ()));
emit_memset (ctx, ptr, const_int32 (mono_class_value_size (klass, NULL)), 0);
Expand Down Expand Up @@ -7910,7 +7936,7 @@ MONO_RESTORE_WARNING
MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);

if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
addresses [ins->dreg] = create_address (ctx->module, convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), pointer_type (IntPtrType ())), IntPtrType ());
addresses [ins->dreg] = create_address (ctx, convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), pointer_type (IntPtrType ())), IntPtrType ());
} else {
g_assert (addresses [ins->sreg1]);
addresses [ins->dreg] = addresses [ins->sreg1];
Expand All @@ -7927,7 +7953,7 @@ MONO_RESTORE_WARNING

if (!addresses [ins->sreg1]) {
g_assert (!addresses [ins->dreg]);
addresses [ins->dreg] = create_address (ctx->module, build_named_alloca (ctx, t, "llvm_outarg_vt"), etype);
addresses [ins->dreg] = create_address (ctx, build_named_alloca (ctx, t, "llvm_outarg_vt"), etype);
g_assert (values [ins->sreg1]);
LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], etype), addresses [ins->dreg]->value);
} else if (ainfo->storage == LLVMArgVtypeAddr || values [ins->sreg1] == addresses [ins->sreg1]->value) {
Expand Down Expand Up @@ -11585,7 +11611,7 @@ MONO_RESTORE_WARNING
}
if (!addresses [ins->dreg]) {
LLVMTypeRef etype = type_to_llvm_type (ctx, m_class_get_byval_arg (ins->klass));
addresses [ins->dreg] = create_address (ctx->module, build_named_alloca (ctx, m_class_get_byval_arg (ins->klass), oname), etype);
addresses [ins->dreg] = create_address (ctx, build_named_alloca (ctx, m_class_get_byval_arg (ins->klass), oname), etype);
}
LLVMTypeRef ret_t = simd_valuetuple_to_llvm_type (ctx, ins->klass);
LLVMTypeRef vec_t = LLVMGetElementType (ret_t);
Expand Down Expand Up @@ -12614,7 +12640,9 @@ emit_method_inner (EmitContext *ctx)
int lcount = atoi (llvm_count_str);
g_free (llvm_count_str);
if (count == lcount) {
printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
char *full_method_name = mono_method_full_name (cfg->method, TRUE);
printf ("LAST: %s\n", full_method_name);
g_free (full_method_name);
fflush (stdout);
}
if (count > lcount) {
Expand Down Expand Up @@ -12962,7 +12990,7 @@ emit_method_inner (EmitContext *ctx)
values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);

if (ins->opcode == OP_VPHI)
ctx->addresses [ins->dreg] = create_address (ctx->module, values [ins->dreg], etype);
ctx->addresses [ins->dreg] = create_address (ctx, values [ins->dreg], etype);

g_ptr_array_add (ctx->phi_values, values [ins->dreg]);

Expand Down Expand Up @@ -13263,7 +13291,9 @@ emit_method_inner (EmitContext *ctx)
}

if (cfg->verbose_level > 1) {
g_print ("\n*** Unoptimized LLVM IR for %s ***\n", mono_method_full_name (cfg->method, TRUE));
char *full_method_name = mono_method_full_name (cfg->method, TRUE);
g_print ("\n*** Unoptimized LLVM IR for %s ***\n", full_method_name);
g_free (full_method_name);
if (cfg->compile_aot) {
mono_llvm_dump_value (method);
} else {
Expand Down Expand Up @@ -13706,11 +13736,11 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix,
module->max_got_offset = initial_got_size;
module->context = LLVMGetGlobalContext ();
module->cfgs = g_ptr_array_new ();
module->aotconst_vars = g_hash_table_new_full (NULL, NULL, NULL, address_free);
module->aotconst_vars = g_hash_table_new_full (NULL, NULL, NULL, free_module_address);
module->llvm_types = g_hash_table_new (NULL, NULL);
module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
module->plt_entries_ji = g_hash_table_new (NULL, NULL);
module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
module->plt_entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
module->plt_entries_ji = g_hash_table_new_full (NULL, NULL, g_free, NULL);
module->direct_callables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
module->method_to_lmethod = g_hash_table_new (NULL, NULL);
module->method_to_call_info = g_hash_table_new (NULL, NULL);
Expand Down Expand Up @@ -13789,15 +13819,15 @@ mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix,
LLVMSetVisibility (dummy_got_var, LLVMHiddenVisibility);
LLVMSetLinkage (dummy_got_var, LLVMInternalLinkage);

module->dummy_got_var = create_address (module, dummy_got_var, got_type);
module->dummy_got_var = create_module_address (module, dummy_got_var, got_type);
}

/* Add initialization array */
LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);

LLVMValueRef inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
LLVMSetInitializer (inited_var, LLVMConstNull (inited_type));
module->inited_var = create_address (module, inited_var, inited_type);
module->inited_var = create_module_address (module, inited_var, inited_type);

create_aot_info_var (module);

Expand Down Expand Up @@ -13845,12 +13875,15 @@ mono_llvm_free_aot_module (void)
g_hash_table_destroy (module->method_to_lmethod);
g_hash_table_destroy (module->method_to_call_info);
g_hash_table_destroy (module->idx_to_unbox_tramp);
g_hash_table_destroy (module->got_idx_to_type);
g_hash_table_destroy (module->no_method_table_lmethods);
g_hash_table_destroy (module->intrins_id_to_intrins);
g_hash_table_destroy (module->intrins_id_to_type);

g_ptr_array_free (module->cfgs, TRUE);
g_ptr_array_free (module->callsite_list, TRUE);
if (module->used)
g_ptr_array_free (module->used, TRUE);
}

void
Expand Down