X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=1dd151fb4ab946db6e57c856aaef108129c87bb1;hb=62526938a78e229e700fef9bd825e87d14ba549f;hp=742e6a8e8b0b2c7e93f76bb62b2c91fc68d65ed1;hpb=d61b4fcf547abba70184af32e2d3acc77531c623;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 742e6a8e8..1dd151fb4 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -6,6 +6,10 @@ ** iropt --- optimizations intertwined with IR construction. */ +#ifdef HAVE_CONFIG_H +# include +#endif + # include "irnode_t.h" # include "irgraph_t.h" # include "iropt_t.h" @@ -82,14 +86,15 @@ computed_value (ir_node *n) break; case iro_Minus: if (ta && mode_is_float(get_irn_mode(a))) - res = /*tarval_minus (ta);*/ res; + res = tarval_neg (ta); break; case iro_Mul: if (ta && tb) /* tarval_mul tests for equivalent modes itself */ { res = tarval_mul (ta, tb); } else { - /* calls computed_value recursive and returns the 0 with proper - mode. Why is this an extra case? */ + /* a*0 = 0 or 0*b = 0: + calls computed_value recursive and returns the 0 with proper + mode. */ tarval *v; if ( (tarval_classify ((v = computed_value (a))) == 0) || (tarval_classify ((v = computed_value (b))) == 0)) { @@ -97,10 +102,31 @@ computed_value (ir_node *n) } } break; + case iro_Quot: + /* This was missing in original implementation. Why? */ + if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))) { + if (tarval_classify(tb) == 0) {res = NULL; break;} + res = tarval_quo(ta, tb); + } + break; + case iro_Div: + /* This was missing in original implementation. Why? */ + if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))) { + if (tarval_classify(tb) == 0) {res = NULL; break;} + res = tarval_div(ta, tb); + } + break; + case iro_Mod: + /* This was missing in original implementation. Why? */ + if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))) { + if (tarval_classify(tb) == 0) {res = NULL; break;} + res = tarval_mod(ta, tb); + } + break; + /* for iro_DivMod see iro_Proj */ case iro_Abs: if (ta) - res = /*tarval_abs (ta);*/ res; - /* allowed or problems with max/min ?? */ + res = tarval_abs (ta); break; case iro_And: if (ta && tb) { @@ -125,14 +151,15 @@ 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_neg (ta); } break; case iro_Shl: if (ta && tb) { res = tarval_shl (ta, tb); } break; + /* tarval_shr is faulty !! */ 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_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_Conv:if (ta) { res = tarval_convert_to (ta, get_irn_mode (n)); } break; - case iro_Proj: + case iro_Proj: /* iro_Cmp */ { ir_node *aa, *ab; @@ -195,6 +222,16 @@ computed_value (ir_node *n) res = tarval_from_long (mode_b, get_Proj_proj(n) & irpn_Ne); } } + } else if (get_irn_op(a) == op_DivMod) { + ta = value_of(get_DivMod_left(a)); + tb = value_of(get_DivMod_right(a)); + if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))) { + if (tarval_classify(tb) == 0) {res = NULL; break;} + if (get_Proj_proj(n)== 0) /* Div */ + res = tarval_div(ta, tb); + else /* Mod */ + res = tarval_mod(ta, tb); + } } else { /* printf(" # comp_val: Proj node, not optimized\n"); */ } @@ -260,15 +297,18 @@ equivalent_node (ir_node *n) /* 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. */ + This should be true, as the block is matured before optimize is called. + But what about Phi-cycles with the Phi0/Id that could not be resolved? */ if (get_Block_n_cfgpreds(n) == 1 && get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) { n = get_nodes_Block(get_Block_cfgpred(n, 0)); - } else if (n != current_ir_graph->start_block) { + } else if ((n != current_ir_graph->start_block) && + (n != current_ir_graph->end_block) ) { int i; /* If all inputs are dead, this block is dead too, except if it is - the start block. This is a step of unreachable code elimination */ + the start or end block. This is a step of unreachable code + elimination */ for (i = 0; i < get_Block_n_cfgpreds(n); i++) { if (!is_Bad(get_Block_cfgpred(n, i))) break; } @@ -614,7 +654,7 @@ transform_node (ir_node *n) set_Tuple_pred(n, 0, jmp); set_Tuple_pred(n, 1, new_Bad()); } - } else if (ta && (get_irn_mode(a) == mode_I)) { + } else if (ta && (get_irn_mode(a) == mode_I) && (get_Cond_kind(n) == dense)) { /* I don't want to allow Tuples smaller than the biggest Proj. Also this tuple might get really big... I generate the Jmp here, and remember it in link. Link is used @@ -658,7 +698,8 @@ transform_node (ir_node *n) set_Proj_proj(n, 0); } else if ( (get_irn_op(a) == op_Cond) && (get_irn_mode(get_Cond_selector(a)) == mode_I) - && value_of(a)) { + && value_of(a) + && (get_Cond_kind(a) == dense)) { /* The Cond is a Switch on a Constant */ if (get_Proj_proj(n) == tv_val_CHIL(value_of(a))) { /* The always taken branch, reuse the existing Jmp. */ @@ -709,7 +750,7 @@ transform_node (ir_node *n) return n; } -/***************** Common Subexpression Elimination *****************/ +/* **************** Common Subexpression Elimination **************** */ /* Compare function for two nodes in the hash table. Gets two */ /* nodes as parameters. */ @@ -761,8 +802,7 @@ vt_cmp (const void *elt, const void *key) return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num) || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ); case iro_Call: - return (get_irn_call_attr(a)->kind != get_irn_call_attr(b)->kind) - || (get_irn_call_attr(a)->arity != get_irn_call_attr(b)->arity); + return (get_irn_call_attr(a) != get_irn_call_attr(b)); case iro_Sel: return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind) || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name) @@ -973,7 +1013,6 @@ optimize (ir_node *n) ir_node * optimize_in_place (ir_node *n) { - tarval *tv; ir_node *old_n = n; @@ -1002,7 +1041,7 @@ optimize_in_place (ir_node *n) } /* remove unnecessary nodes */ - //if (get_opt_constant_folding()) + /*if (get_opt_constant_folding()) */ if (get_opt_constant_folding() || get_irn_op(n) == op_Phi) n = equivalent_node (n); @@ -1028,12 +1067,11 @@ optimize_in_place (ir_node *n) /* Now we can verify the node, as it has no dead inputs any more. */ irn_vrfy(n); - /* Now we have a legal, useful node. Enter it in hash table for cse */ - if (get_opt_cse()) { - /* aborts ??! set/pset can not handle several hash tables??! - No, suddenly it works. */ + /* Now we have a legal, useful node. Enter it in hash table for cse. + Blocks should be unique anyways. (Except the successor of start: + is cse with the start block!) */ + if (get_opt_cse() && (get_irn_opcode(n) != iro_Block)) n = identify_remember (current_ir_graph->value_table, n); - } return n; }