2010-02-10 Miguel de Icaza <miguel@novell.com>
[mono.git] / mono / mini / mini-llvm.c
index f61289c586cb417155da0157266725fcd64844d3..ec83b7a13f95b699cd1f0268c3e9c3eb6ddfa845 100644 (file)
@@ -167,6 +167,9 @@ static LLVMExecutionEngineRef ee;
 static guint32 current_cfg_tls_id;
 
 static MonoLLVMModule jit_module, aot_module;
+static gboolean jit_module_inited;
+
+static void init_jit_module (void);
 
 /*
  * IntPtrType:
@@ -945,6 +948,8 @@ get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gc
        if (!callee) {
                callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
 
+               LLVMSetVisibility (callee, LLVMHiddenVisibility);
+
                g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
        }
 
@@ -1281,6 +1286,11 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
                        ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
 
                        emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
+
+                       if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
+                               /* Treat these as normal values */
+                               ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
+                       }
                } else if (ainfo->storage == LLVMArgVtypeByVal) {
                        ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindexes [i]);
                } else {
@@ -1399,6 +1409,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
                method_name = mono_aot_get_method_name (cfg);
                debug_name = mono_aot_get_method_debug_name (cfg);
        } else {
+               init_jit_module ();
                ctx->lmodule = &jit_module;
                method_name = mono_method_full_name (cfg->method, TRUE);
                debug_name = NULL;
@@ -3464,6 +3475,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
                /* Can't delete the method if it has an alias, so only add it if successful */
                if (debug_name) {
                        debug_alias = LLVMAddAlias (module, LLVMTypeOf (method), method, debug_name);
+                       LLVMSetLinkage (debug_alias, LLVMInternalLinkage);
                        LLVMSetVisibility (debug_alias, LLVMHiddenVisibility);
                }
 
@@ -3785,6 +3797,20 @@ void
 mono_llvm_init (void)
 {
        current_cfg_tls_id = TlsAlloc ();
+}
+
+static void
+init_jit_module (void)
+{
+       if (jit_module_inited)
+               return;
+
+       mono_loader_lock ();
+
+       if (jit_module_inited) {
+               mono_loader_unlock ();
+               return;
+       }
 
        jit_module.module = LLVMModuleCreateWithName ("mono");
 
@@ -3795,14 +3821,20 @@ mono_llvm_init (void)
        jit_module.llvm_types = g_hash_table_new (NULL, NULL);
 
        LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "mono_resume_unwind"), mono_resume_unwind);
+
+       jit_module_inited = TRUE;
+
+       mono_loader_unlock ();
 }
 
 void
 mono_llvm_cleanup (void)
 {
-       mono_llvm_dispose_ee (ee);
+       if (ee)
+               mono_llvm_dispose_ee (ee);
 
-       g_hash_table_destroy (jit_module.llvm_types);
+       if (jit_module.llvm_types)
+               g_hash_table_destroy (jit_module.llvm_types);
 }
 
 void
@@ -3833,15 +3865,6 @@ mono_llvm_create_aot_module (const char *got_symbol)
                LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
        }
 
-       /* Add a method to generate the 'methods' symbol needed by the AOT compiler */
-       {
-               LLVMValueRef methods_method = LLVMAddFunction (aot_module.module, "methods", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
-               LLVMBasicBlockRef bb = LLVMAppendBasicBlock (methods_method, "BB_ENTRY");
-               LLVMBuilderRef builder = LLVMCreateBuilder ();
-               LLVMPositionBuilderAtEnd (builder, bb);
-               LLVMBuildRetVoid (builder);
-       }
-
        /* Add a dummy personality function */
        {
                LLVMBasicBlockRef lbb;
@@ -3882,6 +3905,9 @@ mono_llvm_emit_aot_module (const char *filename, int got_size)
 
        mark_as_used (aot_module.module, real_got);
 
+       /* Delete the dummy got so it doesn't become a global */
+       LLVMDeleteGlobal (aot_module.got_var);
+
 #if 0
        {
                char *verifier_err;