Ignore some VC 'security' warnings
[cparser] / driver / firm_opt.c
index 8d3d3fa..fe82a42 100644 (file)
@@ -9,10 +9,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <libfirm/firm.h>
-
-#ifdef FIRM_BACKEND
 #include <libfirm/be.h>
-#endif /* FIRM_BACKEND */
 
 
 #include "firm_opt.h"
@@ -112,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];
 
@@ -310,27 +309,23 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
 
   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);
-
-    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.combo) {
+    for (i = 0; i < get_irp_n_irgs(); i++) {
+      timer_push(TV_COMBO);
+      irg = get_irp_irg(i);
+      combo(irg);
+      timer_pop();
+      DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "combo");
+      CHECK_ONE(firm_opt.check_all, irg);
+    }
+  }
+
   /* first step: kill dead code */
   for (i = 0; i < get_irp_n_irgs(); i++) {
     irg = current_ir_graph = get_irp_irg(i);
@@ -343,6 +338,31 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
     timer_pop();
   }
 
+  if (firm_opt.remove_unused) {
+    ir_entity **keep_methods;
+    int         arr_len;
+
+    timer_push(TV_CGANA);
+    /* 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);
+    timer_pop();
+  }
+
+  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.func_calls) {
     timer_push(TV_REAL_FUNC_CALL);
       optimize_funccalls(firm_const_exists, NULL);
@@ -388,12 +408,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.gcse) {
+      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);
@@ -402,25 +436,11 @@ 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);
     }
 
@@ -436,28 +456,13 @@ 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);
-      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);
 
@@ -477,6 +482,32 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
       CHECK_ONE(firm_opt.check_all, irg);
     }
 
+    lower_Switch(irg, 128);
+    DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "lower_switch");
+
+    /* should we really remove the Confirm here? */
+    if (firm_opt.confirm) {
+      timer_push(TV_CONFIRM_CREATE);
+      remove_confirms(irg);
+      timer_pop();
+    }
+
+    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.gcse) {
+      timer_push(TV_CODE_PLACE);
+        optimize_graph_df(irg);
+        place_code(irg);
+      timer_pop();
+      DUMP_ONE_C(firm_dump.ir_graph && firm_dump.all_phases, irg, "place");
+      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");
@@ -543,13 +574,32 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
     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();
+
+  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);
+    }
+  }
+
+  /* final run of local optimizations */
+  for (i = 0; i < get_irp_n_irgs(); i++) {
+    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, "local_opt");
+    CHECK_ONE(firm_opt.check_all, irg);
 
-    DUMP_ALL_C(firm_dump.ir_graph && firm_dump.all_phases, "tail_rec");
-    CHECK_ALL(firm_opt.check_all);
+    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) {
@@ -562,6 +612,7 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
     ir_entity **keep_methods;
     int arr_len;
 
+    timer_push(TV_CGANA);
     /* Analysis that finds the free methods,
        i.e. methods that are dereferenced.
        Optimizes polymorphic calls :-). */
@@ -571,6 +622,7 @@ static void do_firm_optimizations(const char *input_filename, int firm_const_exi
     gc_irgs(arr_len, keep_methods);
 
     free(keep_methods);
+    timer_pop();
   }
 
 
@@ -670,6 +722,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);
@@ -828,20 +881,26 @@ 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);
 
-      if (firm_opt.code_place)
+      if (firm_opt.gcse)
         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)
+      if (! firm_opt.gcse)
         CHECK_ONE(firm_opt.check_all, current_ir_graph);
 
-      if (firm_opt.code_place) {
+      if (firm_opt.gcse) {
         timer_push(TV_CODE_PLACE);
           place_code(current_ir_graph);
           set_opt_global_cse(0);
@@ -911,7 +970,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 */
@@ -931,9 +989,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(&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;
@@ -943,17 +1009,24 @@ 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;
+  }
+  /* OS option must be set to the backend */
+  switch (firm_opt.os_support) {
+  case OS_SUPPORT_MINGW:
+    firm_be_option("ia32-gasmode=mingw");
+    break;
+  case OS_SUPPORT_MACHO:
+    firm_be_option("ia32-gasmode=macho");
+    break;
+  case OS_SUPPORT_LINUX:
+  default:
+    firm_be_option("ia32-gasmode=linux");
+    break;
+  }
 
-  init_firm(&params);
   dbg_init(NULL, NULL, dbg_snprint);
   edges_init_dbg(firm_opt.vrfy_edges);
   //cbackend_set_debug_retrieve(dbg_retrieve);
@@ -979,19 +1052,16 @@ 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);
@@ -1056,6 +1126,12 @@ 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();
 
@@ -1109,13 +1185,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");
 
@@ -1136,9 +1205,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 */