From: Michael Beck Date: Thu, 6 Nov 2008 01:19:18 +0000 (+0000) Subject: - neither Abs nor Minus change the precision, so we can look-through them X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=0449c5797debdf6977cecaac6324d1c88a79478d;p=libfirm - neither Abs nor Minus change the precision, so we can look-through them when checking for superflous strictConv [r23460] --- diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index b4f5f0fb6..7e3c861c6 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -1214,19 +1214,39 @@ static ir_node *equivalent_node_Conv(ir_node *n) { restart: if (n_mode == a_mode) { /* No Conv necessary */ if (get_Conv_strict(n)) { - /* special case: the predecessor might be a also a Conv */ - if (is_Conv(a)) { - if (! get_Conv_strict(a)) { + ir_node *p = a; + ir_node *s = n; + + /* neither Minus nor Abs nor Confirm change the precision, + so we can "look-through" */ + for (;;) { + if (is_Minus(p)) { + s = p; + p = get_Minus_op(p); + } else if (is_Abs(p)) { + s = p; + p = get_Abs_op(p); + } else if (is_Confirm(p)) { + s = p; + p = get_Confirm_value(p); + } else { + /* stop here */ + break; + } + } + if (is_Conv(p)) { + /* special case: the predecessor is also a Conv */ + if (! get_Conv_strict(p)) { /* first one is not strict, kick it */ - a = get_Conv_op(a); + p = get_Conv_op(p); a_mode = get_irn_mode(a); - set_Conv_op(n, a); + set_irn_n(s, 1, p); goto restart; } /* else both are strict conv, second is superfluous */ } else { - if (is_Proj(a)) { - ir_node *pred = get_Proj_pred(a); + if (is_Proj(p)) { + ir_node *pred = get_Proj_pred(p); if (is_Load(pred)) { /* loads always return with the exact precision of n_mode */ assert(get_Load_mode(pred) == n_mode);