More work for C++ mode:
[cparser] / driver / firm_opt.c
index 4d4e90c..7b0e3a6 100644 (file)
@@ -6,19 +6,24 @@
  *
  * $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
+#endif
 
 #if defined(_DEBUG) || defined(FIRM_DEBUG)
 #define DBG(x)  dbg_printf x
@@ -108,6 +113,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];
 
@@ -239,12 +246,14 @@ static void dump_graph_count(ir_graph *const irg, const char *const suffix)
   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)
 {
@@ -276,16 +285,193 @@ 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. */
@@ -295,6 +481,7 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
   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)
@@ -304,248 +491,102 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
 
   set_irp_memory_disambiguator_options(aa_opt);
 
-  timer_start(TV_ALL_OPT);
-
-  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);
+  /* 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);
 
-    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);
-  }
-
-  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);
-  }
+  timer_start(TV_ALL_OPT);
 
-  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);
-  }
+  do_irp_opt("rts");
 
-  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);
+  /* first step: kill dead code */
+  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");
+    }
   }
 
-  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);
-
-    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);
+    ir_graph *irg = get_irp_irg(i);
 
-    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);
-    }
-
-    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.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);
-
-    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);
+      do_irg_opt(irg, "controlflow");
+      do_irg_opt(irg, "confirm");
+      do_irg_opt(irg, "local");
     }
 
-    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);
+      do_irg_opt(irg, "ifconv");
+      do_irg_opt(irg, "local");
+      do_irg_opt(irg, "controlflow");
     }
 
-    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);
-    }
-
-    timer_push(TV_OSR);
-      opt_osr(current_ir_graph, osr_flag_default /*| 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.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);
+  do_irp_opt("inline");
+  do_irp_opt("clone");
+
+  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) {
@@ -554,27 +595,14 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
       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)
-    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");
@@ -664,6 +692,7 @@ static int compute_type_size(ir_type *ty)
     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);
@@ -717,24 +746,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);
@@ -750,6 +769,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
  *
@@ -759,21 +796,14 @@ static void do_firm_lowering(const char *input_filename)
 {
   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
     };
@@ -785,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();
   }
 
@@ -806,72 +835,34 @@ static void do_firm_lowering(const char *input_filename)
     /* 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);
 
-//      set_opt_global_cse(0);
-      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);
 
@@ -899,7 +890,6 @@ static void do_firm_lowering(const char *input_filename)
 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 */
@@ -919,9 +909,10 @@ void gen_firm_init(void)
   params.cc_mask               = 0; /* no regparam, cdecl */
   params.builtin_dbg           = NULL;
 
-#ifdef FIRM_BACKEND
+  init_firm(&params);
+
   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;
@@ -931,24 +922,20 @@ 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(&params);
   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);
 
+  /* 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);
 
@@ -964,28 +951,19 @@ void gen_firm_init(void)
   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 */
 
 /**
@@ -995,12 +973,14 @@ void gen_firm_init(void)
  * @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);
@@ -1041,18 +1021,30 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm
   /* 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();
 
   /* 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");
   }
 
   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);
@@ -1064,34 +1056,13 @@ 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));
 
-
-#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");
 
@@ -1101,20 +1072,14 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm
 
   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 */
+}