[jit] Introduce has_indirection flag in MonoCompile to signal that LDADDR was generated.
[mono.git] / mono / mini / mini-llvm.c
index ba19a35dc1b6d818cb65888686677d6ef877c633..ce2e50d536914d605f5fe8b4a8951cb9b5bb0921 100644 (file)
@@ -217,7 +217,7 @@ get_vtype_size (MonoType *t)
 
        size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
 
-       while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
+       while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
                size ++;
 
        return size;
@@ -934,12 +934,12 @@ convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_u
                if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
                        return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
 
-#ifdef MONO_ARCH_SOFT_FLOAT
-               if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
-                       return LLVMBuildBitCast (ctx->builder, v, dtype, "");
-               if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
-                       return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
-#endif
+               if (mono_arch_is_soft_float ()) {
+                       if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
+                               return LLVMBuildBitCast (ctx->builder, v, dtype, "");
+                       if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
+                               return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
+               }
 
                if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
                        return LLVMBuildBitCast (ctx->builder, v, dtype, "");
@@ -1044,7 +1044,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 ();
@@ -1680,7 +1680,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 */
@@ -1733,7 +1733,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) {
@@ -1865,6 +1865,10 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                                LLVMAddGlobalMapping (ee, callee, target);
                        }
                }
+
+               if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
+                       /* LLVM miscompiles async methods */
+                       LLVM_FAILURE (ctx, "#13734");
        } else if (calli) {
        } else {
                MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
@@ -2154,8 +2158,10 @@ 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:
@@ -2866,10 +2872,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
                        break;
                case OP_SEXT_I4:
-                       values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
+                       values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
                        break;
                case OP_ZEXT_I4:
-                       values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
+                       values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
                        break;
                case OP_TRUNC_I4:
                        values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
@@ -3370,6 +3376,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) {
@@ -3987,7 +3999,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;
                }
@@ -4221,18 +4233,21 @@ mono_llvm_emit_method (MonoCompile *cfg)
        
        module = ctx->module = ctx->lmodule->module;
 
+       if (cfg->gsharedvt)
+               LLVM_FAILURE (ctx, "gsharedvt");
+
 #if 1
        {
                static int count = 0;
                count ++;
 
-               if (getenv ("LLVM_COUNT")) {
-                       if (count == atoi (getenv ("LLVM_COUNT"))) {
+               if (g_getenv ("LLVM_COUNT")) {
+                       if (count == atoi (g_getenv ("LLVM_COUNT"))) {
                                printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
                                fflush (stdout);
                                last = TRUE;
                        }
-                       if (count > atoi (getenv ("LLVM_COUNT")))
+                       if (count > atoi (g_getenv ("LLVM_COUNT")))
                                LLVM_FAILURE (ctx, "");
                }
        }
@@ -4496,6 +4511,19 @@ mono_llvm_emit_method (MonoCompile *cfg)
 
        mark_as_used (module, method);
 
+       if (cfg->compile_aot) {
+               LLVMValueRef md_args [16];
+               LLVMValueRef md_node;
+               int method_index;
+
+               method_index = mono_aot_get_method_index (cfg->orig_method);
+               md_args [0] = LLVMMDString (method_name, strlen (method_name));
+               md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
+               md_node = LLVMMDNode (md_args, 2);
+               LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
+               //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
+       }
+
        if (cfg->compile_aot) {
                /* Don't generate native code, keep the LLVM IR */
                if (cfg->compile_aot && cfg->verbose_level)
@@ -5124,7 +5152,7 @@ mono_llvm_create_aot_module (const char *got_symbol)
                LLVMValueRef personality;
 
                personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
-               LLVMSetLinkage (personality, LLVMPrivateLinkage);
+               LLVMSetLinkage (personality, LLVMInternalLinkage);
                lbb = LLVMAppendBasicBlock (personality, "BB0");
                lbuilder = LLVMCreateBuilder ();
                LLVMPositionBuilderAtEnd (lbuilder, lbb);