- fixed warnings
[libfirm] / ir / opt / condeval.c
index 65682ab..093a522 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -144,7 +144,7 @@ static void construct_ssa(ir_node * const *blocks, ir_node * const *vals, int n_
                ir_node *value = vals[i];
                ir_node *value_block = blocks[i];
 
-               assert(get_irn_mode(value) == mode);
+               assert(get_irn_mode(value) == mode || is_Bad(value));
 
                set_irn_link(value_block, value);
                mark_irn_visited(value_block);
@@ -256,15 +256,22 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block,
        foreach_out_edge(block, edge) {
                ir_node *node = get_edge_src_irn(edge);
                ir_node *copy;
-               ir_mode *mode = get_irn_mode(node);
+               ir_mode *mode;
+
+               if (is_Block(node)) {
+                       /* Block->Block edge, should be the MacroBlock edge */
+                       assert(get_Block_MacroBlock(node) == block && "Block->Block edge found");
+                       continue;
+               }
 
                /* ignore control flow */
+               mode = get_irn_mode(node);
                if (mode == mode_X || is_Cond(node))
                        continue;
 #ifdef AVOID_PHIB
                /* we may not copy mode_b nodes, because this could produce phi with
                 * mode_bs which can't be handled in all backends. Instead we duplicate
-                * the node and move it to it's users */
+                * the node and move it to its users */
                if (mode == mode_b) {
                        const ir_edge_t *edge, *next;
                        ir_node *pred;
@@ -310,8 +317,15 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block,
                ir_node *vals[2];
                ir_node *blocks[2];
                ir_node *node = get_edge_src_irn(edge);
-               ir_mode *mode = get_irn_mode(node);
+               ir_mode *mode;
+
+               if (is_Block(node)) {
+                       /* Block->Block edge, should be the MacroBlock edge */
+                       assert(get_Block_MacroBlock(node) == block && "Block->Block edge found");
+                       continue;
+               }
 
+               mode = get_irn_mode(node);
                if (mode == mode_X || is_Cond(node))
                        continue;
 #ifdef AVOID_PHIB
@@ -330,7 +344,7 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block,
 }
 
 /**
- * returns wether the cmp evaluates to true or false, or can't be evaluated!
+ * returns whether the cmp evaluates to true or false, or can't be evaluated!
  * 1: true, 0: false, -1: can't evaluate
  */
 static int eval_cmp(pn_Cmp pnc, tarval *tv1, tarval *tv2) {
@@ -345,17 +359,39 @@ static int eval_cmp(pn_Cmp pnc, tarval *tv1, tarval *tv2) {
        return 1;
 }
 
+/**
+ * Check for Const or constlike Confirm.
+ */
+static int is_Const_or_Confirm(const ir_node *node) {
+       if (is_Confirm(node)) {
+               if (get_Confirm_cmp(node) == pn_Cmp_Eq)
+                       node = get_Confirm_bound(node);
+       }
+       return is_Const(node);
+}
+
+/**
+ * get the tarval of a COnst or constlike Confirm
+ */
+static tarval *get_Const_or_Confirm_tarval(const ir_node *node) {
+       if (is_Confirm(node)) {
+               if (get_Confirm_cmp(node) == pn_Cmp_Eq)
+                       node = get_Confirm_bound(node);
+       }
+       return get_Const_tarval(node);
+}
+
 static ir_node *find_const(condeval_env_t *env, ir_node *jump, ir_node *value)
 {
        ir_node *block = get_nodes_block(jump);
 
-       if(irn_visited(value))
+       if (irn_visited(value))
                return NULL;
        mark_irn_visited(value);
 
-       if(is_Const(value)) {
+       if(is_Const_or_Confirm(value)) {
                tarval *tv_const = get_Const_tarval(env->cnst);
-               tarval *tv       = get_Const_tarval(value);
+               tarval *tv       = get_Const_or_Confirm_tarval(value);
 
                if(eval_cmp(env->pnc, tv, tv_const) <= 0) {
                        return NULL;
@@ -422,8 +458,8 @@ static ir_node *find_candidate(condeval_env_t *env, ir_node *jump,
        }
        mark_irn_visited(value);
 
-       if(is_Const(value)) {
-               tarval *tv = get_Const_tarval(value);
+       if(is_Const_or_Confirm(value)) {
+               tarval *tv = get_Const_or_Confirm_tarval(value);
 
                if(tv != env->tv)
                        return NULL;
@@ -560,7 +596,7 @@ static void cond_eval(ir_node* block, void* data)
        if (get_irn_mode(selector) != mode_b)
                return;
 
-       /* handle cases that can be immediately evalutated */
+       /* handle cases that can be immediately evaluated */
        selector_evaluated = -1;
        if(is_Proj(selector)) {
                ir_node *cmp = get_Proj_pred(selector);
@@ -577,8 +613,8 @@ static void cond_eval(ir_node* block, void* data)
                                        return;
                        }
                }
-       } else if(is_Const(selector)) {
-               tarval *tv = get_Const_tarval(selector);
+       } else if(is_Const_or_Confirm(selector)) {
+               tarval *tv = get_Const_or_Confirm_tarval(selector);
                if(tv == get_tarval_b_true()) {
                        selector_evaluated = 1;
                } else {
@@ -651,7 +687,7 @@ void opt_cond_eval(ir_graph* irg)
 
        edges_assure(irg);
        set_using_irn_link(irg);
-       set_using_visited(irg);
+       set_using_irn_visited(irg);
 
        changed = 0;
        do {
@@ -660,14 +696,19 @@ void opt_cond_eval(ir_graph* irg)
                changed |= rerun;
        } while (rerun);
 
+       clear_using_irn_visited(irg);
+       clear_using_irn_link(irg);
+
        if (changed) {
                /* control flow changed, some blocks may become dead */
                set_irg_outs_inconsistent(irg);
                set_irg_doms_inconsistent(irg);
                set_irg_extblk_inconsistent(irg);
                set_irg_loopinfo_inconsistent(irg);
+
+               /* Dead code might be created. Optimize it away as it is dangerous
+                * to call optimize_df() an dead code. */
+               optimize_cf(irg);
        }
 
-       clear_using_visited(irg);
-       clear_using_irn_link(irg);
 }