X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Fmini-llvm.c;h=fd822480af158b26346703d6b756b6642d8b67a9;hb=8170bf67b1e630a8eb7d3fa0cb7c191c38f5c663;hp=9ac07631f30f204a1937efea1dd53191e0ab81a5;hpb=9b3232e7df30dc895bf1d033196d106ae555c4a0;p=mono.git diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 9ac07631f30..fd822480af1 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -9,6 +9,7 @@ #include #include #include +#include #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS @@ -325,11 +326,14 @@ type_to_llvm_type (EmitContext *ctx, MonoType *t) case MONO_TYPE_SZARRAY: case MONO_TYPE_STRING: case MONO_TYPE_PTR: - return LLVMPointerType (IntPtrType (), 0); + return IntPtrType (); case MONO_TYPE_VAR: case MONO_TYPE_MVAR: /* Because of generic sharing */ - return IntPtrType (); + if (mini_type_var_is_vt (ctx->cfg, t)) + return type_to_llvm_type (ctx, mini_get_gsharedvt_alloc_type_for_type (ctx->cfg, t)); + else + return IntPtrType (); case MONO_TYPE_GENERICINST: if (!mono_type_generic_inst_is_valuetype (t)) return IntPtrType (); @@ -729,16 +733,6 @@ simd_op_to_intrins (int opcode) return "llvm.x86.sse.rsqrt.ps"; case OP_RCPPS: return "llvm.x86.sse.rcp.ps"; - case OP_PCMPEQB: - return "llvm.x86.sse2.pcmpeq.b"; - case OP_PCMPEQW: - return "llvm.x86.sse2.pcmpeq.w"; - case OP_PCMPEQD: - return "llvm.x86.sse2.pcmpeq.d"; - case OP_PCMPEQQ: - return "llvm.x86.sse41.pcmpeqq"; - case OP_PCMPGTB: - return "llvm.x86.sse2.pcmpgt.b"; case OP_CVTDQ2PD: return "llvm.x86.sse2.cvtdq2pd"; case OP_CVTDQ2PS: @@ -1053,7 +1047,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo * } else { g_assert_not_reached (); } - } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) { + } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) { g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr); vretaddr = TRUE; ret_type = LLVMVoidType (); @@ -1526,9 +1520,6 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex ctx->ex_index ++; return; - - FAILURE: - return; } /* @@ -1692,7 +1683,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder) MonoInst *var = cfg->varinfo [i]; LLVMTypeRef vtype; - if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) { + if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) { vtype = type_to_llvm_type (ctx, var->inst_vtype); CHECK_FAILURE (ctx); /* Could be already created by an OP_VPHI */ @@ -1745,7 +1736,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder) if (sig->hasthis) emit_volatile_store (ctx, cfg->args [0]->dreg); for (i = 0; i < sig->param_count; ++i) - if (!MONO_TYPE_ISSTRUCT (sig->params [i])) + if (!mini_type_is_vtype (cfg, sig->params [i])) emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg); if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) { @@ -1833,7 +1824,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef *args; LLVMCallInfo *cinfo; GSList *l; - int i, len; + int i, len, nargs; gboolean vretaddr; LLVMTypeRef llvm_sig; gpointer target; @@ -1955,23 +1946,27 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, /* * Collect and convert arguments */ - len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg); + nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg; + len = sizeof (LLVMValueRef) * nargs; args = alloca (len); memset (args, 0, len); l = call->out_ireg_args; if (call->rgctx_arg_reg) { g_assert (values [call->rgctx_arg_reg]); + g_assert (sinfo.rgctx_arg_pindex < nargs); args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg]; } if (call->imt_arg_reg) { g_assert (values [call->imt_arg_reg]); + g_assert (sinfo.imt_arg_pindex < nargs); args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg]; } if (vretaddr) { if (!addresses [call->inst.dreg]) addresses [call->inst.dreg] = build_alloca (ctx, sig->ret); + g_assert (sinfo.vret_arg_pindex < nargs); args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), ""); } @@ -2099,10 +2094,11 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) BBInfo *bblocks = ctx->bblocks; MonoInst *ins; LLVMBasicBlockRef cbb; - LLVMBuilderRef builder; + LLVMBuilderRef builder, starting_builder; gboolean has_terminator; LLVMValueRef v; LLVMValueRef lhs, rhs; + int nins = 0; cbb = get_bb (ctx, bb); builder = create_builder (ctx); @@ -2161,14 +2157,20 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name); LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE)); - LLVMSetLinkage (type_info, LLVMPrivateLinkage); - LLVMSetVisibility (type_info, LLVMHiddenVisibility); + /* + * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM. + */ + LLVMSetLinkage (type_info, LLVMInternalLinkage); /* * Enabling this causes llc to crash: * http://llvm.org/bugs/show_bug.cgi?id=6102 */ //LLVM_FAILURE (ctx, "aot+clauses"); +#ifdef TARGET_ARM + // test_0_invalid_unbox_arrays () fails + LLVM_FAILURE (ctx, "aot+clauses"); +#endif } else { /* * After the cfg mempool is freed, the type info will point to stale memory, @@ -2220,11 +2222,18 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) } has_terminator = FALSE; + starting_builder = builder; for (ins = bb->code; ins; ins = ins->next) { const char *spec = LLVM_INS_INFO (ins->opcode); char *dname = NULL; char dname_buf [128]; + nins ++; + if (nins > 5000 && builder == starting_builder) { + /* some steps in llc are non-linear in the size of basic blocks, see #5714 */ + LLVM_FAILURE (ctx, "basic block too long"); + } + if (has_terminator) /* There could be instructions after a terminator, skip them */ break; @@ -2770,7 +2779,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) break; case OP_INOT: { guint32 v = 0xffffffff; - values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname); + values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname); break; } case OP_LNOT: { @@ -3036,7 +3045,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) } case OP_CHECK_THIS: - emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE); + emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE); break; case OP_OUTARG_VTRETADDR: break; @@ -3151,14 +3160,14 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) */ LLVM_FAILURE (ctx, "sqrt"); #endif - args [0] = lhs; + args [0] = convert (ctx, lhs, LLVMDoubleType ()); values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname); break; } case OP_ABS: { LLVMValueRef args [1]; - args [0] = lhs; + args [0] = convert (ctx, lhs, LLVMDoubleType ()); values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname); break; } @@ -3273,7 +3282,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) #endif } case OP_TLS_GET: { -#if defined(TARGET_AMD64) || defined(TARGET_X86) +#if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__) #ifdef TARGET_AMD64 // 257 == FS segment register LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257); @@ -3366,6 +3375,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) break; } + if (mini_is_gsharedvt_klass (cfg, klass)) { + // FIXME: + LLVM_FAILURE (ctx, "gsharedvt"); + break; + } + switch (ins->opcode) { case OP_STOREV_MEMBASE: if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) { @@ -3572,11 +3587,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) case OP_PSUBW_SAT_UN: case OP_PAVGB_UN: case OP_PAVGW_UN: - case OP_PCMPEQB: - case OP_PCMPEQW: - case OP_PCMPEQD: - case OP_PCMPEQQ: - case OP_PCMPGTB: case OP_PACKW: case OP_PACKD: case OP_PACKW_UN: @@ -3591,6 +3601,17 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname); break; } + case OP_PCMPEQB: + case OP_PCMPEQW: + case OP_PCMPEQD: + case OP_PCMPEQQ: { + values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), ""); + break; + } + case OP_PCMPGTB: { + values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), ""); + break; + } case OP_EXTRACT_R8: case OP_EXTRACT_I8: case OP_EXTRACT_I4: @@ -3749,7 +3770,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) case OP_PSHUFLEW_LOW: case OP_PSHUFLEW_HIGH: { int mask [16]; - LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4]; + LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16]; int i, mask_size = 0; int imask = ins->inst_c0; @@ -3977,7 +3998,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) else ctx->lmodule->throw = callee; } - arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg)); + arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg)); emit_call (ctx, bb, &builder, callee, &arg, 1); break; } @@ -4106,18 +4127,16 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) void mono_llvm_check_method_supported (MonoCompile *cfg) { - /* MonoMethodHeader *header = cfg->header; MonoExceptionClause *clause; int i; - */ if (cfg->method->save_lmf) { cfg->exception_message = g_strdup ("lmf"); cfg->disable_llvm = TRUE; } -#if 0 +#if 1 for (i = 0; i < header->num_clauses; ++i) { clause = &header->clauses [i]; @@ -4456,7 +4475,9 @@ mono_llvm_emit_method (MonoCompile *cfg) if (ctx->unreachable [node->in_bb->block_num]) continue; - g_assert (values [sreg1]); + if (!values [sreg1]) + /* Can happen with values in EH clauses */ + LLVM_FAILURE (ctx, "incoming phi sreg1"); if (phi->opcode == OP_VPHI) { g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg])); @@ -4592,7 +4613,7 @@ mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call) switch (ainfo->storage) { case LLVMArgInIReg: case LLVMArgInFPReg: { - MonoType *t = (sig->hasthis && i == 0) ? &mono_defaults.int_class->byval_arg : sig->params [i - sig->hasthis]; + MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis]; if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) { MONO_INST_NEW (cfg, ins, OP_FMOVE); @@ -4732,6 +4753,27 @@ exception_cb (void *data) g_free (type_info); } +static char* +dlsym_cb (const char *name, void **symbol) +{ + MonoDl *current; + char *err; + + err = NULL; + if (!strcmp (name, "__bzero")) { + *symbol = (void*)bzero; + } else { + current = mono_dl_open (NULL, 0, NULL); + g_assert (current); + + err = mono_dl_symbol (current, name, symbol); + } +#ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK + *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol)); +#endif + return err; +} + static inline void AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams) { @@ -4844,7 +4886,6 @@ add_intrinsics (LLVMModuleRef module) arg_types [1] = ret_type; AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2); - AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2); ret_type = type_to_simd_type (MONO_TYPE_I2); arg_types [0] = ret_type; @@ -4852,7 +4893,6 @@ add_intrinsics (LLVMModuleRef module) AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2); - AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2); @@ -4866,19 +4906,12 @@ add_intrinsics (LLVMModuleRef module) arg_types [1] = ret_type; AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2); - AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2); - AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2); AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2); - ret_type = type_to_simd_type (MONO_TYPE_I8); - arg_types [0] = ret_type; - arg_types [1] = ret_type; - AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2); - ret_type = type_to_simd_type (MONO_TYPE_R8); arg_types [0] = ret_type; arg_types [1] = ret_type; @@ -5035,7 +5068,7 @@ init_jit_module (void) jit_module.module = LLVMModuleCreateWithName ("mono"); - ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb); + ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb); add_intrinsics (jit_module.module);