X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=driver%2Ffirm_opt.c;h=969d0388d5603be48cd02a053224e36352ecdd35;hb=8501f8b1f619827f2828ecdb0f04392f225f3955;hp=d2c976276fdf7580912aa6297976a5c2ea6f27c8;hpb=99fd093374df15b5aaf15f48a900d1a9a012dbd4;p=cparser diff --git a/driver/firm_opt.c b/driver/firm_opt.c index d2c9762..969d038 100644 --- a/driver/firm_opt.c +++ b/driver/firm_opt.c @@ -9,10 +9,7 @@ #include #include #include - -#ifdef FIRM_BACKEND #include -#endif /* FIRM_BACKEND */ #include "firm_opt.h" @@ -20,6 +17,10 @@ #include "firm_cmdline.h" #include "firm_timing.h" +#ifdef _WIN32 +#define snprintf _snprintf +#endif + #if defined(_DEBUG) || defined(FIRM_DEBUG) #define DBG(x) dbg_printf x #else @@ -108,6 +109,8 @@ static create_intrinsic_fkt *arch_create_intrinsic = NULL; static void *create_intrinsic_ctx = NULL; static const ir_settings_if_conv_t *if_conv_info = NULL; +ir_mode *firm_imm_fp_mode = NULL; + /* entities of runtime functions */ ir_entity_ptr rts_entities[rts_max]; @@ -288,6 +291,7 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi ir_graph *irg; unsigned aa_opt; + /* FIXME: cloning might ADD new graphs. */ irg_dump_no = calloc(get_irp_last_idx(), sizeof(*irg_dump_no)); set_opt_strength_red(firm_opt.strength_red); @@ -326,35 +330,32 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi CHECK_ALL(firm_opt.check_all); } - if (firm_opt.tail_rec) { - timer_push(TV_TAIL_REC); - opt_tail_recursion(); + /* first step: kill dead code */ + for (i = 0; i < get_irp_n_irgs(); i++) { + irg = current_ir_graph = get_irp_irg(i); + /* Confirm construction currently can only handle blocks with only one control + flow predecessor. Calling optimize_cf here removes Bad predecessors and help + the optimization of switch constructs. */ + timer_push(TV_CF_OPT); + optimize_graph_df(irg); + optimize_cf(irg); timer_pop(); - - DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "tail_rec"); - CHECK_ALL(firm_opt.check_all); } if (firm_opt.func_calls) { timer_push(TV_REAL_FUNC_CALL); - optimize_funccalls(firm_const_exists); + optimize_funccalls(firm_const_exists, NULL); timer_pop(); DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "func_call"); CHECK_ALL(firm_opt.check_all); } - if (firm_opt.do_inline) { - timer_push(TV_INLINE); - inline_leave_functions(500, 80, 30, FALSE); - timer_pop(); - DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "inl"); - CHECK_ALL(firm_opt.check_all); - } + /* do lowering on the const code irg */ + lower_const_code(); for (i = 0; i < get_irp_n_irgs(); i++) { irg = current_ir_graph = get_irp_irg(i); - #ifdef FIRM_EXT_GRS /* If SIMD optimization is on, make sure we have only 1 return */ if (firm_ext_grs.create_pattern || firm_ext_grs.simd_opt) @@ -386,12 +387,26 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "reassoc"); CHECK_ONE(firm_opt.check_all, irg); + compute_doms(irg); + CHECK_ONE(firm_opt.check_all, irg); + + if (firm_opt.code_place) { + timer_push(TV_CODE_PLACE); + set_opt_global_cse(1); + optimize_graph_df(irg); + place_code(irg); + set_opt_global_cse(0); + timer_pop(); + DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "place"); + CHECK_ONE(firm_opt.check_all, irg); + } + if (firm_opt.confirm) { /* Confirm construction currently can only handle blocks with only one control flow predecessor. Calling optimize_cf here removes Bad predecessors and help the optimization of switch constructs. */ timer_push(TV_CF_OPT); - optimize_cf(irg); + optimize_cf(irg); timer_pop(); DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "cfopt"); CHECK_ONE(firm_opt.check_all, irg); @@ -400,31 +415,18 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi timer_pop(); DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "confirms"); CHECK_ONE(firm_opt.check_all, irg); - } - timer_push(TV_LOCAL_OPT); - optimize_graph_df(irg); - timer_pop(); - DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "lopt"); - CHECK_ONE(firm_opt.check_all, irg); - - compute_doms(irg); - CHECK_ONE(firm_opt.check_all, irg); - - if (firm_opt.code_place) { - timer_push(TV_CODE_PLACE); - set_opt_global_cse(1); + timer_push(TV_LOCAL_OPT); optimize_graph_df(irg); - place_code(irg); - set_opt_global_cse(0); timer_pop(); - DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "place"); + DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "lopt"); CHECK_ONE(firm_opt.check_all, irg); } if (firm_opt.luffig) { opt_ldst2(irg); DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "ldst2"); + CHECK_ONE(firm_opt.check_all, irg); } timer_push(TV_CF_OPT); @@ -433,13 +435,6 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "cfopt"); CHECK_ONE(firm_opt.check_all, irg); - /* should we really remove the Confirm here? */ - if (firm_opt.confirm) { - timer_push(TV_CONFIRM_CREATE); - remove_confirms(irg); - timer_pop(); - } - irg_verify(irg, VRFY_ENFORCE_SSA); if (firm_opt.gvn_pre) { do_gvn_pre(irg); @@ -448,21 +443,13 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi irg_verify(irg, VRFY_ENFORCE_SSA); } - if (firm_opt.loop_unrolling) { - timer_push(TV_LOOP_UNROLL); - optimize_loop_unrolling(irg); - timer_pop(); - DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "loop"); - CHECK_ONE(firm_opt.check_all, irg); - } - if (firm_opt.load_store) { timer_push(TV_LOAD_STORE); optimize_load_store(irg); timer_pop(); DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "ldst"); CHECK_ONE(firm_opt.check_all, irg); - } + } lower_highlevel_graph(irg, firm_opt.lower_bitfields); @@ -482,6 +469,13 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi CHECK_ONE(firm_opt.check_all, irg); } + /* should we really remove the Confirm here? */ + if (firm_opt.confirm) { + timer_push(TV_CONFIRM_CREATE); + remove_confirms(irg); + timer_pop(); + } + compute_doms(irg); compute_postdoms(irg); DUMP_ONE_CFG_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "dom"); @@ -519,7 +513,7 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi } timer_push(TV_OSR); - opt_osr(current_ir_graph, osr_flag_default /*| osr_flag_ignore_x86_shift*/); + opt_osr(current_ir_graph, osr_flag_default | osr_flag_keep_reg_pressure | osr_flag_ignore_x86_shift); timer_pop(); DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "stred"); CHECK_ONE(firm_opt.check_all, irg); @@ -538,9 +532,40 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi CHECK_ONE(firm_opt.check_all, irg); } + if (firm_opt.do_inline) { + inline_functions(500, 50); + DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "inl"); + CHECK_ALL(firm_opt.check_all); + } if (firm_opt.cloning) { proc_cloning((float)firm_opt.clone_threshold); DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "clone"); + CHECK_ALL(firm_opt.check_all); + } + if (firm_opt.tail_rec) { + timer_push(TV_TAIL_REC); + opt_tail_recursion(); + timer_pop(); + + DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "tail_rec"); + CHECK_ALL(firm_opt.check_all); + } + + if (firm_opt.cond_eval) { + for (i = 0; i < get_irp_n_irgs(); i++) { + irg = get_irp_irg(i); + timer_push(TV_COND_EVAL); + opt_cond_eval(irg); + timer_pop(); + DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "cond_eval"); + CHECK_ONE(firm_opt.check_all, irg); + + timer_push(TV_CF_OPT); + optimize_cf(irg); + timer_pop(); + DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "cfopt"); + CHECK_ONE(firm_opt.check_all, irg); + } } if (firm_dump.ir_graph) { @@ -568,8 +593,10 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi DUMP_ALL(firm_dump.ir_graph, "-opt"); /* verify optimized graphs */ - for (i = get_irp_n_irgs() - 1; i >= 0; --i) - irg_verify(get_irp_irg(i), VRFY_ENFORCE_SSA); + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_graph *irg = get_irp_irg(i); + irg_verify(irg, VRFY_ENFORCE_SSA); + } if (firm_dump.statistic & STAT_AFTER_OPT) stat_dump_snapshot(input_filename, "opt"); @@ -712,24 +739,14 @@ static int compute_type_size(ir_type *ty) } /* compute_type_size */ /** - * layout all types of the Firm graph + * layout all non-frame types of the Firm graph */ static void compute_type_sizes(void) { int i; ir_type *tp; - ir_graph *irg; - /* all frame types */ - for (i = get_irp_n_irgs() - 1; i >= 0; --i) { - irg = get_irp_irg(i); - /* do not optimize away variables in debug mode */ - if (firm_opt.debug_mode == DBG_MODE_NONE) - opt_frame_irg(irg); - compute_type_size(get_irg_frame_type(irg)); - } - - /* all other types */ + /* all non-frame other types */ for (i = get_irp_n_types() - 1; i >= 0; --i) { tp = get_irp_type(i); compute_type_size(tp); @@ -745,6 +762,24 @@ static void compute_type_sizes(void) } } /* compute_type_sizes */ +/** + * layout all frame-types of the Firm graph + */ +static void compute_frame_type_sizes(void) +{ + int i; + ir_graph *irg; + + /* all frame types */ + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + irg = get_irp_irg(i); + /* do not optimize away variables in debug mode */ + if (firm_opt.debug_mode == DBG_MODE_NONE) + opt_frame_irg(irg); + compute_type_size(get_irg_frame_type(irg)); + } +} /* compute_frame_type_sizes */ + /** * do Firm lowering * @@ -780,7 +815,6 @@ static void do_firm_lowering(const char *input_filename) } timer_push(TV_DW_LOWER); lower_dw_ops(&init); - DUMP_ALL(firm_dump.ir_graph, "-dw"); timer_pop(); } @@ -810,6 +844,12 @@ static void do_firm_lowering(const char *input_filename) CHECK_ONE(firm_opt.check_all, current_ir_graph); } + /* enable architecture dependent optimizations */ + arch_dep_set_opts((arch_dep_opts_t) + ((firm_opt.muls ? arch_dep_mul_to_shift : arch_dep_none) | + (firm_opt.divs ? arch_dep_div_by_const : arch_dep_none) | + (firm_opt.mods ? arch_dep_mod_by_const : arch_dep_none) )); + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { current_ir_graph = get_irp_irg(i); @@ -832,7 +872,6 @@ static void do_firm_lowering(const char *input_filename) CHECK_ONE(firm_opt.check_all, current_ir_graph); } -// set_opt_global_cse(0); timer_push(TV_LOAD_STORE); optimize_load_store(current_ir_graph); timer_pop(); @@ -914,9 +953,17 @@ void gen_firm_init(void) params.cc_mask = 0; /* no regparam, cdecl */ params.builtin_dbg = NULL; -#ifdef FIRM_BACKEND + #ifdef FIRM_EXT_GRS + /* Activate Graph rewriting if SIMD optimization is turned on */ + /* This has to be done before init_firm() is called! */ + if (firm_ext_grs.simd_opt) + ext_grs_activate(); +#endif + + init_firm(¶ms); + if (firm_be_opt.selection == BE_FIRM_BE) { - const backend_params *be_params = be_init(); + const backend_params *be_params = be_get_backend_param(); firm_opt.lower_ll = (a_byte) be_params->do_dw_lowering; params.arch_op_settings = be_params->arch_op_settings; @@ -926,17 +973,11 @@ void gen_firm_init(void) ad_param = be_params->dep_param; if_conv_info = be_params->if_conv_info; - } -#endif /* FIRM_BACKEND */ -#ifdef FIRM_EXT_GRS - /* Activate Graph rewriting if SIMD optimization is turned on */ - /* This has to be done before init_firm() is called! */ - if (firm_ext_grs.simd_opt) - ext_grs_activate(); -#endif + if (be_params->has_imm_fp_mode) + firm_imm_fp_mode = be_params->imm_fp_mode; + } - init_firm(¶ms); dbg_init(NULL, NULL, dbg_snprint); edges_init_dbg(firm_opt.vrfy_edges); //cbackend_set_debug_retrieve(dbg_retrieve); @@ -944,6 +985,9 @@ void gen_firm_init(void) set_opt_precise_exc_context(firm_opt.precise_exc); set_opt_fragile_ops(firm_opt.fragile_ops); + /* Sel node cannot produce NULL pointers */ + set_opt_sel_based_null_check_elim(1); + /* dynamic dispatch works currently only if whole world scenarios */ set_opt_dyn_meth_dispatch(0); @@ -1042,6 +1086,12 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm /* computes the sizes of all types that are still not computed */ compute_type_sizes(); + /* lower copyb nodes */ + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_graph *irg = get_irp_irg(i); + lower_CopyB(irg, 128, 4); + } + if (firm_dump.statistic & STAT_BEFORE_OPT) { stat_dump_snapshot(input_filename, "noopt"); } @@ -1059,6 +1109,9 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm if (firm_opt.lower) do_firm_lowering(input_filename); + /* computes the sizes of all frame types */ + compute_frame_type_sizes(); + /* set the phase to low */ for (i = get_irp_n_irgs() - 1; i >= 0; --i) set_irg_phase_low(get_irp_irg(i)); @@ -1080,13 +1133,6 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm ext_grs_simd_opt(); #endif - /* enable architecture dependent optimizations */ - arch_dep_set_opts((arch_dep_opts_t) - ((firm_opt.muls ? arch_dep_mul_to_shift : arch_dep_none) | - (firm_opt.divs ? arch_dep_div_by_const : arch_dep_none) | - (firm_opt.mods ? arch_dep_mod_by_const : arch_dep_none) )); - - if (firm_dump.statistic & STAT_FINAL_IR) stat_dump_snapshot(input_filename, "final-ir"); @@ -1107,9 +1153,7 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm * Do very early initializations */ void firm_early_init(void) { -#ifdef FIRM_BACKEND /* arg: need this here for command line options */ be_opt_register(); -#endif firm_init_options(NULL, 0, NULL); } /* firm_early_init */