2009-11-20 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 20 Nov 2009 16:22:30 +0000 (16:22 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 20 Nov 2009 16:22:30 +0000 (16:22 -0000)
* mini.c mini-trampolines.c driver.c: Add a 'mono_use_llvm' flag to control
whenever the runtime uses LLVM code. Add a '--llvm' command line option to set
it. Use this flag to control llvm related code paths instead of #ifdef
ENABLE_LLVM, so a runtime configured without --enable-llvm can use LLVM compiled
AOT code.

* aot-runtime.c aot-compiler.c: Add a 'flag' field to MonoAotFileInfo.

* mini.h: Bump AOT file format version.

svn path=/trunk/mono/; revision=146625

mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/driver.c
mono/mini/mini-amd64.h
mono/mini/mini-trampolines.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/tramp-amd64.c

index 6df8695c8e6060a288ee67a1dc9f3d6b7c13adbf..0377fc02bc5abc0b636ee6870d5fbb5583ce3462 100644 (file)
@@ -1,5 +1,15 @@
 2009-11-20  Zoltan Varga  <vargaz@gmail.com>
 
+       * mini.c mini-trampolines.c driver.c: Add a 'mono_use_llvm' flag to control
+       whenever the runtime uses LLVM code. Add a '--llvm' command line option to set
+       it. Use this flag to control llvm related code paths instead of #ifdef
+       ENABLE_LLVM, so a runtime configured without --enable-llvm can use LLVM compiled
+       AOT code.
+
+       * aot-runtime.c aot-compiler.c: Add a 'flag' field to MonoAotFileInfo.
+
+       * mini.h: Bump AOT file format version.
+
        * tramp-ppc.c (mono_arch_create_generic_class_init_trampoline_full): These
        receive their argument in MONO_ARCH_VTABLE_REG, not in the first argument reg.
 
index 938a605b0ee9ca51c252b6bd6501efd02f8da524..19f59ceda1d30d868d52898bd9328b98c479648e 100644 (file)
@@ -164,6 +164,7 @@ typedef struct MonoAotCompile {
        const char *temp_prefix;
        guint32 label_generator;
        gboolean llvm;
+       MonoAotFileFlags flags;
 } MonoAotCompile;
 
 #define mono_acfg_lock(acfg) EnterCriticalSection (&((acfg)->mutex))
@@ -5116,6 +5117,7 @@ emit_file_info (MonoAotCompile *acfg)
        emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer)));
        emit_int32 (acfg, acfg->plt_offset);
        emit_int32 (acfg, acfg->nmethods);
+       emit_int32 (acfg, acfg->flags);
 
        for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
                emit_int32 (acfg, acfg->num_trampolines [i]);
@@ -5506,6 +5508,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 #ifdef ENABLE_LLVM
        acfg->llvm = TRUE;
        acfg->aot_opts.asm_writer = TRUE;
+       acfg->flags |= MONO_AOT_FILE_FLAG_WITH_LLVM;
 #endif
 
        load_profile_files (acfg);
index 7ddd737099d9e6b1a9a460032d8283cb8067f511..92d7f54e837257efbfc5fc9d11161ea44cf3d111 100644 (file)
@@ -958,6 +958,9 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
        g_free (build_info);
 
+       find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info);
+       g_assert (file_info);
+
        {
                char *full_aot_str;
 
@@ -976,6 +979,11 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                usable = FALSE;
        }
 
+       if ((((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s is compiled with LLVM.\n", aot_name);
+               usable = FALSE;
+       }
+
        if (!usable) {
                if (mono_aot_only) {
                        fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode.\n", aot_name);
@@ -988,9 +996,6 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                return;
        }
 
-       find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info);
-       g_assert (file_info);
-
        amodule = g_new0 (MonoAotModule, 1);
        amodule->aot_name = aot_name;
        amodule->assembly = assembly;
index cec99fb01340c595b0fbf0c7df2808c04487e1e5..5810bfd37ce6c822a47840d3ace77f2b9f56ff60 100644 (file)
@@ -1123,6 +1123,7 @@ mini_usage (void)
                "                           mode is one of cas, core-clr, verifiable or validil\n"
                "    --attach=OPTIONS       Pass OPTIONS to the attach agent in the runtime.\n"
                "                           Currently the only supported option is 'disable'.\n"
+               "    --llvm                 Controls whenever the runtime uses LLVM compiled code.\n"
          );
 }
 
@@ -1534,6 +1535,13 @@ mono_main (int argc, char* argv[])
 #ifdef MONO_JIT_INFO_TABLE_TEST
                } else if (strcmp (argv [i], "--test-jit-info-table") == 0) {
                        test_jit_info_table = TRUE;
+#endif
+               } else if (strcmp (argv [i], "--llvm") == 0) {
+#ifndef MONO_ARCH_LLVM_SUPPORTED
+                       fprintf (stderr, "--llvm not supported on this platform.\n");
+                       return 1;
+#else
+                       mono_use_llvm = TRUE;
 #endif
                } else {
                        fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
index 5da9db704f5d5ac0de454d5bdbee949383f043ae..ac7dabc24d24bfde4714d3fe49b74158137b7665 100644 (file)
@@ -376,6 +376,7 @@ typedef struct {
 #define MONO_ARCH_DYN_CALL_PARAM_AREA 0
 
 #define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
+#define MONO_ARCH_LLVM_SUPPORTED 1
 
 #define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_metadata_signature_equal ((caller_sig), (callee_sig))
 
index b0181c364f550efa0757d7697ca0649bf5a2a5e8..4af243ff5b1fd0bbfbf50fb9a2010e4c1a4579ae 100644 (file)
@@ -527,7 +527,7 @@ mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
        return addr;
 }
  
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
 /*
  * mono_llvm_vcall_trampoline:
  *
@@ -927,7 +927,7 @@ mono_get_trampoline_func (MonoTrampolineType tramp_type)
                return mono_monitor_enter_trampoline;
        case MONO_TRAMPOLINE_MONITOR_EXIT:
                return mono_monitor_exit_trampoline;
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
        case MONO_TRAMPOLINE_LLVM_VCALL:
                return mono_llvm_vcall_trampoline;
 #endif
@@ -961,7 +961,7 @@ mono_trampolines_init (void)
        mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
        mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER);
        mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_EXIT] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
        mono_trampoline_code [MONO_TRAMPOLINE_LLVM_VCALL] = mono_arch_create_trampoline_code (MONO_TRAMPOLINE_LLVM_VCALL);
 #endif
 }
@@ -1286,7 +1286,7 @@ mono_create_monitor_exit_trampoline (void)
        return code;
 }
  
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
 /*
  * mono_create_llvm_vcall_trampoline:
  *
index 0c9e55e9f17c69f9978513160321a16fed49819f..c591124d281a8771b8139a09a62c74e7baed3f6a 100644 (file)
@@ -112,6 +112,21 @@ static int mini_verbose = 0;
 static int methods_with_llvm, methods_without_llvm;
 #endif
 
+/*
+ * This flag controls whenever the runtime uses LLVM compiled code.
+ * Enabling this causes different/slower code paths to be used, which is why it
+ * defaults to FALSE if ENABLE_LLVM is not defined, i.e. the runtime is only capable of
+ * running AOT code compiled by LLVM.
+ * Changes when this flag is set include:
+ * - a per method vtable trampoline is used to handle virtual calls, instead of only
+ *   one trampoline.
+ */
+#ifdef ENABLE_LLVM
+gboolean mono_use_llvm = TRUE;
+#else
+gboolean mono_use_llvm = FALSE;
+#endif
+
 #define mono_jit_lock() EnterCriticalSection (&jit_mutex)
 #define mono_jit_unlock() LeaveCriticalSection (&jit_mutex)
 static CRITICAL_SECTION jit_mutex;
@@ -2788,7 +2803,8 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                break;
 #endif
        case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
+               g_assert (mono_use_llvm);
                target = mono_create_llvm_imt_trampoline (domain, patch_info->data.imt_tramp->method, patch_info->data.imt_tramp->vt_offset);
 #else
                g_assert_not_reached ();
@@ -5115,9 +5131,12 @@ mini_init (const char *filename, const char *runtime_version)
 #ifdef JIT_TRAMPOLINES_WORK
        mono_install_compile_method (mono_jit_compile_method);
        mono_install_free_method (mono_jit_free_method);
-#ifdef ENABLE_LLVM
-       /* The runtime currently only uses this for filling out vtables */
-       mono_install_trampoline (mono_create_llvm_vcall_trampoline);
+#ifdef MONO_ARCH_LLVM_SUPPORTED
+       if (mono_use_llvm)
+               /* The runtime currently only uses this for filling out vtables */
+               mono_install_trampoline (mono_create_llvm_vcall_trampoline);
+       else
+               mono_install_trampoline (mono_create_jit_trampoline);
 #else
        mono_install_trampoline (mono_create_jit_trampoline);
 #endif
@@ -5152,15 +5171,15 @@ mini_init (const char *filename, const char *runtime_version)
                        mono_install_imt_thunk_builder (mono_aot_get_imt_thunk);
                else
                        mono_install_imt_thunk_builder (mono_arch_build_imt_thunk);
-#ifndef ENABLE_LLVM
-               /* LLVM needs a per-method vtable trampoline */
-               mono_install_vtable_trampoline (mini_get_vtable_trampoline ());
-               /* 
-                * The imt code in mono_magic_trampoline () can't handle LLVM code. By disabling
-                * this, we force iface calls to go through the llvm vcall trampoline.
-                */
-               mono_install_imt_trampoline (mini_get_imt_trampoline ());
-#endif
+               if (!mono_use_llvm) {
+                       /* LLVM needs a per-method vtable trampoline */
+                       mono_install_vtable_trampoline (mini_get_vtable_trampoline ());
+                       /* 
+                        * The imt code in mono_magic_trampoline () can't handle LLVM code. By disabling
+                        * this, we force iface calls to go through the llvm vcall trampoline.
+                        */
+                       mono_install_imt_trampoline (mini_get_imt_trampoline ());
+               }
        }
 #endif
 
index b5857d2f72a39ab9c036bc7e936d0da9998f1de3..e2d2db85f3af4f3934950f32d0d23224ae495d7f 100644 (file)
@@ -89,7 +89,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "60"
+#define MONO_AOT_FILE_VERSION "61"
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -118,6 +118,10 @@ typedef enum {
        MONO_AOT_TRAMP_NUM = 3
 } MonoAotTrampoline;
 
+typedef enum {
+       MONO_AOT_FILE_FLAG_WITH_LLVM = 1
+} MonoAotFileFlags;
+
 /* This structure is stored in the AOT file */
 typedef struct MonoAotFileInfo
 {
@@ -125,6 +129,7 @@ typedef struct MonoAotFileInfo
        guint32 got_size;
        guint32 plt_size;
        guint32 nmethods;
+       guint32 flags;
 
        guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
@@ -376,6 +381,7 @@ extern gboolean mono_dont_free_global_codeman;
 extern gboolean mono_do_x86_stack_align;
 extern const char *mono_build_date;
 extern gboolean mono_do_signal_chaining;
+extern gboolean mono_use_llvm;
 
 #define INS_INFO(opcode) (&ins_info [((opcode) - OP_START - 1) * 4])
 
@@ -877,7 +883,7 @@ typedef enum {
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
        MONO_TRAMPOLINE_MONITOR_ENTER,
        MONO_TRAMPOLINE_MONITOR_EXIT,
-#ifdef ENABLE_LLVM
+#ifdef MONO_ARCH_LLVM_SUPPORTED
        MONO_TRAMPOLINE_LLVM_VCALL,
 #endif
        MONO_TRAMPOLINE_NUM
index e70995e6b6f13472790638d5a5d2a9b4a9c4853c..15df66528ff03cecf8cb9faf75a5c0d4d5b35b7e 100644 (file)
@@ -217,11 +217,11 @@ mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
        MonoJitInfo *ji = NULL;
        gboolean can_write;
 
-#ifdef ENABLE_LLVM
-       /* code - 7 might be before the start of the method */
-       /* FIXME: Avoid this expensive call somehow */
-       ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
-#endif
+       if (mono_use_llvm) {
+               /* code - 7 might be before the start of the method */
+               /* FIXME: Avoid this expensive call somehow */
+               ji = mono_jit_info_table_find (mono_domain_get (), (char*)code);
+       }
 
        can_write = mono_breakpoint_clean_code (ji ? ji->code_start : NULL, code, 7, buf, sizeof (buf));