Skip to content

Commit

Permalink
[mono][aot] Extract the code invoking external tools into separate fu…
Browse files Browse the repository at this point in the history
…nctions.
  • Loading branch information
vargaz committed Feb 23, 2024
1 parent 13c05e9 commit 807b012
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 64 deletions.
175 changes: 112 additions & 63 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,12 @@ typedef struct MonoAotCompile {
MonoDwarfWriter *dwarf;
FILE *fp;
char *tmpbasename;
char *tmpfname;
char *asm_fname;
char *temp_dir_to_delete;
char *llvm_sfile;
char *llvm_ofile;
char *bc_fname;
char *optbc_fname;
GSList *cie_program;
GHashTable *unwind_info_offsets;
GPtrArray *unwind_ops;
Expand Down Expand Up @@ -483,9 +485,15 @@ get_patch_name (int info)
static int
aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options);

static void
set_paths (MonoAotCompile *acfg);

static int
emit_aot_image (MonoAotCompile *acfg);

static int
assemble_link (MonoAotCompile *acfg);

static guint32
get_unwind_info_offset (MonoAotCompile *acfg, guint8 *encoded, guint32 encoded_len);

Expand Down Expand Up @@ -10651,32 +10659,21 @@ execute_system (const char * command)
#endif

/*
* emit_llvm_file:
* compile_llvm_file:
*
* Emit the LLVM code into an LLVM bytecode file, and compile it using the LLVM
* tools.
* Compile the llvm bitcode file using the LLVM tools.
*/
static gboolean
emit_llvm_file (MonoAotCompile *acfg)
compile_llvm_file (MonoAotCompile *acfg)
{
char *command, *opts, *tempbc, *optbc, *output_fname;

if (acfg->aot_opts.llvm_only && acfg->aot_opts.asm_only) {
if (acfg->aot_opts.no_opt)
tempbc = g_strdup (acfg->aot_opts.llvm_outfile);
else
tempbc = g_strdup_printf ("%s.bc", acfg->tmpbasename);
optbc = g_strdup (acfg->aot_opts.llvm_outfile);
} else {
tempbc = g_strdup_printf ("%s.bc", acfg->tmpbasename);
optbc = g_strdup_printf ("%s.opt.bc", acfg->tmpbasename);
}

mono_llvm_emit_aot_module (tempbc, g_path_get_basename (acfg->image->name));

if (acfg->aot_opts.no_opt)
return TRUE;

tempbc = acfg->bc_fname;
optbc = acfg->optbc_fname;

#if (defined(TARGET_X86) || defined(TARGET_AMD64))
if (acfg->aot_opts.llvm_cpu_attr && strstr (acfg->aot_opts.llvm_cpu_attr, "sse4.2"))
/*
Expand Down Expand Up @@ -10799,7 +10796,7 @@ emit_llvm_file (MonoAotCompile *acfg)
#if ( defined(TARGET_MACH) && defined(TARGET_ARM) ) || defined(TARGET_ORBIS) || defined(TARGET_X86_64_WIN32_MSVC) || defined(TARGET_ANDROID)
g_string_append_printf (acfg->llc_args, " -relocation-model=pic");
#else
if (llvm_acfg->aot_opts.static_link)
if (acfg->aot_opts.static_link)
g_string_append_printf (acfg->llc_args, " -relocation-model=static");
else
g_string_append_printf (acfg->llc_args, " -relocation-model=pic");
Expand Down Expand Up @@ -13182,7 +13179,7 @@ compile_asm (MonoAotCompile *acfg)
#endif

if (acfg->aot_opts.asm_only) {
aot_printf (acfg, "Output file: '%s'.\n", acfg->tmpfname);
aot_printf (acfg, "Output file: '%s'.\n", acfg->asm_fname);
if (acfg->aot_opts.static_link)
aot_printf (acfg, "Linking symbol: '%s'.\n", acfg->static_linking_symbol);
if (acfg->llvm)
Expand All @@ -13196,7 +13193,7 @@ compile_asm (MonoAotCompile *acfg)
else
objfile = g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->image->name);
} else {
objfile = g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname);
objfile = g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->asm_fname);
}

#ifdef TARGET_OSX
Expand All @@ -13205,7 +13202,7 @@ compile_asm (MonoAotCompile *acfg)

command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, AS_NAME, AS_OPTIONS,
acfg->as_args ? acfg->as_args->str : "",
wrap_path (objfile), wrap_path (acfg->tmpfname));
wrap_path (objfile), wrap_path (acfg->asm_fname));
aot_printf (acfg, "Executing the native assembler: %s\n", command);
if (execute_system (command) != 0) {
g_free (command);
Expand Down Expand Up @@ -13290,7 +13287,7 @@ compile_asm (MonoAotCompile *acfg)
#endif
g_string_append_printf (str, " -o %s %s %s %s",
wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->tmpfname)), ld_flags);
wrap_path (g_strdup_printf ("%s." AS_OBJECT_FILE_SUFFIX, acfg->asm_fname)), ld_flags);

#if defined(TARGET_MACH)
g_string_append_printf (str, " \"-Wl,-install_name,%s%s\"", g_path_get_basename (acfg->image->name), MONO_SOLIB_EXT);
Expand Down Expand Up @@ -13357,7 +13354,7 @@ compile_asm (MonoAotCompile *acfg)
if (acfg->aot_opts.save_temps)
aot_printf (acfg, "Retained input file.\n");
else
g_unlink (acfg->tmpfname);
g_unlink (acfg->asm_fname);

return 0;
}
Expand Down Expand Up @@ -14831,6 +14828,11 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
dedup_change_phase (acfg, DEDUP_EMIT);
}

if (mono_use_llvm || acfg->aot_opts.llvm)
acfg->llvm = TRUE;

set_paths (acfg);

if (acfg->aot_opts.logfile) {
acfg->logfile = g_fopen (acfg->aot_opts.logfile, "a+");
}
Expand Down Expand Up @@ -15290,24 +15292,18 @@ create_depfile (MonoAotCompile *acfg)
fclose (depfile);
}

static int
emit_aot_image (MonoAotCompile *acfg)
static void
set_paths (MonoAotCompile *acfg)
{
int res;
TV_DECLARE (atv);
TV_DECLARE (btv);

TV_GETTIME (atv);

#ifdef ENABLE_LLVM
if (acfg->llvm) {
if (acfg->aot_opts.asm_only) {
if (acfg->aot_opts.outfile) {
acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
acfg->tmpbasename = g_strdup (acfg->tmpfname);
acfg->asm_fname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
acfg->tmpbasename = g_strdup (acfg->asm_fname);
} else {
acfg->tmpbasename = g_strdup_printf ("%s", acfg->image->name);
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
acfg->asm_fname = g_strdup_printf ("%s.s", acfg->tmpbasename);
}
g_assert (acfg->aot_opts.llvm_outfile);
acfg->llvm_sfile = g_strdup (acfg->aot_opts.llvm_outfile);
Expand All @@ -15326,7 +15322,7 @@ emit_aot_image (MonoAotCompile *acfg)
}

acfg->tmpbasename = g_build_filename (temp_path, "temp", (const char*)NULL);
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
acfg->asm_fname = g_strdup_printf ("%s.s", acfg->tmpbasename);
acfg->llvm_sfile = g_strdup_printf ("%s-llvm.s", acfg->tmpbasename);

if (acfg->aot_opts.static_link)
Expand All @@ -15336,26 +15332,88 @@ emit_aot_image (MonoAotCompile *acfg)

g_free (temp_path);
}

if (acfg->aot_opts.llvm_only && acfg->aot_opts.asm_only) {
if (acfg->aot_opts.no_opt)
acfg->bc_fname = g_strdup (acfg->aot_opts.llvm_outfile);
else
acfg->bc_fname = g_strdup_printf ("%s.bc", acfg->tmpbasename);
acfg->optbc_fname = g_strdup (acfg->aot_opts.llvm_outfile);
} else {
acfg->bc_fname = g_strdup_printf ("%s.bc", acfg->tmpbasename);
acfg->optbc_fname = g_strdup_printf ("%s.opt.bc", acfg->tmpbasename);
}
}
#endif

if (acfg->aot_opts.asm_only && !acfg->aot_opts.llvm_only) {
if (acfg->aot_opts.outfile)
acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
acfg->asm_fname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
else
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
acfg->fp = g_fopen (acfg->tmpfname, "w+");
acfg->asm_fname = g_strdup_printf ("%s.s", acfg->image->name);
} else {
if (strcmp (acfg->aot_opts.temp_path, "") == 0) {
acfg->fp = fdopen (g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL), "w+");
/* Done later */
} else {
acfg->tmpbasename = g_build_filename (acfg->aot_opts.temp_path, "temp", (const char*)NULL);
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
acfg->fp = g_fopen (acfg->tmpfname, "w+");
acfg->asm_fname = g_strdup_printf ("%s.s", acfg->tmpbasename);
}
}
}

/* Run external tools to assemble/link the aot image */
static int
assemble_link (MonoAotCompile *acfg)
{
int res;
TV_DECLARE (atv);
TV_DECLARE (btv);

TV_GETTIME (atv);

#ifdef ENABLE_LLVM
if (acfg->llvm) {
gboolean emit_res;

emit_res = compile_llvm_file (acfg);
if (!emit_res)
return 1;
}
#endif

if (!acfg->aot_opts.llvm_only) {
res = compile_asm (acfg);
if (res != 0) {
acfg_free (acfg);
return res;
}
}
TV_GETTIME (btv);
acfg->stats.link_time = GINT64_TO_INT (TV_ELAPSED (atv, btv));

return 0;
}

static int
emit_aot_image (MonoAotCompile *acfg)
{
int res;
TV_DECLARE (atv);
TV_DECLARE (btv);

TV_GETTIME (atv);

if (acfg->aot_opts.asm_only && !acfg->aot_opts.llvm_only) {
acfg->fp = g_fopen (acfg->asm_fname, "w+");
} else {
if (strcmp (acfg->aot_opts.temp_path, "") == 0) {
acfg->fp = fdopen (g_file_open_tmp ("mono_aot_XXXXXX", &acfg->asm_fname, NULL), "w+");
} else {
acfg->fp = g_fopen (acfg->asm_fname, "w+");
}
}
if (acfg->fp == 0 && !acfg->aot_opts.llvm_only) {
aot_printerrf (acfg, "Unable to open file '%s': %s\n", acfg->tmpfname, strerror (errno));
aot_printerrf (acfg, "Unable to open file '%s': %s\n", acfg->asm_fname, strerror (errno));
return 1;
}
if (acfg->fp)
Expand Down Expand Up @@ -15473,13 +15531,8 @@ emit_aot_image (MonoAotCompile *acfg)
fclose (acfg->data_outfile);

#ifdef ENABLE_LLVM
if (acfg->llvm) {
gboolean emit_res;

emit_res = emit_llvm_file (acfg);
if (!emit_res)
return 1;
}
if (acfg->llvm)
mono_llvm_emit_aot_module (acfg->bc_fname, g_path_get_basename (acfg->image->name));
#endif

emit_library_info (acfg);
Expand All @@ -15491,33 +15544,29 @@ emit_aot_image (MonoAotCompile *acfg)
if (!acfg->aot_opts.stats)
aot_printf (acfg, "Compiled: %d/%d\n", acfg->stats.ccount, acfg->stats.mcount);

TV_GETTIME (atv);
if (acfg->w) {
res = mono_img_writer_emit_writeout (acfg->w);
if (res != 0) {
acfg_free (acfg);
return res;
}
res = compile_asm (acfg);
if (res != 0) {
acfg_free (acfg);
return res;
}
}
TV_GETTIME (btv);
acfg->stats.link_time = GINT64_TO_INT (TV_ELAPSED (atv, btv));

if (acfg->aot_opts.stats)
print_stats (acfg);

aot_printf (acfg, "JIT time: %d ms, Generation time: %d ms, Assembly+Link time: %d ms.\n", acfg->stats.jit_time / 1000, acfg->stats.gen_time / 1000, acfg->stats.link_time / 1000);

if (acfg->aot_opts.depfile)
create_depfile (acfg);

if (acfg->aot_opts.dump_json)
aot_dump (acfg);

res = assemble_link (acfg);
if (res)
return res;

if (acfg->aot_opts.stats)
print_stats (acfg);

aot_printf (acfg, "JIT time: %d ms, Generation time: %d ms, Assembly+Link time: %d ms.\n", acfg->stats.jit_time / 1000, acfg->stats.gen_time / 1000, acfg->stats.link_time / 1000);

if (!acfg->aot_opts.save_temps && acfg->temp_dir_to_delete) {
char *command = g_strdup_printf ("rm -r %s", acfg->temp_dir_to_delete);
execute_system (command);
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/mini/interp/jiterpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ mono_jiterp_parse_option (const char *option)

const char *arr[2] = { option, NULL };
int temp;
mono_options_parse_options (arr, 1, &temp, NULL);
mono_options_parse_options (arr, 1, &temp, NULL, NULL);
return TRUE;
}

Expand Down

0 comments on commit 807b012

Please sign in to comment.