reorder for loops
[libfirm] / ir / ana / irconsconfirm.c
index 0a9f250..3830849 100644 (file)
@@ -23,6 +23,8 @@
 #include "irgmod.h"
 #include "iropt_dbg.h"
 #include "iredges_t.h"
+#include "irgwalk.h"
+#include "irprintf.h"
 
 /**
  * Walker environment.
@@ -38,7 +40,7 @@ typedef struct _env_t {
  *
  * @param block   the block which is entered by the branch
  * @param irn     the node expressing the switch value
- * @param pnc     the branch label
+ * @param nr      the branch label
  * @param env     statistical environment
  *
  * Branch labels are a simple case. We can replace the value
@@ -50,6 +52,9 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env)
   const ir_edge_t *edge, *next;
   ir_node *c = NULL;
 
+  if (is_Bad(irn))
+    return;
+
   for (edge = get_irn_out_edge_first(irn); edge; edge = next) {
     ir_node *succ = get_edge_src_irn(edge);
     ir_node *blk = get_nodes_block(succ);
@@ -66,14 +71,15 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env)
 
       if (! c) {
         ir_mode *mode = get_irn_mode(irn);
-        type *tp      = get_irn_type(irn);
+        ir_type *tp   = get_irn_type(irn);
         tarval *tv    = new_tarval_from_long(nr, mode);
         c = new_r_Const_type(current_ir_graph, block, mode, tv, tp);
       }
 
       pos = get_edge_src_pos(edge);
       set_irn_n(succ, pos, c);
-      DBG_OPT_CONFIRM(irn, c);
+      DBG_OPT_CONFIRM_C(irn, c);
+//      ir_printf("1 Replacing input %d of node %n with %n\n", pos, succ, c);
 
       env->num_consts += 1;
     }
@@ -92,14 +98,17 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
 {
   ir_node *left  = get_Cmp_left(cmp);
   ir_node *right = get_Cmp_right(cmp);
+       ir_op *op;
   const ir_edge_t *edge, *next;
 
-  /* remove unordered if it's an integer compare */
-  if (mode_is_int(get_irn_mode(left)))
-    pnc &= ~pn_Cmp_Uo;
+  /* Beware of Bads */
+  if (is_Bad(left) ||is_Bad(right))
+    return;
+
+  op = get_irn_op(left);
 
-  /* try to place the constant on the right side */
-  if (get_irn_op(left) == op_Const) {
+  /* try to place the constant on the right side for a Confirm */
+  if (op == op_Const || op == op_SymConst) {
     ir_node *t = left;
 
     left  = right;
@@ -110,7 +119,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
 
   /*
    * First case: both values are identical.
-   * replace the left one by the right one.
+   * replace the right one by the left one.
    */
   if (pnc == pn_Cmp_Eq) {
     int pos;
@@ -122,7 +131,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
       next = get_irn_out_edge_next(left, edge);
       if (block_dominates(block, blk)) {
         /*
-         * Ok, we found a user of left that is placed
+         * Ok, we found a user of right that is placed
          * in a block dominated by the branch block.
          * We can replace the input with right.
          */
@@ -130,6 +139,8 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
         set_irn_n(succ, pos, right);
         DBG_OPT_CONFIRM(left, right);
 
+//        ir_printf("2 Replacing input %d of node %n with %n\n", pos, succ, right);
+
         env->num_eq += 1;
       }
     }
@@ -145,17 +156,16 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
       next = get_irn_out_edge_next(left, edge);
       if (block_dominates(block, blk)) {
         /*
-         * Ok, we found a user of left that is placed
+         * Ok, we found a user of right that is placed
          * in a block dominated by the branch block.
          * We can replace the input with a Confirm(left, pnc, right).
          */
-
         if (! c)
           c = new_r_Confirm(current_ir_graph, block, left, right, pnc);
 
         pos = get_edge_src_pos(edge);
         set_irn_n(succ, pos, c);
-        DBG_OPT_CONFIRM(left, c);
+//        ir_printf("3 Replacing input %d of node %n with %n\n", pos, succ, c);
 
         env->num_confirms += 1;
       }
@@ -205,8 +215,10 @@ static void insert_Confirm(ir_node *block, void *env)
 
     if (get_Proj_proj(proj) != pn_Cond_true) {
       /* it's the false branch */
-      pnc = get_negated_pnc(pnc);
+      pnc = get_negated_pnc(pnc, mode);
     }
+//    ir_printf("At %n using %n Confirm %=\n", block, cmp, pnc);
+
     handle_if(block, cmp, pnc, env);
   }
   else if (mode_is_int(mode)) {
@@ -233,6 +245,9 @@ void construct_confirms(ir_graph *irg)
     compute_doms(irg);
   }
 
+  assert(get_irg_pinned(irg) == op_pin_state_pinned &&
+    "Nodes must be placed to insert Confirms");
+
   if (! edges_active) {
     /* We need edges */
     edges_activate(irg);
@@ -253,9 +268,11 @@ void construct_confirms(ir_graph *irg)
     set_irg_loopinfo_inconsistent(irg);
   }
 
-  printf("No Confirms inserted : %u\n", env.num_confirms);
-  printf("No Const replacements: %u\n", env.num_consts);
-  printf("No node equalities   : %u\n", env.num_eq);
+#if 0
+  printf("# Confirms inserted : %u\n", env.num_confirms);
+  printf("# Const replacements: %u\n", env.num_consts);
+  printf("# node equalities   : %u\n", env.num_eq);
+#endif
 
   /* deactivate edges if they where off */
   if (! edges_active)
@@ -263,11 +280,20 @@ void construct_confirms(ir_graph *irg)
 }
 
 /**
- * Post-walker: Remove COnfirm nodes
+ * Post-walker: Remove Confirm nodes
  */
 static void rem_Confirm(ir_node *n, void *env) {
   if (get_irn_op(n) == op_Confirm) {
-    exchange(n, get_Confirm_value(n));
+    ir_node *value = get_Confirm_value(n);
+    if (value != n)
+      exchange(n, value);
+    else {
+      /*
+       * Strange: a Confirm is it's own bound. This can happen
+       * in dead blocks when Phi nodes are already removed.
+       */
+      exchange(n, new_Bad());
+    }
   }
 }