*
* $Id$
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
#include <libfirm/firm.h>
-
-#ifdef FIRM_BACKEND
#include <libfirm/be.h>
-#endif /* FIRM_BACKEND */
#include "firm_opt.h"
#include "firm_codegen.h"
#include "firm_cmdline.h"
#include "firm_timing.h"
+#include "ast2firm.h"
#ifdef _WIN32
#define snprintf _snprintf
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];
DUMP_ONE(1, irg, name);
}
+#if 0
static void dump_graph_cfg_count(ir_graph *const irg, const char *const suffix)
{
char name[64];
snprintf(name, sizeof(name), "-%02d_%s", irg_dump_no[get_irg_idx(irg)]++, suffix);
DUMP_ONE_CFG(1, irg, name);
}
+#endif
static void dump_all_count(const char *const suffix)
{
} \
} while (0)
+static void remove_unused_functions(void)
+{
+ ir_entity **keep_methods;
+ int arr_len;
+
+ /* Analysis that finds the free methods,
+ i.e. methods that are dereferenced.
+ Optimizes polymorphic calls :-). */
+ cgana(&arr_len, &keep_methods);
+
+ /* Remove methods that are never called. */
+ gc_irgs(arr_len, keep_methods);
+ free(keep_methods);
+}
+
+static int firm_const_exists;
+
+static void do_optimize_funccalls(void)
+{
+ optimize_funccalls(firm_const_exists, NULL);
+}
+
+static void do_gcse(ir_graph *irg)
+{
+ set_opt_global_cse(1);
+ optimize_graph_df(irg);
+ place_code(irg);
+ set_opt_global_cse(0);
+}
+
+static void do_lower_highlevel(ir_graph *irg)
+{
+ lower_highlevel_graph(irg, firm_opt.lower_bitfields);
+}
+
+static void do_if_conv(ir_graph *irg)
+{
+ opt_if_conv(irg, if_conv_info);
+}
+
+static void do_stred(ir_graph *irg)
+{
+ opt_osr(irg, osr_flag_default | osr_flag_keep_reg_pressure | osr_flag_ignore_x86_shift);
+}
+
+static void do_inline(void)
+{
+ inline_functions(firm_opt.inline_maxsize, firm_opt.inline_threshold);
+}
+
+static void do_cloning(void)
+{
+ proc_cloning((float) firm_opt.clone_threshold);
+}
+
+static void do_lower_switch(ir_graph *irg)
+{
+ lower_switch(irg, firm_opt.spare_size);
+}
+
+typedef enum opt_target {
+ OPT_TARGET_IRG,
+ OPT_TARGET_IRP
+} opt_target;
+
+typedef void (*transform_irg_func)(ir_graph *irg);
+typedef void (*transform_irp_func)(void);
+typedef void (*func_ptr_t)(void);
+
+typedef struct {
+ opt_target target;
+ const char *name;
+ func_ptr_t func;
+ bool enabled;
+ bool dump;
+ bool verify;
+ int timer;
+} opt_config_t;
+
+static opt_config_t opts[] = {
+ { OPT_TARGET_IRP, "rts", (func_ptr_t) rts_map, true, true, true, -1 },
+ { OPT_TARGET_IRG, "combo", (func_ptr_t) combo, true, true, true, TV_COMBO },
+ { OPT_TARGET_IRG, "controlflow", (func_ptr_t) optimize_cf, true, true, true, TV_CF_OPT },
+ { OPT_TARGET_IRG, "local", (func_ptr_t) optimize_graph_df, true, true, true, TV_LOCAL_OPT },
+ { OPT_TARGET_IRP, "gc_irgs", (func_ptr_t) remove_unused_functions, true, false, false, TV_CGANA },
+ { OPT_TARGET_IRP, "tailrec", (func_ptr_t) opt_tail_recursion, true, true, true, TV_TAIL_REC },
+ { OPT_TARGET_IRP, "funccalls", (func_ptr_t) do_optimize_funccalls, true, true, true, TV_REAL_FUNC_CALL },
+ { OPT_TARGET_IRP, "lowerconst", (func_ptr_t) lower_const_code, true, false, false, -1 },
+ { OPT_TARGET_IRG, "onereturn", (func_ptr_t) normalize_one_return, true, false, false, -1 },
+ { OPT_TARGET_IRG, "scalar", (func_ptr_t) scalar_replacement_opt, true, true, true, TV_SCALAR_REPLACE },
+ { OPT_TARGET_IRG, "reassoc", (func_ptr_t) optimize_reassociation, true, true, true, TV_REASSOCIATION },
+ { OPT_TARGET_IRG, "gcse", (func_ptr_t) do_gcse, true, true, true, TV_CODE_PLACE },
+ { OPT_TARGET_IRG, "place", (func_ptr_t) place_code, true, true, true, TV_CODE_PLACE },
+ { OPT_TARGET_IRG, "confirm", (func_ptr_t) construct_confirms, true, true, true, TV_CONFIRM_CREATE },
+ { OPT_TARGET_IRG, "ldst", (func_ptr_t) optimize_load_store, true, true, true, TV_LOAD_STORE },
+ { OPT_TARGET_IRG, "sync", (func_ptr_t) opt_sync, true, true, true, -1 },
+ { OPT_TARGET_IRG, "lower", (func_ptr_t) do_lower_highlevel, true, true, true, -1 },
+ { OPT_TARGET_IRG, "deconv", (func_ptr_t) conv_opt, true, true, true, TV_DECONV },
+ { OPT_TARGET_IRG, "condeval", (func_ptr_t) opt_cond_eval, true, true, true, TV_COND_EVAL },
+ { OPT_TARGET_IRG, "remove_confirms", (func_ptr_t) remove_confirms, true, false, false, TV_CONFIRM_CREATE },
+ { OPT_TARGET_IRG, "gvnpre", (func_ptr_t) do_gvn_pre, true, true, true, -1 },
+ { OPT_TARGET_IRG, "ifconv", (func_ptr_t) do_if_conv, true, true, true, TV_IF_CONV },
+ { OPT_TARGET_IRG, "bool", (func_ptr_t) opt_bool, true, true, true, -1 },
+ { OPT_TARGET_IRG, "shape-blocks",(func_ptr_t) shape_blocks, true, true, true, TV_END_MELT },
+ { OPT_TARGET_IRG, "stred", (func_ptr_t) do_stred, true, true, true, TV_OSR },
+ { OPT_TARGET_IRG, "dead", (func_ptr_t) dead_node_elimination, true, false, true, TV_DEAD_NODE },
+ { OPT_TARGET_IRP, "inline", (func_ptr_t) do_inline, true, true, true, -1 },
+ { OPT_TARGET_IRP, "clone", (func_ptr_t) do_cloning, true, true, true, -1 },
+ { OPT_TARGET_IRG, "lower_switch", (func_ptr_t) do_lower_switch, true, true, true, -1 },
+};
+static const int n_opts = sizeof(opts) / sizeof(opts[0]);
+
+static opt_config_t *get_opt(const char *name)
+{
+ int i;
+ for (i = 0; i < n_opts; ++i) {
+ opt_config_t *config = &opts[i];
+ if (strcmp(config->name, name) == 0)
+ return config;
+ }
+
+ assert(0);
+ return NULL;
+}
+
+static void set_opt_enabled(const char *name, bool enabled)
+{
+ opt_config_t *config = get_opt(name);
+ config->enabled = enabled;
+}
+
+static void do_irg_opt(ir_graph *irg, const char *name)
+{
+ transform_irg_func func;
+ ir_graph *old_irg;
+ opt_config_t *config = get_opt(name);
+ assert(config->target == OPT_TARGET_IRG);
+ if (!config->enabled)
+ return;
+
+ if (config->timer != -1)
+ timer_push(config->timer);
+
+ old_irg = current_ir_graph;
+ current_ir_graph = irg;
+
+ func = (transform_irg_func) config->func;
+ func(irg);
+
+ if (config->timer != -1)
+ timer_pop();
+
+ DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, config->name);
+ CHECK_ONE(firm_opt.check_all, irg);
+
+ current_ir_graph = old_irg;
+}
+
+static void do_irp_opt(const char *name)
+{
+ transform_irp_func func;
+ opt_config_t *config = get_opt(name);
+ assert(config->target == OPT_TARGET_IRP);
+ if (!config->enabled)
+ return;
+
+ if (config->timer != -1)
+ timer_push(config->timer);
+
+ func = (transform_irp_func) config->func;
+ func();
+
+ DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, config->name);
+ CHECK_ALL(firm_opt.check_all);
+
+ if (config->timer != -1)
+ timer_pop();
+}
+
/**
* run all the Firm optimizations
*
* @param input_filename the name of the (main) source file
- * @param firm_const_exists non-zero, if the const attribute was used on functions
*/
-static void do_firm_optimizations(const char *input_filename, int firm_const_exists)
+static void do_firm_optimizations(const char *input_filename)
{
int i;
- ir_graph *irg;
unsigned aa_opt;
/* FIXME: cloning might ADD new graphs. */
set_opt_scalar_replacement(firm_opt.scalar_replace);
set_opt_auto_create_sync(firm_opt.auto_sync);
set_opt_alias_analysis(firm_opt.alias_analysis);
+ set_opt_combo(firm_opt.combo);
aa_opt = aa_opt_no_opt;
if (firm_opt.strict_alias)
set_irp_memory_disambiguator_options(aa_opt);
- timer_start(TV_ALL_OPT);
+ /* parameter passing code should set them directly sometime... */
+ set_opt_enabled("rts", firm_opt.freestanding);
+ set_opt_enabled("gc_irgs", firm_opt.remove_unused);
+ set_opt_enabled("tailrec", firm_opt.tail_rec);
+ set_opt_enabled("funccalls", firm_opt.func_calls);
+ set_opt_enabled("gcse", firm_opt.gcse);
+ set_opt_enabled("place", !firm_opt.gcse);
+ set_opt_enabled("confirm", firm_opt.confirm);
+ set_opt_enabled("remove_confirms", firm_opt.confirm);
+ set_opt_enabled("sync", firm_opt.sync);
+ set_opt_enabled("ldst", firm_opt.load_store);
+ set_opt_enabled("deconv", firm_opt.deconv);
+ set_opt_enabled("condeval", firm_opt.cond_eval);
+ set_opt_enabled("gvnpre", firm_opt.gvn_pre);
+ set_opt_enabled("ifconv", firm_opt.if_conversion);
+ set_opt_enabled("bool", firm_opt.bool_opt);
+ set_opt_enabled("shape-blocks", firm_opt.shape_blocks);
+ set_opt_enabled("inline", firm_opt.do_inline);
+ set_opt_enabled("clone", firm_opt.cloning);
+ set_opt_enabled("combo", firm_opt.combo);
- if (firm_opt.remove_unused) {
- ir_entity **keep_methods;
- int arr_len;
-
- /* Analysis that finds the free methods,
- i.e. methods that are dereferenced.
- Optimizes polymorphic calls :-). */
- cgana(&arr_len, &keep_methods);
+ timer_start(TV_ALL_OPT);
- /* Remove methods that are never called. */
- gc_irgs(arr_len, keep_methods);
-
- free(keep_methods);
- }
-
- if (! firm_opt.freestanding) {
- rts_map();
- DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "rts");
- CHECK_ALL(firm_opt.check_all);
- }
+ do_irp_opt("rts");
/* 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();
- }
-
- if (firm_opt.func_calls) {
- timer_push(TV_REAL_FUNC_CALL);
- 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.combo) {
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_graph *irg = get_irp_irg(i);
+ do_irg_opt(irg, "combo");
+ }
+ } else {
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_graph *irg = get_irp_irg(i);
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
+ }
}
- /* do lowering on the const code irg */
- lower_const_code();
+ do_irp_opt("gc_irgs");
+ do_irp_opt("tailrec");
+ do_irp_opt("funccalls");
+ do_irp_opt("lowerconst");
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)
- normalize_one_return(irg);
-#endif
-
-
-#if 0
- if (firm_opt.modes) {
- /* convert all modes into integer if possible */
- arch_mode_conversion(irg, predefs.mode_uint);
- }
-#endif
- timer_push(TV_SCALAR_REPLACE);
- scalar_replacement_opt(irg);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "scalar");
- CHECK_ONE(firm_opt.check_all, irg);
+ ir_graph *irg = get_irp_irg(i);
- 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);
-
- timer_push(TV_REASSOCIATION);
- optimize_reassociation(irg);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "reassoc");
- CHECK_ONE(firm_opt.check_all, irg);
+ do_irg_opt(irg, "scalar");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "reassoc");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "gcse");
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);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "cfopt");
- CHECK_ONE(firm_opt.check_all, irg);
- timer_push(TV_CONFIRM_CREATE);
- construct_confirms(irg);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "confirms");
- CHECK_ONE(firm_opt.check_all, irg);
+ do_irg_opt(irg, "controlflow");
+ do_irg_opt(irg, "confirm");
+ do_irg_opt(irg, "local");
}
- 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);
- 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.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);
- 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);
-
- /* 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);
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "pre");
- CHECK_ONE(firm_opt.check_all, irg);
- irg_verify(irg, VRFY_ENFORCE_SSA);
- }
-
- 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);
-
- if (firm_opt.deconv) {
- timer_push(TV_DECONV);
- conv_opt(irg);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "deconv");
- CHECK_ONE(firm_opt.check_all, irg);
- }
-
- if (firm_opt.cond_eval) {
- 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);
- }
-
- compute_doms(irg);
- compute_postdoms(irg);
- DUMP_ONE_CFG_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "dom");
- CHECK_ONE(firm_opt.check_all, irg);
-
- construct_backedges(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);
+ do_irg_opt(irg, "controlflow");
+ do_irg_opt(irg, "ldst");
+ do_irg_opt(irg, "lower");
+ do_irg_opt(irg, "deconv");
+ do_irg_opt(irg, "condeval");
+ do_irg_opt(irg, "remove_confirms");
+ do_irg_opt(irg, "gvnpre");
+ do_irg_opt(irg, "place");
+ do_irg_opt(irg, "controlflow");
if (firm_opt.if_conversion) {
- timer_push(TV_IF_CONV);
- opt_if_conv(current_ir_graph, if_conv_info);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "if");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
-
- timer_push(TV_LOCAL_OPT);
- optimize_graph_df(current_ir_graph);
- timer_pop();
- timer_push(TV_CF_OPT);
- optimize_cf(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "after_if");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
- }
-
- if (firm_opt.bool_opt) {
- opt_bool(irg);
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "bool");
- CHECK_ONE(firm_opt.check_all, irg);
+ do_irg_opt(irg, "ifconv");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
}
- timer_push(TV_OSR);
- 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);
-
- 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);
-
- edges_deactivate(irg);
- timer_push(TV_DEAD_NODE);
- dead_node_elimination(irg);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "dead");
- CHECK_ONE(firm_opt.check_all, irg);
+ do_irg_opt(irg, "bool");
+ do_irg_opt(irg, "shape-blocks");
+ do_irg_opt(irg, "lower_switch");
+ do_irg_opt(irg, "stred");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "dead");
}
- 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();
+ do_irp_opt("inline");
+ do_irp_opt("clone");
- DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "tail_rec");
- CHECK_ALL(firm_opt.check_all);
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_graph *irg = get_irp_irg(i);
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
+ do_irg_opt(irg, "condeval");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
}
if (firm_dump.ir_graph) {
construct_cf_backedges(get_irp_irg(i));
}
- if (firm_opt.remove_unused) {
- ir_entity **keep_methods;
- int arr_len;
-
- /* Analysis that finds the free methods,
- i.e. methods that are dereferenced.
- Optimizes polymorphic calls :-). */
- cgana(&arr_len, &keep_methods);
-
- /* Remove methods that are never called. */
- gc_irgs(arr_len, keep_methods);
-
- free(keep_methods);
- }
-
+ do_irp_opt("gc_irgs");
DUMP_ALL(firm_dump.ir_graph, "-opt");
-
/* verify optimized graphs */
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
ir_graph *irg = get_irp_irg(i);
save_optimization_state(&state);
set_optimize(1);
set_opt_constant_folding(1);
+ set_opt_algebraic_simplification(1);
for (i = 0; i < dims; ++i) {
ir_node *lower = get_array_lower_bound(ty, i);
{
int i;
- /* do class lowering and vtbl creation */
-// lower_classes_to_struct("vtbl", "m");
-
-#if 0
- timer_push(TV_LOWER);
- lower_highlevel();
- timer_pop();
-#endif
-
if (firm_opt.lower_ll) {
lwrdw_param_t init = {
1,
1,
- mode_Ls, mode_Lu,
- mode_Is, mode_Iu,
+ get_atomic_mode(ATOMIC_TYPE_LONGLONG),
+ get_atomic_mode(ATOMIC_TYPE_ULONGLONG),
+ get_atomic_mode(ATOMIC_TYPE_INT),
+ get_atomic_mode(ATOMIC_TYPE_UINT),
def_create_intrinsic_fkt,
NULL
};
/* run reassociation first on all graphs BEFORE the architecture dependent optimizations
are enabled */
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
- current_ir_graph = get_irp_irg(i);
+ ir_graph *irg = get_irp_irg(i);
+ do_irg_opt(irg, "reassoc");
+ }
- timer_push(TV_REASSOCIATION);
- optimize_reassociation(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "reassoc");
- 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);
-
- if (firm_opt.code_place)
- set_opt_global_cse(1);
-
- timer_push(TV_LOCAL_OPT);
- optimize_graph_df(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "lopt");
- if (! firm_opt.code_place)
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
-
- if (firm_opt.code_place) {
- timer_push(TV_CODE_PLACE);
- place_code(current_ir_graph);
- set_opt_global_cse(0);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "place");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
- }
+ ir_graph *irg = get_irp_irg(i);
- timer_push(TV_LOAD_STORE);
- optimize_load_store(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "ldst");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
+ current_ir_graph = irg;
-
- timer_push(TV_LOCAL_OPT);
- optimize_graph_df(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "lopt");
-
- timer_push(TV_CF_OPT);
- optimize_cf(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "cf");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "gcse");
+ do_irg_opt(irg, "ldst");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
if (firm_opt.if_conversion) {
- timer_push(TV_IF_CONV);
- opt_if_conv(current_ir_graph, if_conv_info);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "if");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
-
- timer_push(TV_LOCAL_OPT);
- optimize_graph_df(current_ir_graph);
- timer_pop();
- timer_push(TV_CF_OPT);
- optimize_cf(current_ir_graph);
- timer_pop();
- DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, current_ir_graph, "after_if");
- CHECK_ONE(firm_opt.check_all, current_ir_graph);
- }
+ do_irg_opt(irg, "ifconv");
+ do_irg_opt(irg, "local");
+ do_irg_opt(irg, "controlflow");
+ }
+
+ do_irg_opt(current_ir_graph, "sync");
}
timer_stop(TV_ALL_OPT);
void gen_firm_init(void)
{
firm_parameter_t params;
- char *dump_filter;
unsigned pattern = 0;
/* the automatic state is only set if inlining is enabled */
params.cc_mask = 0; /* no regparam, cdecl */
params.builtin_dbg = NULL;
-#ifdef FIRM_BACKEND
+ 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;
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);
set_opt_precise_exc_context(firm_opt.precise_exc);
set_opt_fragile_ops(firm_opt.fragile_ops);
if (firm_opt.enabled) {
set_optimize(1);
set_opt_constant_folding(firm_opt.const_folding);
+ set_opt_algebraic_simplification(firm_opt.const_folding);
set_opt_cse(firm_opt.cse);
- set_opt_global_cse (0);
+ set_opt_global_cse(0);
set_opt_unreachable_code(1);
set_opt_control_flow(firm_opt.control_flow);
set_opt_control_flow_weak_simplification(1);
set_opt_control_flow_strong_simplification(1);
- }
- else
+ } else {
set_optimize(0);
-
- dump_filter = getenv("FIRM_DUMP_FILTER");
- if (dump_filter)
- only_dump_method_with_name(new_id_from_str(dump_filter));
+ }
/* do not dump entity ld names */
dump_ld_names(0);
-
-#if 0
- /* init the ycomp debugger extension */
- if (firm_opt.ycomp_dbg)
- firm_init_ycomp_debugger(firm_opt.ycomp_host, firm_opt.ycomp_port);
-#endif
} /* gen_firm_init */
/**
* @param out a file handle for the output, may be NULL
* @param input_filename the name of the (main) source file
* @param c_mode non-zero if "C" was compiled
- * @param firm_const_exists non-zero, if the const attribute was used on functions
+ * @param new_firm_const_exists non-zero, if the const attribute was used on functions
*/
-void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm_const_exists)
+void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int new_firm_const_exists)
{
int i;
+ firm_const_exists = new_firm_const_exists;
+
/* the general for dumping option must be set, or the others will not work */
firm_dump.ir_graph
= (a_byte) (firm_dump.ir_graph | firm_dump.all_phases | firm_dump.extbb);
/* all graphs are finalized, set the irp phase to high */
set_irp_phase_state(phase_high);
+ /* BEWARE: kill unreachable code before doing compound lowering */
+ for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
+ ir_graph *irg = get_irp_irg(i);
+ optimize_cf(irg);
+ }
+
/* lower all compound call return values */
lower_compound_params();
}
if (firm_opt.enabled)
- do_firm_optimizations(input_filename, firm_const_exists);
+ do_firm_optimizations(input_filename);
if (firm_dump.gen_firm_asm) {
timer_push(TV_FIRM_ASM);
for (i = get_irp_n_irgs() - 1; i >= 0; --i)
set_irg_phase_low(get_irp_irg(i));
-
-#ifdef FIRM_EXT_GRS
- /** SIMD Optimization Extensions **/
-
- /* Pattern creation step. No code has to be generated, so
- exit after pattern creation */
- if (firm_ext_grs.create_pattern) {
- ext_grs_create_pattern();
- exit(0);
- }
-
- /* SIMD optimization step. Uses graph patterns to find
- rich instructions and rewrite */
- if (firm_ext_grs.simd_opt)
- 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");
if (firm_dump.statistic & STAT_FINAL)
stat_dump_snapshot(input_filename, "final");
-
-#if 0
- if (firm_opt.ycomp_dbg)
- firm_finish_ycomp_debugger();
-#endif
-} /* gen_firm_finish */
+}
/**
* Do very early initializations
*/
-void firm_early_init(void) {
-#ifdef FIRM_BACKEND
+void firm_early_init(void)
+{
/* arg: need this here for command line options */
be_opt_register();
-#endif
firm_init_options(NULL, 0, NULL);
-} /* firm_early_init */
+}