becopyheur4: Clean up co_mst_irn_init().
[libfirm] / ir / opt / boolopt.c
index fa2d2b7..2632da6 100644 (file)
@@ -1,27 +1,12 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
  * @file
  * @brief   boolean condition/control flow optimizations
  * @author  Matthias Braun, Christoph Mallon, Michael Beck
- * @version $Id: cfopt.c 22579 2008-10-07 14:54:04Z beck $
  */
 #include "config.h"
 
@@ -56,7 +41,7 @@ typedef struct {
        int changed;  /**< Set if the graph was changed. */
 } bool_opt_env_t;
 
-DEBUG_ONLY(static firm_dbg_module_t *dbg);
+DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
 /**
  * Check if tho given nodes, l and r, represent two compares with
@@ -64,62 +49,61 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg);
  */
 static bool find_cond_pair(ir_node *const l, ir_node *const r, cond_pair *const res)
 {
-       if (!is_Cmp(l) || !is_Cmp(r))
-               return false;
-
-       ir_node    *const lol   = get_Cmp_left(l);
-       ir_node    *const lor   = get_Cmp_right(l);
-       ir_node    *const rol   = get_Cmp_left(r);
-       ir_node    *const ror   = get_Cmp_right(r);
-       ir_relation const pnc_l = get_Cmp_relation(l);
-       ir_relation const pnc_r = get_Cmp_relation(r);
-
-       if (is_Const(lor) && is_Const_null(lor) &&
-               is_Const(ror) && is_Const_null(ror) &&
-               pnc_l == pnc_r &&
-               (pnc_l == ir_relation_less_greater || pnc_l == ir_relation_equal)) {
-               /* l == (lol !=|== NULL) && r == (rol !=|== NULL) */
-               res->cmp_lo  = l;
-               res->cmp_hi  = r;
-               res->rel_lo  = pnc_l;
-               res->rel_hi  = pnc_l;
-               res->tv_lo   = get_Const_tarval(lor);
-               res->tv_hi   = get_Const_tarval(ror);
-               res->lo_mode = get_irn_mode(lor);
-
-               return true;
-       }
-
-       if (lol == rol && lor != ror && is_Const(lor) && is_Const(ror)) {
-               /* l == (x CMP c_l), r == (x cmp c_r) */
-               ir_tarval  *const tv_l  = get_Const_tarval(lor);
-               ir_tarval  *const tv_r  = get_Const_tarval(ror);
-               ir_relation const rel   = tarval_cmp(tv_l, tv_r);
-
-               res->lo_mode = get_irn_mode(lol);
-
-               if (rel == ir_relation_less) {
-                       /* c_l < c_r */
+       if (is_Cmp(l) && is_Cmp(r)) {
+               ir_node    *const lol   = get_Cmp_left(l);
+               ir_node    *const lor   = get_Cmp_right(l);
+               ir_node    *const rol   = get_Cmp_left(r);
+               ir_node    *const ror   = get_Cmp_right(r);
+               ir_relation const pnc_l = get_Cmp_relation(l);
+               ir_relation const pnc_r = get_Cmp_relation(r);
+
+               if (is_Const(lor) && is_Const_null(lor) &&
+                       is_Const(ror) && is_Const_null(ror) &&
+                       pnc_l == pnc_r &&
+                       (pnc_l == ir_relation_less_greater || pnc_l == ir_relation_equal)) {
+                       /* l == (lol !=|== NULL) && r == (rol !=|== NULL) */
                        res->cmp_lo  = l;
                        res->cmp_hi  = r;
                        res->rel_lo  = pnc_l;
-                       res->rel_hi  = pnc_r;
-                       res->tv_lo   = tv_l;
-                       res->tv_hi   = tv_r;
-               } else if (rel == ir_relation_greater) {
-                       /* c_l > c_r */
-                       res->cmp_lo  = r;
-                       res->cmp_hi  = l;
-                       res->rel_lo  = pnc_r;
                        res->rel_hi  = pnc_l;
-                       res->tv_lo   = tv_r;
-                       res->tv_hi   = tv_l;
-               } else {
-                       /* The constants shall be unequal but comparable.
-                        * Local optimizations handle the equal case. */
-                       return false;
+                       res->tv_lo   = get_Const_tarval(lor);
+                       res->tv_hi   = get_Const_tarval(ror);
+                       res->lo_mode = get_irn_mode(lor);
+
+                       return true;
+               }
+
+               if (lol == rol && lor != ror && is_Const(lor) && is_Const(ror)) {
+                       /* l == (x CMP c_l), r == (x cmp c_r) */
+                       ir_tarval  *const tv_l  = get_Const_tarval(lor);
+                       ir_tarval  *const tv_r  = get_Const_tarval(ror);
+                       ir_relation const rel   = tarval_cmp(tv_l, tv_r);
+
+                       res->lo_mode = get_irn_mode(lol);
+
+                       if (rel == ir_relation_less) {
+                               /* c_l < c_r */
+                               res->cmp_lo  = l;
+                               res->cmp_hi  = r;
+                               res->rel_lo  = pnc_l;
+                               res->rel_hi  = pnc_r;
+                               res->tv_lo   = tv_l;
+                               res->tv_hi   = tv_r;
+                       } else if (rel == ir_relation_greater) {
+                               /* c_l > c_r */
+                               res->cmp_lo  = r;
+                               res->cmp_hi  = l;
+                               res->rel_lo  = pnc_r;
+                               res->rel_hi  = pnc_l;
+                               res->tv_lo   = tv_r;
+                               res->tv_hi   = tv_l;
+                       } else {
+                               /* The constants shall be unequal but comparable.
+                                * Local optimizations handle the equal case. */
+                               return false;
+                       }
+                       return true;
                }
-               return true;
        }
        return false;
 }
@@ -585,8 +569,6 @@ restart:
                ir_node      *lower_block;
                ir_node      *lower_cf;
                ir_node      *cond;
-               ir_node      *cond_selector;
-               ir_node      *lower_pred;
 
                lower_cf = get_Block_cfgpred(block, low_idx);
                lower_cf = skip_empty_blocks(lower_cf);
@@ -605,17 +587,11 @@ restart:
                if (get_Block_mark(lower_block))
                        continue;
 
-               cond_selector = get_Cond_selector(cond);
-               if (get_irn_mode(cond_selector) != mode_b)
-                       continue;
-
-               lower_pred = get_Block_cfgpred_block(lower_block, 0);
-
+               ir_node *const cond_selector = get_Cond_selector(cond);
+               ir_node *const lower_pred    = get_Block_cfgpred_block(lower_block, 0);
                for (up_idx = 0; up_idx < n_cfgpreds; ++up_idx) {
                        ir_node   *upper_block;
                        ir_node   *upper_cf;
-                       ir_node   *upper_cond;
-                       ir_node   *upper_cond_selector;
                        ir_node   *replacement;
                        cond_pair  cpair;
 
@@ -629,13 +605,6 @@ restart:
                        if (!block_dominates(upper_block, block))
                                continue;
 
-                       assert(is_Proj(upper_cf));
-                       upper_cond = get_Proj_pred(upper_cf);
-                       assert(is_Cond(upper_cond));
-                       upper_cond_selector = get_Cond_selector(upper_cond);
-                       if (get_irn_mode(upper_cond_selector) != mode_b)
-                               continue;
-
                        /* we have found the structure */
                        /* check Phis: There must be NO Phi in block that
                           depends on the existence of low block */
@@ -643,11 +612,13 @@ restart:
                                continue;
 
                        /* all fine, try it */
+                       ir_node *const upper_cond          = get_Proj_pred(upper_cf);
+                       ir_node *const upper_cond_selector = get_Cond_selector(upper_cond);
                        if (!find_cond_pair(cond_selector, upper_cond_selector, &cpair))
                                continue;
 
                        /* normalize pncs: we need the true case to jump into the
-                        * common block (ie. conjunctive normal form) */
+                        * common block (i.e. conjunctive normal form) */
                        if (get_Proj_proj(lower_cf) == pn_Cond_false) {
                                if (cpair.cmp_lo == cond_selector) {
                                        ir_node  *cmp   = cpair.cmp_lo;
@@ -724,28 +695,19 @@ void opt_bool(ir_graph *const irg)
        /* register a debug mask */
        FIRM_DBG_REGISTER(dbg, "firm.opt.bool");
 
-       /* works better with one return block only */
-       normalize_one_return(irg);
-
        env.changed = 0;
 
        /* optimize simple Andb and Orb cases */
        irg_walk_graph(irg, NULL, bool_walk, &env);
 
-       ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST);
-
        /* now more complicated cases: find control flow And/Or and optimize. */
+       ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST);
        irg_walk_graph(irg, clear_block_infos, collect_phis, NULL);
        irg_block_walk_graph(irg, NULL, find_cf_and_or_walker, &env);
-
-       if (env.changed) {
-               set_irg_outs_inconsistent(irg);
-               set_irg_doms_inconsistent(irg);
-               set_irg_extblk_inconsistent(irg);
-               set_irg_loopinfo_inconsistent(irg);
-       }
-
        ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_PHI_LIST);
+
+       confirm_irg_properties(irg,
+               env.changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL);
 }
 
 /* Creates an ir_graph pass for opt_bool. */