X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=742e6a8e8b0b2c7e93f76bb62b2c91fc68d65ed1;hb=5f8ddee6b08c8040c0a304a347d65045c1141d52;hp=6b44caa8cd38b8e265ed15307aa3c309b0fcc8ae;hpb=a84a02c67f3b1325633a380a5c66179594499ab6;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 6b44caa8c..742e6a8e8 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -6,11 +6,15 @@ ** iropt --- optimizations intertwined with IR construction. */ -# include "iropt.h" +# include "irnode_t.h" +# include "irgraph_t.h" +# include "iropt_t.h" # include "ircons.h" # include "irgmod.h" # include "irvrfy.h" # include "tv.h" +# include "tune.h" +# include "debinfo.h" /* Make types visible to allow most efficient access */ # include "entity_t.h" @@ -121,12 +125,12 @@ computed_value (ir_node *n) } break; case iro_Eor: if (ta && tb) { res = tarval_eor (ta, tb); } break; - case iro_Not: if(ta) { /*res = tarval_not (ta)*/; } break; + case iro_Not: if (ta) { /*res = tarval_not (ta)*/; } break; case iro_Shl: if (ta && tb) { res = tarval_shl (ta, tb); } break; case iro_Shr: if (ta && tb) { res = tarval_shr (ta, tb); } break; case iro_Shrs: if(ta && tb) { /*res = tarval_shrs (ta, tb)*/; } break; - case iro_Rot: if(ta && tb) { /*res = tarval_rot (ta, tb)*/; } break; - case iro_Conv: if (ta) { res = tarval_convert_to (ta, get_irn_mode (n)); } + case iro_Rot: if (ta && tb) { /*res = tarval_rot (ta, tb)*/; } break; + case iro_Conv: if(ta) { res = tarval_convert_to (ta, get_irn_mode (n)); } break; case iro_Proj: { @@ -253,7 +257,8 @@ equivalent_node (ir_node *n) calls the optimization. */ assert(get_Block_matured(n)); - /* a single entry Region following a single exit Region can be merged */ + /* A single entry Block following a single exit Block can be merged, + if it is not the Start block. */ /* !!! Beware, all Phi-nodes of n must have been optimized away. This is true, as the block is matured before optimize is called. */ if (get_Block_n_cfgpreds(n) == 1 @@ -370,6 +375,8 @@ equivalent_node (ir_node *n) themselves. */ int i, n_preds; + + ir_node *block = NULL; /* to shutup gcc */ ir_node *first_val = NULL; /* to shutup gcc */ ir_node *scnd_val = NULL; /* to shutup gcc */ @@ -408,20 +415,21 @@ equivalent_node (ir_node *n) } } #endif + /* Find first non-self-referencing input */ for (i = 0; i < n_preds; ++i) { first_val = follow_Id(get_Phi_pred(n, i)); /* skip Id's */ set_Phi_pred(n, i, first_val); if ( (first_val != n) /* not self pointer */ - && (get_irn_op(first_val) != op_Bad) /* value not dead */ + && (get_irn_op(first_val) != op_Bad) /* value not dead */ && !(is_Bad (get_Block_cfgpred(block, i))) ) { /* not dead control flow */ break; /* then found first value. */ } } /* A totally Bad or self-referencing Phi (we didn't break the above loop) */ - if (i > n_preds) { n = new_Bad(); break; } + if (i >= n_preds) { n = new_Bad(); break; } scnd_val = NULL; @@ -440,8 +448,8 @@ equivalent_node (ir_node *n) } /* Fold, if no multiple distinct non-self-referencing inputs */ - if (i > n_preds) { - n = a; + if (i >= n_preds) { + n = first_val; } else { /* skip the remaining Ids. */ while (++i < n_preds) { @@ -684,7 +692,7 @@ transform_node (ir_node *n) n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b); } break; - case iro_Not: { /* @@@ not tested as boolean Eor not allowed any more. */ + case iro_Not: { a = get_Not_op(n); if ( (get_irn_mode(n) == mode_b) @@ -867,11 +875,20 @@ gigo (ir_node *node) if ( op != op_Block && op != op_Phi && op != op_Tuple) { for (i = -1; i < get_irn_arity(node); i++) { if (is_Bad(get_irn_n(node, i))) { - node = new_Bad(); - break; + return new_Bad(); } } } +#if 0 + /* If Block has only Bads as predecessors it's garbage. */ + /* If Phi has only Bads as predecessors it's garbage. */ + if (op == op_Block || op == op_Phi) { + for (i = 0; i < get_irn_arity(node); i++) { + if (!is_Bad(get_irn_n(node, i))) break; + } + if (i = get_irn_arity(node)) node = new_Bad(); + } +#endif return node; } @@ -885,6 +902,7 @@ optimize (ir_node *n) tarval *tv; ir_node *old_n = n; + /* Allways optimize Phi nodes: part of the construction. */ if ((!get_optimize()) && (get_irn_op(n) != op_Phi)) return n; /* if not optimize return n */ @@ -959,6 +977,8 @@ optimize_in_place (ir_node *n) tarval *tv; ir_node *old_n = n; + if (!get_optimize()) return n; + /* if not optimize return n */ if (n == NULL) { /* Here this is possible. Why? */ @@ -973,15 +993,17 @@ optimize_in_place (ir_node *n) tv = computed_value (n); if (tv != NULL) { /* evaluation was succesful -- replace the node. */ - return new_Const (get_tv_mode (tv), tv); + n = new_Const (get_tv_mode (tv), tv); + deb_info_copy(n, old_n, id_from_str("const_eval", 10)); + return n; /* xprintf("* optimize: computed node %I\n", n->op->name);*/ } } } /* remove unnecessary nodes */ - if (get_opt_constant_folding()) - // if (get_opt_constant_folding() || get_irn_op(n) == op_Phi) + //if (get_opt_constant_folding()) + if (get_opt_constant_folding() || get_irn_op(n) == op_Phi) n = equivalent_node (n); /** common subexpression elimination **/ @@ -997,11 +1019,9 @@ optimize_in_place (ir_node *n) /* The AmRoq fiasco returns n here. Martin's version doesn't. */ } -#if 0 /* Some more constant expression evaluation. */ if (get_opt_constant_folding()) n = transform_node (n); -#endif /* Remove nodes with dead (Bad) input. */ n = gigo (n);