+
+ dump(DUMP_RA, irg, "-ra", dump_ir_block_graph_sched);
+ be_do_stat_nodes(irg, "06 Register Allocation");
+
+ /* let the code generator 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_nodes(birg->abi);
+ be_remove_dead_nodes_from_schedule(irg);
+ be_abi_fix_stack_bias(birg->abi);
+ BE_TIMER_POP(t_abi);
+
+ dump(DUMP_SCHED, irg, "-fix_stack_after_ra", dump_ir_block_graph_sched);
+
+ BE_TIMER_PUSH(t_finish);
+ arch_code_generator_finish(birg->cg);
+ BE_TIMER_POP(t_finish);
+
+ dump(DUMP_FINAL, irg, "-finish", dump_ir_block_graph_sched);
+
+ /* check schedule and register allocation */
+ BE_TIMER_PUSH(t_verify);
+ if (be_options.vrfy_option == BE_VRFY_WARN) {
+ irg_verify(irg, VRFY_ENFORCE_SSA);
+ be_check_dominance(irg);
+ be_verify_out_edges(irg);
+ be_verify_schedule(birg);
+ be_verify_register_allocation(env.arch_env, irg);
+ } else if (be_options.vrfy_option == BE_VRFY_ASSERT) {
+ assert(irg_verify(irg, VRFY_ENFORCE_SSA) && "irg verification failed");
+ assert(be_verify_out_edges(irg) && "out edge verification failed");
+ assert(be_check_dominance(irg) && "Dominance verification failed");
+ assert(be_verify_schedule(birg) && "Schedule verification failed");
+ assert(be_verify_register_allocation(env.arch_env, irg)
+ && "register allocation verification failed");
+
+ }
+ BE_TIMER_POP(t_verify);
+
+ /* 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_block_graph_sched);
+
+ BE_TIMER_PUSH(t_abi);
+ be_abi_free(birg->abi);
+ BE_TIMER_POP(t_abi);
+
+ be_do_stat_nodes(irg, "07 Final");
+ restore_optimization_state(&state);
+
+ BE_TIMER_ONLY(num_nodes_a = get_num_reachable_nodes(irg));
+ BE_TIMER_POP(t_other);
+
+#define LC_EMIT(timer) \
+ if(!be_stat_ev_is_active()) { \
+ printf("%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0); \
+ } else { \
+ be_stat_ev_l(lc_timer_get_name(timer), lc_timer_elapsed_msec(timer)); \
+ }
+#define LC_EMIT_RA(timer) \
+ if(!be_stat_ev_is_active()) { \
+ printf("\t%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0); \
+ } else { \
+ be_stat_ev_l(lc_timer_get_name(timer), lc_timer_elapsed_msec(timer)); \
+ }
+ BE_TIMER_ONLY(
+ if(!be_stat_ev_is_active()) {
+ printf("==>> IRG %s <<==\n", get_entity_name(get_irg_entity(irg)));
+ printf("# nodes at begin: %u\n", num_nodes_b);
+ printf("# nodes before ra: %u\n", num_nodes_r);
+ printf("# nodes at end: %u\n\n", num_nodes_a);
+ }
+ LC_EMIT(t_abi);
+ LC_EMIT(t_codegen);
+ LC_EMIT(t_sched);
+ LC_EMIT(t_constr);
+ LC_EMIT(t_regalloc);
+ if(global_ra_timer != NULL) {
+ LC_EMIT_RA(global_ra_timer->t_prolog);
+ LC_EMIT_RA(global_ra_timer->t_live);
+ LC_EMIT_RA(global_ra_timer->t_spill);
+ LC_EMIT_RA(global_ra_timer->t_spillslots);
+ LC_EMIT_RA(global_ra_timer->t_color);
+ LC_EMIT_RA(global_ra_timer->t_ifg);
+ LC_EMIT_RA(global_ra_timer->t_copymin);
+ LC_EMIT_RA(global_ra_timer->t_ssa);
+ LC_EMIT_RA(global_ra_timer->t_epilog);
+ LC_EMIT_RA(global_ra_timer->t_verify);
+ LC_EMIT_RA(global_ra_timer->t_other);
+ }
+ LC_EMIT(t_finish);
+ LC_EMIT(t_emit);
+ LC_EMIT(t_verify);
+ LC_EMIT(t_other);
+ );
+#undef LC_EMIT_RA
+#undef LC_EMIT
+
+ be_free_birg(birg);
+
+ /* switched off due to statistics (statistic module needs all irgs) */
+#if 0 /* STA needs irgs */
+#ifdef FIRM_STATISTICS
+ if (! stat_is_active())
+#endif /* FIRM_STATISTICS */
+ free_ir_graph(irg);
+#endif /* if 0 */
+ if(be_stat_ev_is_active()) {
+ be_stat_ev_pop();
+ }