X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fboolopt.c;h=2632da66d52aa6ea33fdc815537480549ecfb04f;hb=34e3b8d50bce639e760da7233524a4db85c80290;hp=fa2d2b7dcf5a2bf24270eef38cab3eca374dc536;hpb=af300963705d97b2f596e8cf2887813c25de6ad8;p=libfirm diff --git a/ir/opt/boolopt.c b/ir/opt/boolopt.c index fa2d2b7dc..2632da66d 100644 --- a/ir/opt/boolopt.c +++ b/ir/opt/boolopt.c @@ -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. */