make block numbers accross functions more deterministic
[libfirm] / ir / opt / convopt.c
index 27518bb..fac7e32 100644 (file)
@@ -53,7 +53,6 @@
 #include "irpass_t.h"
 #include "tv.h"
 #include "vrp.h"
-#include "opt_manage.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
@@ -110,7 +109,6 @@ static int get_conv_costs(const ir_node *node, ir_mode *dest_mode)
                return 0;
 
        if (is_Const(node)) {
-               /* TODO tarval module is incomplete and can't convert floats to ints */
                return conv_const_tv(node, dest_mode) == tarval_bad ? 1 : 0;
        }
 
@@ -156,10 +154,14 @@ static int get_conv_costs(const ir_node *node, ir_mode *dest_mode)
                ir_node *pred      = get_Conv_op(node);
                ir_mode *pred_mode = get_irn_mode(pred);
 
-               if (!values_in_mode(dest_mode, pred_mode)) {
+               if (smaller_mode(pred_mode, dest_mode)) {
+                       return get_conv_costs(get_Conv_op(node), dest_mode) - 1;
+               }
+               if (may_leave_out_middle_conv(pred_mode, mode, dest_mode)) {
+                       return 0;
+               } else {
                        return 1;
                }
-               return get_conv_costs(get_Conv_op(node), dest_mode) - 1;
        }
 
        if (!is_optimizable_node(node, dest_mode)) {
@@ -198,7 +200,6 @@ static ir_node *conv_transform(ir_node *node, ir_mode *dest_mode)
                return node;
 
        if (is_Const(node)) {
-               /* TODO tarval module is incomplete and can't convert floats to ints */
                ir_tarval *tv = conv_const_tv(node, dest_mode);
                if (tv == tarval_bad) {
                        return place_conv(node, dest_mode);
@@ -225,10 +226,10 @@ static ir_node *conv_transform(ir_node *node, ir_mode *dest_mode)
                ir_node *pred      = get_Conv_op(node);
                ir_mode *pred_mode = get_irn_mode(pred);
 
-               if (!values_in_mode(dest_mode, pred_mode)) {
-                       return place_conv(node, dest_mode);
+               if (smaller_mode(pred_mode, dest_mode)) {
+                       return conv_transform(get_Conv_op(node), dest_mode);
                }
-               return conv_transform(get_Conv_op(node), dest_mode);
+               return place_conv(node, dest_mode);
        }
 
        if (!is_optimizable_node(node, dest_mode)) {
@@ -303,31 +304,25 @@ static void conv_opt_walker(ir_node *node, void *data)
        }
 }
 
-static ir_graph_properties_t do_deconv(ir_graph *irg)
+void conv_opt(ir_graph *irg)
 {
+       bool global_changed = false;
        bool changed;
        FIRM_DBG_REGISTER(dbg, "firm.opt.conv");
 
+       assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES);
+
        DB((dbg, LEVEL_1, "===> Performing conversion optimization on %+F\n", irg));
 
        do {
                changed = false;
                irg_walk_graph(irg, NULL, conv_opt_walker, &changed);
                local_optimize_graph(irg);
+               global_changed |= changed;
        } while (changed);
 
-       return 0;
-}
-
-static optdesc_t opt_deconv = {
-       "deconv",
-       IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES,
-       do_deconv,
-};
-
-void conv_opt(ir_graph *irg)
-{
-       perform_irg_optimization(irg, &opt_deconv);
+       confirm_irg_properties(irg,
+               global_changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL);
 }
 
 /* Creates an ir_graph pass for conv_opt. */