X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbemain.c;h=77cc93c3b3cbfe007558a8aaec6af0d7a5325a2f;hb=4c0f123728ea93f7f0a4af114b040a58a9e97059;hp=4c8e8875b0b52203a157227e4cc1c27dc4bfd73b;hpb=6161a76604293595d3467597e036d9f02ac66e20;p=libfirm diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 4c8e8875b..77cc93c3b 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -29,6 +29,7 @@ #include "irloop_t.h" #include "irtools.h" #include "return.h" +#include "firmstat.h" #include "bearch.h" #include "firm/bearch_firm.h" @@ -45,7 +46,6 @@ #include "besched_t.h" #include "belistsched.h" #include "belive_t.h" -#include "bespillilp.h" #include "bespillbelady.h" #include "bera.h" #include "beraextern.h" @@ -228,7 +228,6 @@ const backend_params *be_init(void) be_opt_register(); be_sched_init(); - be_liveness_init(); be_numbering_init(); be_copy_opt_init(); copystat_init(); @@ -340,15 +339,7 @@ static void be_main_loop(FILE *file_handle) unsigned num_nodes_b = 0; unsigned num_nodes_a = 0; unsigned num_nodes_r = 0; - unsigned ra_prolog = 0; - unsigned ra_epilog = 0; - unsigned ra_live = 0; - unsigned ra_spill = 0; - unsigned ra_color = 0; - unsigned ra_ifg = 0; - unsigned ra_copymin = 0; - unsigned ra_ssa = 0; - lc_timer_t *t_prolog, *t_abi, *t_codegen, *t_sched, *t_constr, *t_regalloc, *t_finish, *t_emit, *t_other; + lc_timer_t *t_prolog, *t_abi, *t_codegen, *t_sched, *t_constr, *t_regalloc, *t_finish, *t_emit, *t_other, *t_verify; be_ra_timer_t *ra_timer; if (be_options.timing == BE_TIME_ON) { @@ -360,6 +351,7 @@ static void be_main_loop(FILE *file_handle) t_regalloc = lc_timer_register("regalloc", "register allocation"); t_finish = lc_timer_register("finish", "graph finish"); t_emit = lc_timer_register("emiter", "code emiter"); + t_verify = lc_timer_register("verify", "graph verification"); t_other = lc_timer_register("other", "other"); } @@ -370,8 +362,26 @@ static void be_main_loop(FILE *file_handle) /* for debugging, anchors helps */ // dump_all_anchors(1); -#define BE_TIMER_PUSH(timer) if (be_options.timing == BE_TIME_ON) lc_timer_push(timer) -#define BE_TIMER_POP() if (be_options.timing == BE_TIME_ON) lc_timer_pop() +#define BE_TIMER_PUSH(timer) \ + if (be_options.timing == BE_TIME_ON) { \ + int res = lc_timer_push(timer); \ + if (vrfy_option == BE_VRFY_ASSERT) \ + assert(res && "Timer already on stack, cannot be pushed twice."); \ + else if (vrfy_option == BE_VRFY_WARN && ! res) \ + fprintf(stderr, "Timer %s already on stack, cannot be pushed twice.\n", \ + lc_timer_get_name(timer)); \ + } +#define BE_TIMER_POP(timer) \ + if (be_options.timing == BE_TIME_ON) { \ + lc_timer_t *tmp = lc_timer_pop(); \ + if (vrfy_option == BE_VRFY_ASSERT) \ + assert(tmp == timer && "Attempt to pop wrong timer."); \ + else if (vrfy_option == BE_VRFY_WARN && tmp != timer) \ + fprintf(stderr, "Attempt to pop wrong timer. %s is on stack, trying to pop %s.\n", \ + lc_timer_get_name(tmp), lc_timer_get_name(timer)); \ + timer = tmp; \ + } + #define BE_TIMER_ONLY(code) if (be_options.timing == BE_TIME_ON) do { code; } while(0) /* For all graphs */ @@ -391,9 +401,10 @@ static void be_main_loop(FILE *file_handle) LC_STOP_AND_RESET_TIMER(t_regalloc); LC_STOP_AND_RESET_TIMER(t_finish); LC_STOP_AND_RESET_TIMER(t_emit); + LC_STOP_AND_RESET_TIMER(t_verify); LC_STOP_AND_RESET_TIMER(t_other); } - BE_TIMER_PUSH(t_other); + BE_TIMER_PUSH(t_other); /* t_other */ BE_TIMER_ONLY(num_nodes_b = get_num_reachable_nodes(irg)); @@ -420,23 +431,25 @@ static void be_main_loop(FILE *file_handle) /* create the code generator and generate code. */ prepare_graph(&birg); + BE_TIMER_POP(t_prolog); + /* some transformations need to be done before abi introduce */ + BE_TIMER_PUSH(t_codegen); arch_code_generator_before_abi(birg.cg); - - BE_TIMER_POP(); - BE_TIMER_PUSH(t_abi); + BE_TIMER_POP(t_codegen); /* implement the ABI conventions. */ + BE_TIMER_PUSH(t_abi); birg.abi = be_abi_introduce(&birg); - dump(DUMP_ABI, irg, "-abi", dump_ir_block_graph); + BE_TIMER_POP(t_abi); + dump(DUMP_ABI, irg, "-abi", dump_ir_block_graph); be_do_stat_nodes(irg, "02 Abi"); - BE_TIMER_POP(); - BE_TIMER_PUSH(t_codegen); - /* generate code */ + BE_TIMER_PUSH(t_codegen); arch_code_generator_prepare_graph(birg.cg); + BE_TIMER_POP(t_codegen); be_do_stat_nodes(irg, "03 Prepare"); @@ -451,26 +464,30 @@ static void be_main_loop(FILE *file_handle) /* Compute loop nesting information (for weighting copies) */ construct_cf_backedges(irg); - dump(DUMP_PREPARED, irg, "-prepared", dump_ir_block_graph); - - BE_TIMER_POP(); BE_TIMER_ONLY(num_nodes_r = get_num_reachable_nodes(irg)); - BE_TIMER_PUSH(t_sched); - /* Schedule the graphs. */ + /* let backend prepare scheduling */ + BE_TIMER_PUSH(t_codegen); arch_code_generator_before_sched(birg.cg); + BE_TIMER_POP(t_codegen); + + /* schedule the irg */ + BE_TIMER_PUSH(t_sched); list_sched(&birg, be_enable_mris); + BE_TIMER_POP(t_sched); + dump(DUMP_SCHED, irg, "-sched", dump_ir_block_graph_sched); /* check schedule */ + BE_TIMER_PUSH(t_verify); be_sched_vrfy(birg.irg, vrfy_option); + BE_TIMER_POP(t_verify); be_do_stat_nodes(irg, "04 Schedule"); - BE_TIMER_POP(); + /* introduce patterns to assure constraints */ BE_TIMER_PUSH(t_constr); - /* we switch off optimizations here, because they might cause trouble */ save_optimization_state(&state); set_optimize(0); @@ -479,73 +496,78 @@ static void be_main_loop(FILE *file_handle) /* add Keeps for should_be_different constrained nodes */ /* beware: needs schedule due to usage of be_ssa_constr */ assure_constraints(&birg); - dump(DUMP_SCHED, irg, "-assured", dump_ir_block_graph_sched); + BE_TIMER_POP(t_constr); + dump(DUMP_SCHED, irg, "-assured", dump_ir_block_graph_sched); be_do_stat_nodes(irg, "05 Constraints"); /* connect all stack modifying nodes together (see beabi.c) */ - be_abi_fix_stack_nodes(birg.abi); + BE_TIMER_PUSH(t_abi); + be_abi_fix_stack_nodes(birg.abi, NULL); + BE_TIMER_POP(t_abi); + dump(DUMP_SCHED, irg, "-fix_stack", dump_ir_block_graph_sched); /* check schedule */ + BE_TIMER_PUSH(t_verify); be_sched_vrfy(birg.irg, vrfy_option); + BE_TIMER_POP(t_verify); /* do some statistics */ be_do_stat_reg_pressure(&birg); /* stuff needs to be done after scheduling but before register allocation */ + BE_TIMER_PUSH(t_codegen); arch_code_generator_before_ra(birg.cg); - - BE_TIMER_POP(); - BE_TIMER_PUSH(t_regalloc); + BE_TIMER_POP(t_codegen); /* Do register allocation */ + BE_TIMER_ONLY(lc_timer_start(t_regalloc)); ra_timer = ra->allocate(&birg); - dump(DUMP_RA, irg, "-ra", dump_ir_block_graph_sched); - - if (be_options.timing == BE_TIME_ON && ra_timer) { - ra_prolog = lc_timer_elapsed_msec(ra_timer->t_prolog); - ra_epilog = lc_timer_elapsed_msec(ra_timer->t_epilog); - ra_live = lc_timer_elapsed_msec(ra_timer->t_live); - ra_spill = lc_timer_elapsed_msec(ra_timer->t_spill); - ra_color = lc_timer_elapsed_msec(ra_timer->t_color); - ra_copymin = lc_timer_elapsed_msec(ra_timer->t_copymin); - ra_ssa = lc_timer_elapsed_msec(ra_timer->t_ssa); - ra_ifg = lc_timer_elapsed_msec(ra_timer->t_ifg); - } + BE_TIMER_ONLY(lc_timer_stop(t_regalloc)); + dump(DUMP_RA, irg, "-ra", dump_ir_block_graph_sched); be_do_stat_nodes(irg, "06 Register Allocation"); - BE_TIMER_POP(); + /* let the codegenerator prepare the graph for emitter */ BE_TIMER_PUSH(t_finish); - arch_code_generator_after_ra(birg.cg); + BE_TIMER_POP(t_finish); + + /* fix stack offsets */ + BE_TIMER_PUSH(t_abi); be_abi_fix_stack_bias(birg.abi); + BE_TIMER_POP(t_abi); /* check schedule */ + BE_TIMER_PUSH(t_verify); be_sched_vrfy(birg.irg, vrfy_option); + BE_TIMER_POP(t_verify); - BE_TIMER_POP(); + /* emit assembler code */ BE_TIMER_PUSH(t_emit); - arch_code_generator_done(birg.cg); + BE_TIMER_POP(t_emit); + dump(DUMP_FINAL, irg, "-end", dump_ir_extblock_graph_sched); + + BE_TIMER_PUSH(t_abi); be_abi_free(birg.abi); + BE_TIMER_POP(t_abi); be_do_stat_nodes(irg, "07 Final"); - - BE_TIMER_POP(); - restore_optimization_state(&state); BE_TIMER_ONLY(num_nodes_a = get_num_reachable_nodes(irg)); /* switched off due to statistics (statistic module needs all irgs) */ - // free_ir_graph(irg); - BE_TIMER_POP(); + if (! stat_is_active()) + free_ir_graph(irg); + + BE_TIMER_POP(t_other); -#define LC_EMIT(timer) printf("%-20s: %u msec\n", lc_timer_get_description(timer), lc_timer_elapsed_msec(timer)) -#define EMIT_RA_TIME(n, t) printf("%-20s: %u msec\n", n, t) +#define LC_EMIT(timer) printf("%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0) +#define LC_EMIT_RA(timer) printf("\t%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0) if (be_options.timing == BE_TIME_ON) { printf("==>> IRG %s <<==\n", get_entity_name(get_irg_entity(irg))); printf("# nodes at begin: %u\n", num_nodes_b); @@ -557,25 +579,28 @@ static void be_main_loop(FILE *file_handle) LC_EMIT(t_sched); LC_EMIT(t_constr); LC_EMIT(t_regalloc); - EMIT_RA_TIME("prolog", ra_prolog); - EMIT_RA_TIME("liveness", ra_live); - EMIT_RA_TIME("spilling", ra_spill); - EMIT_RA_TIME("coloring", ra_color); - EMIT_RA_TIME("ifg build", ra_ifg); - EMIT_RA_TIME("copymin", ra_copymin); - EMIT_RA_TIME("ssa destr", ra_ssa); - EMIT_RA_TIME("epilog", ra_epilog); + LC_EMIT_RA(ra_timer->t_prolog); + LC_EMIT_RA(ra_timer->t_live); + LC_EMIT_RA(ra_timer->t_spill); + LC_EMIT_RA(ra_timer->t_color); + LC_EMIT_RA(ra_timer->t_ifg); + LC_EMIT_RA(ra_timer->t_copymin); + LC_EMIT_RA(ra_timer->t_ssa); + LC_EMIT_RA(ra_timer->t_epilog); + LC_EMIT_RA(ra_timer->t_verify); + LC_EMIT_RA(ra_timer->t_other); LC_EMIT(t_finish); LC_EMIT(t_emit); + LC_EMIT(t_verify); LC_EMIT(t_other); } #undef LC_EMIT } be_done_env(&env); -#undef BE_TIME_START -#undef BE_TIME_STOP -#undef BE_TIME_ONLY +#undef BE_TIMER_POP +#undef BE_TIMER_PUSH +#undef BE_TIMER_ONLY } /* Main interface to the frontend. */