Split looking for Cmp-Phi-Constant into a separate function.
authorChristoph Mallon <christoph.mallon@gmx.de>
Wed, 4 Jul 2007 21:43:20 +0000 (21:43 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Wed, 4 Jul 2007 21:43:20 +0000 (21:43 +0000)
[r14944]

ir/opt/condeval.c

index c7c6683..65c4d80 100644 (file)
@@ -362,61 +362,23 @@ static ir_node *find_phi_with_const(ir_node *jump, ir_node *value, condeval_env_
 }
 
 
-/**
- * Block-walker: searches for the following construct
- *
- *  Const or Phi with constants
- *           |
- *          Cmp
- *           |
- *         Cond
- *          /
- *       ProjX
- *        /
- *     Block
- */
-static void cond_eval(ir_node* block, void* data)
+static int cond_eval_cmp(ir_node* proj_b, ir_node* block, ir_node* projx, ir_node* cond)
 {
-       condeval_env_t env;
-       int *changed = data;
        ir_graph *irg = current_ir_graph;
-       ir_node *copy_block;
-       ir_node *pred;
-       ir_node *projx;
-       ir_node *cond;
-       ir_node *cmp;
-       ir_node *left;
-       ir_node *right;
-       ir_node *cond_block;
-       pn_Cmp pnc;
-
-       if(get_Block_n_cfgpreds(block) != 1)
-               return;
+       ir_node  *cmp = get_Proj_pred(proj_b);
+       ir_node  *left;
+       ir_node  *right;
+       ir_node  *cond_block;
+       ir_node  *copy_block;
+       pn_Cmp    pnc;
 
-       projx = get_Block_cfgpred(block, 0);
-       if (!is_Proj(projx))
-               return;
-       assert(get_irn_mode(projx) == mode_X);
-
-       cond = get_Proj_pred(projx);
-       if (!is_Cond(cond))
-               return;
-
-       pred = get_Cond_selector(cond);
-       // TODO handle switches
-       if (get_irn_mode(pred) != mode_b)
-               return;
-       if (!is_Proj(pred))
-               return;
-       pnc = get_Proj_proj(pred);
-
-       cmp = get_Proj_pred(pred);
        assert(is_Cmp(cmp));
 
        left  = get_Cmp_left(cmp);
        right = get_Cmp_right(cmp);
        assert(get_irn_mode(left) == get_irn_mode(right));
 
+       pnc = get_Proj_proj(proj_b);
        /* we assume that the cond_block is the true case */
        if (get_Proj_proj(projx) == pn_Cond_false) {
                pnc = get_negated_pnc(pnc, get_irn_mode(left));
@@ -433,7 +395,7 @@ static void cond_eval(ir_node* block, void* data)
        }
 
        if(!is_Const(right))
-               return;
+               return 0;
 
        cond_block = get_nodes_block(cond);
 
@@ -448,13 +410,11 @@ static void cond_eval(ir_node* block, void* data)
                        pred = new_Bad();
                }
                set_Block_cfgpred(block, 0, pred);
-               *changed = 1;
-               set_irg_doms_inconsistent(irg);
-               set_irg_extblk_inconsistent(irg);
-               set_irg_loopinfo_inconsistent(irg);
        } else {
+               condeval_env_t env;
+
                if(get_nodes_block(left) != cond_block)
-                       return;
+                       return 0;
 
                // (recursively) look if a pred of a phi is a constant
                env.true_block = block;
@@ -465,28 +425,72 @@ static void cond_eval(ir_node* block, void* data)
 
                copy_block = find_phi_with_const(projx, left, &env);
 
-               if(copy_block != NULL) {
-                       /* we have to remove the edge towards the pred as the pred now
-                        * jumps into the true_block. We also have to shorten phis
-                        * in our block because of this */
-                       const ir_edge_t *edge, *next;
-                       ir_node* bad = new_Bad();
-                       size_t cnst_pos = env.cnst_pos;
+               if (copy_block == NULL)
+                       return 0;
 
-                       /* shorten phis */
-                       foreach_out_edge_safe(env.cnst_pred, edge, next) {
-                               ir_node *node = get_edge_src_irn(edge);
+               /* we have to remove the edge towards the pred as the pred now
+                * jumps into the true_block. We also have to shorten phis
+                * in our block because of this */
+               const ir_edge_t *edge, *next;
+               ir_node* bad = new_Bad();
+               size_t cnst_pos = env.cnst_pos;
 
-                               if(is_Phi(node))
-                                       set_Phi_pred(node, cnst_pos, bad);
-                       }
+               /* shorten phis */
+               foreach_out_edge_safe(env.cnst_pred, edge, next) {
+                       ir_node *node = get_edge_src_irn(edge);
 
-                       set_Block_cfgpred(env.cnst_pred, cnst_pos, bad);
-
-                       /* the graph is changed now */
-                       *changed = 1;
+                       if(is_Phi(node))
+                               set_Phi_pred(node, cnst_pos, bad);
                }
+
+               set_Block_cfgpred(env.cnst_pred, cnst_pos, bad);
        }
+       /* the graph is changed now */
+       return 1;
+}
+
+
+/**
+ * Block-walker: searches for the following construct
+ *
+ *  Const or Phi with constants
+ *           |
+ *          Cmp
+ *           |
+ *         Cond
+ *          /
+ *       ProjX
+ *        /
+ *     Block
+ */
+static void cond_eval(ir_node* block, void* data)
+{
+       int *changed = data;
+       ir_node *pred;
+       ir_node *projx;
+       ir_node *cond;
+
+       if(get_Block_n_cfgpreds(block) != 1)
+               return;
+
+       projx = get_Block_cfgpred(block, 0);
+       if (!is_Proj(projx))
+               return;
+       assert(get_irn_mode(projx) == mode_X);
+
+       cond = get_Proj_pred(projx);
+       if (!is_Cond(cond))
+               return;
+
+       pred = get_Cond_selector(cond);
+       // TODO handle switches
+       if (get_irn_mode(pred) != mode_b)
+               return;
+       if (!is_Proj(pred))
+               return;
+
+       if (cond_eval_cmp(pred, block, projx, cond))
+               *changed = 1;
 }
 
 void opt_cond_eval(ir_graph* irg)