Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[mono.git] / mono / mini / mini-llvm.c
index aa3657cb4d7db62e01e44f062951292f19e2cae4..2fa1da978d424eed7b04ba70685dd45e0a4da8e1 100644 (file)
 extern void *memset(void *, int, size_t);
 void bzero (void *to, size_t count) { memset (to, 0, count); }
 
+#endif
+
+#if LLVM_API_VERSION < 4
+#error "The version of the mono llvm repository is too old."
 #endif
 
  /*
@@ -372,10 +376,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 +1156,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);
 
@@ -1516,12 +1520,6 @@ emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LL
        return lcall;
 }
 
-#if LLVM_API_VERSION >= 4
-#define EXTRA_MONO_LOAD_STORE_ARGS 1
-#else
-#define EXTRA_MONO_LOAD_STORE_ARGS 0
-#endif
-
 static LLVMValueRef
 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
 {
@@ -1530,7 +1528,6 @@ emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder
        LLVMTypeRef addr_type;
 
        if (is_faulting && bb->region != -1) {
-#if LLVM_API_VERSION >= 4
                LLVMAtomicOrdering ordering;
 
                switch (barrier) {
@@ -1547,7 +1544,6 @@ emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder
                        g_assert_not_reached ();
                        break;
                }
-#endif
 
                /*
                 * We handle loads which can fault by calling a mono specific intrinsic
@@ -1579,10 +1575,8 @@ emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder
                args [0] = addr;
                args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
                args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
-#if LLVM_API_VERSION >= 4
                args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
-#endif
-               res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3 + EXTRA_MONO_LOAD_STORE_ARGS);
+               res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
 
                if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
                        res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
@@ -1623,7 +1617,6 @@ emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builde
        LLVMValueRef args [16];
 
        if (is_faulting && bb->region != -1) {
-#if LLVM_API_VERSION >= 4
                LLVMAtomicOrdering ordering;
 
                switch (barrier) {
@@ -1640,7 +1633,6 @@ emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builde
                        g_assert_not_reached ();
                        break;
                }
-#endif
 
                switch (size) {
                case 1:
@@ -1668,10 +1660,8 @@ emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builde
                args [1] = addr;
                args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
                args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
-#if LLVM_API_VERSION >= 4
                args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
-#endif
-               emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4 + EXTRA_MONO_LOAD_STORE_ARGS);
+               emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
        } else {
                mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
        }
@@ -2157,7 +2147,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
        CHECK_FAILURE (ctx);
 
        virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
-       calli = (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
+       calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
 
        /* FIXME: Avoid creating duplicate methods */
 
@@ -2261,7 +2251,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
        /* 
         * Collect and convert arguments
         */
-       nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
+       nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
        len = sizeof (LLVMValueRef) * nargs;
        args = alloca (len);
        memset (args, 0, len);
@@ -2350,6 +2340,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                                args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
                        break;
                }
+               g_assert (pindex <= nargs);
 
                l = l->next;
        }
@@ -3756,12 +3747,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        /* new value */
                        args [2] = convert (ctx, values [ins->sreg2], t);
                        val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
-#if LLVM_API_VERSION >= 1
                        /* cmpxchg returns a pair */
                        values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
-#else
-                       values [ins->dreg] = val;
-#endif
                        break;
                }
                case OP_MEMORY_BARRIER: {
@@ -3779,7 +3766,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_ATOMIC_LOAD_R4:
                case OP_ATOMIC_LOAD_R8: {
                        LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
-#if LLVM_API_VERSION >= 4
+
                        int size;
                        gboolean sext, zext;
                        LLVMTypeRef t;
@@ -3807,9 +3794,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
                        else if (zext)
                                values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
-#else
-                       LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
-#endif
                        break;
                }
                case OP_ATOMIC_STORE_I1:
@@ -3823,7 +3807,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_ATOMIC_STORE_R4:
                case OP_ATOMIC_STORE_R8: {
                        LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
-#if LLVM_API_VERSION >= 4
+
                        int size;
                        gboolean sext, zext;
                        LLVMTypeRef t;
@@ -3842,10 +3826,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
                        break;
-#else
-                       LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
-#endif
-                       break;
                }
                case OP_RELAXED_NOP: {
 #if defined(TARGET_AMD64) || defined(TARGET_X86)
@@ -4879,10 +4859,6 @@ mono_llvm_emit_method (MonoCompile *cfg)
 
        if (cfg->compile_aot) {
                LLVMSetLinkage (method, LLVMInternalLinkage);
-#if LLVM_API_VERSION == 0
-               /* This causes an assertion in later LLVM versions */
-               LLVMSetVisibility (method, LLVMHiddenVisibility);
-#endif
                if (ctx->lmodule->external_symbols) {
                        LLVMSetLinkage (method, LLVMExternalLinkage);
                        LLVMSetVisibility (method, LLVMHiddenVisibility);
@@ -5670,21 +5646,17 @@ add_intrinsics (LLVMModuleRef module)
                        arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
                        arg_types [1] = LLVMInt32Type ();
                        arg_types [2] = LLVMInt1Type ();
-#if LLVM_API_VERSION >= 4
                        arg_types [3] = LLVMInt32Type ();
-#endif
                        sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
-                       LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3 + EXTRA_MONO_LOAD_STORE_ARGS, FALSE));
+                       LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 4, FALSE));
 
                        arg_types [0] = LLVMIntType (i * 8);
                        arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
                        arg_types [2] = LLVMInt32Type ();
                        arg_types [3] = LLVMInt1Type ();
-#if LLVM_API_VERSION >= 4
                        arg_types [4] = LLVMInt32Type ();
-#endif
                        sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
-                       LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4 + EXTRA_MONO_LOAD_STORE_ARGS, FALSE));
+                       LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 5, FALSE));
                }
        }
 }
@@ -6209,9 +6181,9 @@ emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil
 
 /*
   AOT SUPPORT:
-  Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then 
-  append the AOT data structures to that file. For methods which cannot be
-  handled by LLVM, the normal JIT compiled versions are used.
+  Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
+  it with the file containing the methods emitted by the JIT and the AOT data
+  structures.
 */
 
 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like: