beabi: Remove unnecessary exclusion/inclusion of ignore registers from call/return.
[libfirm] / ir / be / bemain.c
index 529b337..48a95ed 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "obst.h"
 #include "bitset.h"
-
+#include "statev.h"
 #include "irprog.h"
 #include "irgopt.h"
 #include "irgraph.h"
@@ -53,6 +53,7 @@
 
 #include "bearch.h"
 #include "be_t.h"
+#include "begnuas.h"
 #include "bemodule.h"
 #include "beutil.h"
 #include "benode.h"
@@ -398,21 +399,19 @@ ir_type *be_get_type_long_double(void)
  * @param env          an empty environment
  * @param file_handle  the file handle where the output will be written to
  */
-static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle,
-                                  const char *compilation_unit_name)
+static be_main_env_t *be_init_env(be_main_env_t *const env, char const *const compilation_unit_name)
 {
        memset(env, 0, sizeof(*env));
-       env->file_handle          = file_handle;
        env->ent_trampoline_map   = pmap_create();
        env->pic_trampolines_type = new_type_class(NEW_ID("$PIC_TRAMPOLINE_TYPE"));
        env->ent_pic_symbol_map   = pmap_create();
        env->pic_symbols_type     = new_type_struct(NEW_ID("$PIC_SYMBOLS_TYPE"));
        env->cup_name             = compilation_unit_name;
+       env->arch_env             = isa_if->begin_codegeneration();
 
        set_class_final(env->pic_trampolines_type, 1);
 
        memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags));
-       env->arch_env = arch_env_begin_codegeneration(isa_if, env);
 
        return env;
 }
@@ -456,7 +455,6 @@ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env)
        irg->be_data = birg;
 
        memset(birg, 0, sizeof(*birg));
-       birg->irg = irg;
        birg->main_env = env;
        obstack_init(&birg->obst);
        birg->lv = be_liveness_new(irg);
@@ -481,7 +479,6 @@ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env)
        /* Ensure, that the ir_edges are computed. */
        assure_edges(irg);
 
-       set_irg_phase_state(irg, phase_backend);
        be_info_init_irg(irg);
 
        dump(DUMP_INITIAL, irg, "prepared");
@@ -496,7 +493,6 @@ static const char *get_timer_name(be_timer_id_t id)
        case T_CODEGEN:        return "codegen";
        case T_RA_PREPARATION: return "ra_preparation";
        case T_SCHED:          return "sched";
-       case T_SPLIT:          return "split";
        case T_CONSTR:         return "constr";
        case T_FINISH:         return "finish";
        case T_EMIT:           return "emit";
@@ -506,7 +502,6 @@ static const char *get_timer_name(be_timer_id_t id)
        case T_LIVE:           return "live";
        case T_EXECFREQ:       return "execfreq";
        case T_SSA_CONSTR:     return "ssa_constr";
-       case T_RA_PROLOG:      return "ra_prolog";
        case T_RA_EPILOG:      return "ra_epilog";
        case T_RA_CONSTR:      return "ra_constr";
        case T_RA_SPILL:       return "ra_spill";
@@ -527,16 +522,13 @@ void be_lower_for_target(void)
 
        initialize_isa();
 
-       /* shouldn't lower program twice */
-       assert(get_irp_phase_state() != phase_low);
-
        isa_if->lower_for_target();
        /* set the phase to low */
        for (i = get_irp_n_irgs(); i > 0;) {
                ir_graph *irg = get_irp_irg(--i);
-               set_irg_phase_state(irg, phase_low);
+               assert(!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_TARGET_LOWERED));
+               add_irg_constraints(irg, IR_GRAPH_CONSTRAINT_TARGET_LOWERED);
        }
-       set_irp_phase_state(phase_low);
 }
 
 /**
@@ -562,7 +554,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
        be_timing = (be_options.timing == BE_TIME_ON);
 
        /* perform target lowering if it didn't happen yet */
-       if (get_irp_phase_state() != phase_low)
+       if (get_irp_n_irgs() > 0 && !irg_is_constrained(get_irp_irg(0), IR_GRAPH_CONSTRAINT_TARGET_LOWERED))
                be_lower_for_target();
 
        if (be_timing) {
@@ -571,7 +563,10 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                }
        }
 
-       be_init_env(&env, file_handle, cup_name);
+       be_init_env(&env, cup_name);
+
+       be_emit_init(file_handle);
+       be_gas_begin_compilation_unit(&env);
 
        arch_env = env.arch_env;
 
@@ -634,18 +629,19 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
        }
 
        /* For all graphs */
-       for (i = 0; i < num_birgs; ++i) {
-               be_irg_t *birg = &birgs[i];
-               ir_graph *irg  = birg->irg;
-               optimization_state_t state;
+       for (i = 0; i < num_irgs; ++i) {
+               ir_graph  *const irg    = get_irp_irg(i);
+               ir_entity *const entity = get_irg_entity(irg);
+               if (get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN)
+                       continue;
 
                /* set the current graph (this is important for several firm functions) */
                current_ir_graph = irg;
 
                if (stat_ev_enabled) {
-                       stat_ev_ctx_push_fobj("bemain_irg", irg);
-                       be_stat_ev("bemain_insns_start", be_count_insns(irg));
-                       be_stat_ev("bemain_blocks_start", be_count_blocks(irg));
+                       stat_ev_ctx_push_fmt("bemain_irg", "%+F", irg);
+                       stat_ev_ull("bemain_insns_start", be_count_insns(irg));
+                       stat_ev_ull("bemain_blocks_start", be_count_blocks(irg));
                }
 
                /* stop and reset timers */
@@ -655,15 +651,14 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                be_timer_push(T_VERIFY);
                if (be_options.verify_option == BE_VERIFY_WARN) {
                        irg_verify(irg, VERIFY_ENFORCE_SSA);
-                       be_check_dominance(irg);
                } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
                        assert(irg_verify(irg, VERIFY_ENFORCE_SSA) && "irg verification failed");
-                       assert(be_check_dominance(irg) && "Dominance verification failed");
                }
                be_timer_pop(T_VERIFY);
 
                /* get a code generator for this graph. */
-               arch_env->impl->init_graph(irg);
+               if (arch_env->impl->init_graph)
+                       arch_env->impl->init_graph(irg);
 
                /* some transformations need to be done before abi introduce */
                if (arch_env->impl->before_abi != NULL)
@@ -691,24 +686,12 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 
                dump(DUMP_PREPARED, irg, "before-code-selection");
 
-               if (be_options.verify_option == BE_VERIFY_WARN) {
-                       be_check_dominance(irg);
-               } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
-                       assert(be_check_dominance(irg) && "Dominance verification failed");
-               }
-
                /* perform codeselection */
                be_timer_push(T_CODEGEN);
                if (arch_env->impl->prepare_graph != NULL)
                        arch_env->impl->prepare_graph(irg);
                be_timer_pop(T_CODEGEN);
 
-               if (be_options.verify_option == BE_VERIFY_WARN) {
-                       be_check_dominance(irg);
-               } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
-                       assert(be_check_dominance(irg) && "Dominance verification failed");
-               }
-
                dump(DUMP_PREPARED, irg, "code-selection");
 
                /* disabled for now, fails for EmptyFor.c and XXEndless.c */
@@ -729,6 +712,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                /* introduce patterns to assure constraints */
                be_timer_push(T_CONSTR);
                /* we switch off optimizations here, because they might cause trouble */
+               optimization_state_t state;
                save_optimization_state(&state);
                set_optimize(0);
                set_opt_cse(0);
@@ -760,8 +744,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 
                if (stat_ev_enabled) {
                        stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg));
-                       be_stat_ev("bemain_insns_before_ra", be_count_insns(irg));
-                       be_stat_ev("bemain_blocks_before_ra", be_count_blocks(irg));
+                       stat_ev_ull("bemain_insns_before_ra", be_count_insns(irg));
+                       stat_ev_ull("bemain_blocks_before_ra", be_count_blocks(irg));
                }
 
                /* Do register allocation */
@@ -779,20 +763,18 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                dump(DUMP_FINAL, irg, "finish");
 
                if (stat_ev_enabled) {
-                       be_stat_ev("bemain_insns_finish", be_count_insns(irg));
-                       be_stat_ev("bemain_blocks_finish", be_count_blocks(irg));
+                       stat_ev_ull("bemain_insns_finish", be_count_insns(irg));
+                       stat_ev_ull("bemain_blocks_finish", be_count_blocks(irg));
                }
 
                /* check schedule and register allocation */
                be_timer_push(T_VERIFY);
                if (be_options.verify_option == BE_VERIFY_WARN) {
                        irg_verify(irg, VERIFY_ENFORCE_SSA);
-                       be_check_dominance(irg);
                        be_verify_schedule(irg);
                        be_verify_register_allocation(irg);
                } else if (be_options.verify_option == BE_VERIFY_ASSERT) {
                        assert(irg_verify(irg, VERIFY_ENFORCE_SSA) && "irg verification failed");
-                       assert(be_check_dominance(irg) && "Dominance verification failed");
                        assert(be_verify_schedule(irg) && "Schedule verification failed");
                        assert(be_verify_register_allocation(irg)
                               && "register allocation verification failed");
@@ -808,12 +790,6 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 
                dump(DUMP_FINAL, irg, "end");
 
-               if (!arch_env->custom_abi) {
-                       be_timer_push(T_ABI);
-                       be_abi_free(irg);
-                       be_timer_pop(T_ABI);
-               }
-
                restore_optimization_state(&state);
 
                be_timer_pop(T_OTHER);
@@ -832,7 +808,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                                       get_entity_name(get_irg_entity(irg)));
                                for (t = T_FIRST; t < T_LAST+1; ++t) {
                                        double val = ir_timer_elapsed_usec(be_timers[t]) / 1000.0;
-                                       printf("%-20s: %8.3lf msec\n", get_timer_name(t), val);
+                                       printf("%-20s: %10.3f msec\n", get_timer_name(t), val);
                                }
                        }
                        for (t = T_FIRST; t < T_LAST+1; ++t) {
@@ -844,6 +820,9 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                stat_ev_ctx_pop("bemain_irg");
        }
 
+       be_gas_end_compilation_unit(&env);
+       be_emit_exit();
+
        arch_env_end_codegeneration(arch_env);
 
        be_done_env(&env);
@@ -887,7 +866,7 @@ void be_main(FILE *file_handle, const char *cup_name)
                        stat_ev_dbl("bemain_backend_time", ir_timer_elapsed_msec(t));
                } else {
                        double val = ir_timer_elapsed_usec(t) / 1000.0;
-                       printf("%-20s: %8.3lf msec\n", "BEMAINLOOP", val);
+                       printf("%-20s: %10.3f msec\n", "BEMAINLOOP", val);
                }
        }