give Bad nodes a mode
[libfirm] / ir / be / bemain.c
index 9d1eb93..07afa5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -73,6 +73,7 @@
 #include "be_dbgout.h"
 #include "beirg.h"
 #include "bestack.h"
+#include "beemitter.h"
 
 #define NEW_ID(s) new_id_from_chars(s, sizeof(s) - 1)
 
 static be_options_t be_options = {
        DUMP_NONE,                         /* dump flags */
        BE_TIME_OFF,                       /* no timing */
-       0,                                 /* no opt profile */
+       false,                             /* profile_generate */
+       false,                             /* profile_use */
        0,                                 /* try to omit frame pointer */
        0,                                 /* create PIC code */
-       0,                                 /* create gprof compatible profiling code */
        BE_VERIFY_WARN,                    /* verification level: warn */
-       "linux",                           /* target OS name */
        "i44pc52.info.uni-karlsruhe.de",   /* ilp server */
        "cplex",                           /* ilp solver */
        0,                                 /* enable statistic event dumping */
        "",                                /* print stat events */
 };
 
-/* config file. */
-static char config_file[256] = { 0 };
-
 /* back end instruction set architecture to use */
 static const arch_isa_if_t *isa_if = NULL;
 
@@ -129,19 +126,15 @@ static lc_opt_enum_int_var_t verify_var = {
 };
 
 static const lc_opt_table_entry_t be_main_options[] = {
-       LC_OPT_ENT_STR      ("config",     "read another config file containing backend options", config_file, sizeof(config_file)),
        LC_OPT_ENT_ENUM_MASK("dump",       "dump irg on several occasions",                       &dump_var),
        LC_OPT_ENT_BOOL     ("omitfp",     "omit frame pointer",                                  &be_options.omit_fp),
        LC_OPT_ENT_BOOL     ("pic",        "create PIC code",                                     &be_options.pic),
-       LC_OPT_ENT_BOOL     ("gprof",      "create gprof profiling code",                         &be_options.gprof),
        LC_OPT_ENT_ENUM_PTR ("verify",     "verify the backend irg",                              &verify_var),
        LC_OPT_ENT_BOOL     ("time",       "get backend timing statistics",                       &be_options.timing),
-       LC_OPT_ENT_BOOL     ("profile",    "instrument the code for execution count profiling",   &be_options.opt_profile),
-       LC_OPT_ENT_STR      ("os",         "specify target operating system",                     &be_options.target_os, sizeof(be_options.target_os)),
-#ifdef FIRM_STATISTICS
+       LC_OPT_ENT_BOOL     ("profilegenerate", "instrument the code for execution count profiling",   &be_options.opt_profile_generate),
+       LC_OPT_ENT_BOOL     ("profileuse",      "use existing profile data",                           &be_options.opt_profile_use),
        LC_OPT_ENT_BOOL     ("statev",     "dump statistic events",                               &be_options.statev),
        LC_OPT_ENT_STR      ("filtev",     "filter for stat events (regex if support is active",  &be_options.filtev, sizeof(be_options.filtev)),
-#endif
 
 #ifdef WITH_ILP
        LC_OPT_ENT_STR ("ilp.server", "the ilp server name", be_options.ilp_server, sizeof(be_options.ilp_server)),
@@ -370,7 +363,6 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
        memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags));
        env->arch_env = arch_env_init(isa_if, file_handle, env);
 
-       be_dbg_open();
        return env;
 }
 
@@ -379,9 +371,6 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
  */
 static void be_done_env(be_main_env_t *env)
 {
-       arch_env_done(env->arch_env);
-       be_dbg_close();
-
        pmap_destroy(env->ent_trampoline_map);
        pmap_destroy(env->ent_pic_symbol_map);
        free_type(env->pic_trampolines_type);
@@ -477,17 +466,28 @@ ir_timer_t *be_timers[T_LAST+1];
 
 void be_lower_for_target(void)
 {
-       int i;
+       size_t i;
 
        isa_if->lower_for_target();
        /* set the phase to low */
-       for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
-               ir_graph *irg = get_irp_irg(i);
+       for (i = get_irp_n_irgs(); i > 0;) {
+               ir_graph *irg = get_irp_irg(--i);
                set_irg_phase_state(irg, phase_low);
        }
        set_irp_phase_state(phase_low);
 }
 
+static void emit_global_asms(void)
+{
+       size_t n = get_irp_n_asms();
+       size_t i;
+       for (i = 0; i < n; ++i) {
+               be_emit_cstring("#APP\n");
+               be_emit_ident(get_irp_asm(i));
+               be_emit_cstring("\n#NO_APP\n");
+       }
+}
+
 /**
  * The Firm backend main loop.
  * Do architecture specific lowering for all graphs
@@ -500,7 +500,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 {
        static const char suffix[] = ".prof";
 
-       int           i, num_birgs, stat_active = 0;
+       size_t        i, num_birgs;
+       int           stat_active = 0;
        be_main_env_t env;
        char          prof_filename[256];
        be_irg_t      *birgs;
@@ -518,9 +519,12 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
        be_init_env(&env, file_handle);
        env.cup_name = cup_name;
 
-       be_dbg_so(cup_name);
+       be_dbg_open();
+       be_dbg_unit_begin(cup_name);
        be_dbg_types();
 
+       emit_global_asms();
+
        arch_env = env.arch_env;
 
        /* backend may provide an ordered list of irgs where code should be
@@ -546,23 +550,24 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                Get the filename for the profiling data.
                Beware: '\0' is already included in sizeof(suffix)
        */
-       sprintf(prof_filename, "%.*s%s\n", (int)(sizeof(prof_filename) - sizeof(suffix)), cup_name, suffix);
-
-       /*
-               Next: Either instruments all irgs with profiling code
-               or try to read in profile data for current translation unit.
-       */
-       if (be_options.opt_profile) {
-               ir_graph *prof_init_irg = ir_profile_instrument(prof_filename, profile_default);
+       sprintf(prof_filename, "%.*s%s",
+               (int)(sizeof(prof_filename) - sizeof(suffix)), cup_name, suffix);
+
+       if (be_options.opt_profile_use) {
+               bool res = ir_profile_read(prof_filename);
+               if (!res) {
+                       fprintf(stderr, "Warning: Couldn't read profile data '%s'\n",
+                               prof_filename);
+               }
+       }
+       if (be_options.opt_profile_generate) {
+               ir_graph *prof_init_irg
+                       = ir_profile_instrument(prof_filename);
                initialize_birg(&birgs[num_birgs], prof_init_irg, &env);
                num_birgs++;
-       } else {
-               ir_profile_read(prof_filename);
        }
 
-#ifdef FIRM_STATISTICS
        stat_active = stat_is_active();
-#endif /* FIRM_STATISTICS */
 
        /* For all graphs */
        for (i = 0; i < num_birgs; ++i) {
@@ -639,6 +644,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                        assert(be_check_dominance(irg) && "Dominance verification failed");
                }
 
+               dump(DUMP_PREPARED, irg, "code-selection");
+
                be_timer_push(T_EXECFREQ);
                /**
                 * Create execution frequencies from profile data or estimate some
@@ -711,9 +718,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                /* Do register allocation */
                be_allocate_registers(irg);
 
-#ifdef FIRM_STATISTICS
                stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg, birg->exec_freq));
-#endif
 
                dump(DUMP_RA, irg, "ra");
 
@@ -805,6 +810,12 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                be_free_birg(irg);
                stat_ev_ctx_pop("bemain_irg");
        }
+
+       arch_env_done(arch_env);
+
+       be_dbg_unit_end();
+       be_dbg_close();
+
        ir_profile_free();
        be_done_env(&env);
 
@@ -816,18 +827,6 @@ void be_main(FILE *file_handle, const char *cup_name)
 {
        ir_timer_t *t = NULL;
 
-       /* The user specified another config file to read. do that now. */
-       if (config_file[0] != '\0') {
-               FILE *f = fopen(config_file, "rt");
-
-               if (f != NULL) {
-                       lc_opt_from_file(config_file, f, NULL);
-                       fclose(f);
-               } else {
-                       fprintf(stderr, "Warning: Cannot open config file '%s'\n", config_file);
-               }
-       }
-
        if (be_options.timing == BE_TIME_ON) {
                t = ir_timer_new();
 
@@ -838,7 +837,6 @@ void be_main(FILE *file_handle, const char *cup_name)
                ir_timer_reset_and_start(t);
        }
 
-#ifdef FIRM_STATISTICS
        if (be_options.statev) {
                const char *dot = strrchr(cup_name, '.');
                const char *pos = dot ? dot : cup_name + strlen(cup_name);
@@ -850,7 +848,6 @@ void be_main(FILE *file_handle, const char *cup_name)
                stat_ev_begin(buf, be_options.filtev);
                stat_ev_ctx_push_str("bemain_compilation_unit", cup_name);
        }
-#endif
 
        be_main_loop(file_handle, cup_name);
 
@@ -865,12 +862,10 @@ void be_main(FILE *file_handle, const char *cup_name)
                }
        }
 
-#ifdef FIRM_STATISTICS
        if (be_options.statev) {
                stat_ev_ctx_pop("bemain_compilation_unit");
                stat_ev_end();
        }
-#endif
 }
 
 static int do_lower_for_target(ir_prog *irp, void *context)