[jit] Add a new mini_get_underlying_type () function which handles byref, enums,...
authorZoltan Varga <vargaz@gmail.com>
Thu, 5 Mar 2015 01:03:24 +0000 (20:03 -0500)
committerZoltan Varga <vargaz@gmail.com>
Thu, 5 Mar 2015 01:03:30 +0000 (20:03 -0500)
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-arm.c
mono/mini/mini-llvm.c
mono/mini/mini-x86.c
mono/mini/mini.c
mono/mini/mini.h

index 6df610b771fd8545815bc204deb906080b9dc196..a7ea46ba97b4f6f96cc407720fdfac1ff122d920 100755 (executable)
@@ -276,7 +276,7 @@ mono_type_to_regmove (MonoCompile *cfg, MonoType *type)
        if (type->byref)
                return OP_MOVE;
 
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
 handle_enum:
        switch (type->type) {
        case MONO_TYPE_I1:
@@ -738,7 +738,7 @@ type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst)
 {
        MonoClass *klass;
 
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
        inst->klass = klass = mono_class_from_mono_type (type);
        if (type->byref) {
                inst->type = STACK_MP;
@@ -2140,12 +2140,8 @@ emit_instrumentation_call (MonoCompile *cfg, void *func)
 static int
 ret_type_to_call_opcode (MonoCompile *cfg, MonoType *type, int calli, int virt, MonoGenericSharingContext *gsctx)
 {
-       if (type->byref)
-               return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL;
-
 handle_enum:
-       type = mini_get_basic_type_from_generic (gsctx, type);
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
        switch (type->type) {
        case MONO_TYPE_VOID:
                return calli? OP_VOIDCALL_REG: virt? OP_VOIDCALL_MEMBASE: OP_VOIDCALL;
@@ -2217,7 +2213,6 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg)
        MonoType *simple_type;
        MonoClass *klass;
 
-       target = mini_replace_type (target);
        if (target->byref) {
                /* FIXME: check that the pointed to types match */
                if (arg->type == STACK_MP)
@@ -2227,7 +2222,7 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg)
                return 1;
        }
 
-       simple_type = mono_type_get_underlying_type (target);
+       simple_type = mini_get_underlying_type (cfg, target);
        switch (simple_type->type) {
        case MONO_TYPE_VOID:
                return 1;
@@ -2612,7 +2607,7 @@ mono_emit_call_args (MonoCompile *cfg, MonoMethodSignature *sig,
        call->args = args;
        call->signature = sig;
        call->rgctx_reg = rgctx;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        type_to_eval_stack_type ((cfg), sig_ret, &call->inst);
 
@@ -6671,7 +6666,7 @@ emit_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype)
        MonoInst *ins;
        int t;
 
-       rtype = mini_replace_type (rtype);
+       rtype = mini_get_underlying_type (cfg, rtype);
        t = rtype->type;
 
        if (rtype->byref) {
@@ -6707,7 +6702,7 @@ emit_dummy_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype)
 {
        int t;
 
-       rtype = mini_replace_type (rtype);
+       rtype = mini_get_underlying_type (cfg, rtype);
        t = rtype->type;
 
        if (rtype->byref) {
@@ -7410,7 +7405,7 @@ emit_optimized_ldloca_ir (MonoCompile *cfg, unsigned char *ip, unsigned char *en
                token = read32 (ip + 2);
                klass = mini_get_class (cfg->current_method, token, cfg->generic_context);
                CHECK_TYPELOAD (klass);
-               type = mini_replace_type (&klass->byval_arg);
+               type = mini_get_underlying_type (cfg, &klass->byval_arg);
                emit_init_local (cfg, local, type, TRUE);
                return ip + 6;
        }
@@ -9548,7 +9543,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        emit_pop_lmf (cfg);
 
                                if (cfg->ret) {
-                                       MonoType *ret_type = mini_replace_type (mono_method_signature (method)->ret);
+                                       MonoType *ret_type = mini_get_underlying_type (cfg, mono_method_signature (method)->ret);
 
                                        if (seq_points && !sym_seq_points) {
                                                /* 
index 3a7eedd7e35eea505dc0fe02bde2c1eeead2dbf1..69769b53be4fe4ab0939671900fcb45b837c21b1 100755 (executable)
@@ -1250,7 +1250,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig
        c1 = get_call_info (NULL, NULL, caller_sig);
        c2 = get_call_info (NULL, NULL, callee_sig);
        res = c1->stack_usage >= c2->stack_usage;
-       callee_ret = mini_replace_type (callee_sig->ret);
+       callee_ret = mini_get_underlying_type (cfg, callee_sig->ret);
        if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
@@ -1659,7 +1659,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        /*
         * Contrary to mono_arch_allocate_vars (), the information should describe
@@ -1741,7 +1741,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        mono_arch_compute_omit_fp (cfg);
 
@@ -2022,7 +2022,7 @@ mono_arch_create_vars (MonoCompile *cfg)
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
 
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
        if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig_ret)) {
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
                if (G_UNLIKELY (cfg->verbose_level > 1)) {
@@ -2167,7 +2167,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
        MonoType *t, *sig_ret;
 
        n = sig->param_count + sig->hasthis;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
 
@@ -2398,7 +2398,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos))
                emit_sig_cookie (cfg, call, cinfo);
 
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
        if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) {
                MonoInst *vtarg;
 
@@ -2533,7 +2533,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
 void
 mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
 {
-       MonoType *ret = mini_replace_type (mono_method_signature (method)->ret);
+       MonoType *ret = mini_get_underlying_type (cfg, mono_method_signature (method)->ret);
 
        if (ret->type == MONO_TYPE_R4) {
                if (COMPILE_LLVM (cfg))
@@ -7662,7 +7662,7 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea
        guchar *code = p;
        int save_mode = SAVE_NONE;
        MonoMethod *method = cfg->method;
-       MonoType *ret_type = mini_replace_type (mono_method_signature (method)->ret);
+       MonoType *ret_type = mini_get_underlying_type (cfg, mono_method_signature (method)->ret);
        int i;
        
        switch (ret_type->type) {
index ea04525ff14fa08ed11e769046fd1cecfb098102..d89c46b500e02d5185b226eab391f81bc1d9c65c 100644 (file)
@@ -1753,7 +1753,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig
         * the extra stack space would be left on the stack after the tail call.
         */
        res = c1->stack_usage >= c2->stack_usage;
-       callee_ret = mini_replace_type (callee_sig->ret);
+       callee_ret = mini_get_underlying_type (cfg, callee_sig->ret);
        if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != RegTypeStructByVal)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
@@ -1869,7 +1869,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        if (!cfg->arch.cinfo)
                cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
        cinfo = cfg->arch.cinfo;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        mono_arch_compute_omit_fp (cfg);
 
index 9fd46669119651316dce95780ea13315aa1eb6bc..25323968831671376c17118a140a3fe9a5b3f9da 100644 (file)
@@ -372,10 +372,10 @@ create_llvm_type_for_type (MonoClass *klass)
 static LLVMTypeRef
 type_to_llvm_type (EmitContext *ctx, MonoType *t)
 {
-       t = mini_replace_type (t);
-
        if (t->byref)
                return LLVMPointerType (LLVMInt8Type (), 0);
+
+       t = mini_get_underlying_type (ctx->cfg, t);
        switch (t->type) {
        case MONO_TYPE_VOID:
                return LLVMVoidType ();
@@ -1152,7 +1152,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
        if (sinfo)
                memset (sinfo, 0, sizeof (LLVMSigInfo));
 
-       rtype = mini_replace_type (sig->ret);
+       rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
        ret_type = type_to_llvm_type (ctx, rtype);
        CHECK_FAILURE (ctx);
 
index 9281ea9d1eb134d9165561b75afa6fb7efad9351..7f213efd28da480380e4a6098b60a75866c25a08 100644 (file)
@@ -324,7 +324,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
 
                /* Special case structs with only a float member */
                if (info->num_fields == 1) {
-                       int ftype = mini_replace_type (info->fields [0].field->type)->type;
+                       int ftype = mini_type_get_underlying_type (gsctx, info->fields [0].field->type)->type;
                        if ((info->native_size == 8) && (ftype == MONO_TYPE_R8)) {
                                ainfo->storage = ArgValuetypeInReg;
                                ainfo->pair_storage [0] = ArgOnDoubleFpStack;
@@ -721,7 +721,7 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig
         * the extra stack space would be left on the stack after the tail call.
         */
        res = c1->stack_usage >= c2->stack_usage;
-       callee_ret = mini_replace_type (callee_sig->ret);
+       callee_ret = mini_get_underlying_type (cfg, callee_sig->ret);
        if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
@@ -1209,7 +1209,7 @@ mono_arch_create_vars (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
@@ -1424,7 +1424,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
-       sig_ret = mini_replace_type (sig->ret);
+       sig_ret = mini_get_underlying_type (cfg, sig->ret);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
        call->call_info = cinfo;
index b86f4afd6bdd0453ea66ce4d41c60630e423f993..409ef5dacf4394a04ad1b42423089eb4a9548d40 100755 (executable)
@@ -423,10 +423,7 @@ mono_reverse_branch_op (guint32 opcode)
 guint
 mono_type_to_store_membase (MonoCompile *cfg, MonoType *type)
 {
-       if (type->byref)
-               return OP_STORE_MEMBASE_REG;
-
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
 
 handle_enum:
        switch (type->type) {
@@ -474,10 +471,8 @@ handle_enum:
                goto handle_enum;
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
-               if (mini_type_var_is_vt (cfg, type))
-                       return OP_STOREV_MEMBASE;
-               else
-                       return OP_STORE_MEMBASE_REG;
+               g_assert (mini_type_var_is_vt (cfg, type));
+               return OP_STOREV_MEMBASE;
        default:
                g_error ("unknown type 0x%02x in type_to_store_membase", type->type);
        }
@@ -487,10 +482,7 @@ handle_enum:
 guint
 mono_type_to_load_membase (MonoCompile *cfg, MonoType *type)
 {
-       if (type->byref)
-               return OP_LOAD_MEMBASE;
-
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
 
        switch (type->type) {
        case MONO_TYPE_I1:
@@ -539,10 +531,8 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                g_assert (cfg->generic_sharing_context);
-               if (mini_type_var_is_vt (cfg, type))
-                       return OP_LOADV_MEMBASE;
-               else
-                       return OP_LOAD_MEMBASE;
+               g_assert (mini_type_var_is_vt (cfg, type));
+               return OP_LOADV_MEMBASE;
        default:
                g_error ("unknown type 0x%02x in type_to_load_membase", type->type);
        }
@@ -552,13 +542,10 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type)
 static guint
 mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
 {
-       if (cfg->generic_sharing_context && !type->byref) {
-               if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) {
-                       if (mini_type_var_is_vt (cfg, type))
-                               return CEE_LDOBJ;
-                       else
-                               return CEE_LDIND_REF;
-               }
+       type = mini_get_underlying_type (cfg, type);
+       if (cfg->generic_sharing_context && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
+               g_assert (mini_type_var_is_vt (cfg, type));
+               return CEE_LDOBJ;
        }
        return mono_type_to_ldind (type);
 }
@@ -568,15 +555,10 @@ mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
 guint
 mini_type_to_stind (MonoCompile* cfg, MonoType *type)
 {
-       type = mini_replace_type (type);
-
-       if (cfg->generic_sharing_context && !type->byref) {
-               if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) {
-                       if (mini_type_var_is_vt (cfg, type))
-                               return CEE_STOBJ;
-                       else
-                               return CEE_STIND_REF;
-               }
+       type = mini_get_underlying_type (cfg, type);
+       if (cfg->generic_sharing_context && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
+               g_assert (mini_type_var_is_vt (cfg, type));
+               return CEE_STOBJ;
        }
        return mono_type_to_stind (type);
 }
@@ -751,7 +733,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode,
        int num = cfg->num_varinfo;
        gboolean regpair;
 
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
 
        if ((num + 1) >= cfg->varinfo_count) {
                int orig_count = cfg->varinfo_count;
@@ -779,8 +761,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode,
                if (type->byref) {
                        mono_mark_vreg_as_mp (cfg, vreg);
                } else {
-                       MonoType *t = mini_replace_type (type);
-                       if ((MONO_TYPE_ISSTRUCT (t) && inst->klass->has_references) || mini_type_is_reference (cfg, t)) {
+                       if ((MONO_TYPE_ISSTRUCT (type) && inst->klass->has_references) || mini_type_is_reference (cfg, type)) {
                                inst->flags |= MONO_INST_GC_TRACK;
                                mono_mark_vreg_as_ref (cfg, vreg);
                        }
@@ -861,7 +842,7 @@ MonoInst*
 mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
 {
        int dreg;
-       type = mini_replace_type (type);
+       type = mini_get_underlying_type (cfg, type);
 
        if (mono_type_is_long (type))
                dreg = mono_alloc_dreg (cfg, STACK_I8);
@@ -878,7 +859,8 @@ mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
  * Transform a MonoInst into a load from the variable of index var_index.
  */
 void
-mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index) {
+mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index)
+{
        memset (dest, 0, sizeof (MonoInst));
        dest->inst_i0 = cfg->varinfo [var_index];
        dest->opcode = mini_type_to_ldind (cfg, dest->inst_i0->inst_vtype);
@@ -4551,6 +4533,20 @@ mini_replace_type (MonoType *type)
        return mini_native_type_replace_type (type);
 }
 
+/*
+ * mini_get_underlying_type:
+ *
+ *   Return the type the JIT will use during compilation.
+ * Handles: byref, enums, native types, generic sharing.
+ * For gsharedvt types, it will return the original VAR/MVAR.
+ */
+MonoType*
+mini_get_underlying_type (MonoCompile *cfg, MonoType *type)
+{
+       type = mini_type_get_underlying_type (cfg->generic_sharing_context, type);
+       return mini_native_type_replace_type (type);
+}
+
 void
 mini_jit_init (void)
 {
index 2821f479d3d486cde4ff607ef8ebad9a01efd19d..fcef6531e32b262ea9b4c06412b8d77c1717c9c6 100755 (executable)
@@ -2794,6 +2794,7 @@ MonoClass* mini_class_get_container_class (MonoClass *class) MONO_INTERNAL;
 MonoGenericContext* mini_class_get_context (MonoClass *class) MONO_INTERNAL;
 
 MonoType* mini_replace_type (MonoType *type) MONO_LLVM_INTERNAL;
+MonoType* mini_get_underlying_type (MonoCompile *cfg, MonoType *type) MONO_LLVM_INTERNAL;
 MonoType* mini_get_basic_type_from_generic (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
 MonoType* mini_type_get_underlying_type (MonoGenericSharingContext *gsctx, MonoType *type) MONO_INTERNAL;
 MonoMethod* mini_get_shared_method (MonoMethod *method) MONO_INTERNAL;