#include "opt_confirms.h"
#include "opt_polymorphy.h"
#include "irtools.h"
-#include "xmalloc.h"
+#include "array_t.h"
/* Make types visible to allow most efficient access */
#include "entity_t.h"
goto restart;
}
/* else both are strict conv, second is superfluous */
- } else if (is_Proj(a)) {
- ir_node *pred = get_Proj_pred(a);
- if (is_Load(pred)) {
- /* loads always return with the exact precision of n_mode */
- assert(get_Load_mode(pred) == n_mode);
- return a;
- }
- /* leave strict floating point Conv's */
- return n;
} else {
+ if (is_Proj(a)) {
+ ir_node *pred = get_Proj_pred(a);
+ if (is_Load(pred)) {
+ /* loads always return with the exact precision of n_mode */
+ assert(get_Load_mode(pred) == n_mode);
+ return a;
+ }
+ }
/* leave strict floating point Conv's */
return n;
}
n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
} else if (get_mode_arithmetic(n_mode) == get_mode_arithmetic(a_mode)) {
- if (smaller_mode(b_mode, a_mode)) {
+ if (values_in_mode(b_mode, a_mode)) {
n = b; /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
}
}
}
- if (mode_is_int(n_mode) && mode_is_float(a_mode)) {
+ if (mode_is_int(n_mode) && get_mode_arithmetic(a_mode) == irma_ieee754) {
/* ConvI(ConvF(I)) -> I, iff float mantissa >= int mode */
- size_t int_mantissa = get_mode_size_bits(n_mode) - (mode_is_signed(n_mode) ? 1 : 0);
- size_t float_mantissa;
- /* FIXME There is no way to get the mantissa size of a mode */
- switch (get_mode_size_bits(a_mode)) {
- case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
- case 64: float_mantissa = 52 + 1; break;
- case 80: float_mantissa = 64 + 1; break;
- default: float_mantissa = 0; break;
- }
- if (float_mantissa != 0 && float_mantissa >= int_mantissa) {
+ unsigned int_mantissa = get_mode_size_bits(n_mode) - (mode_is_signed(n_mode) ? 1 : 0);
+ unsigned float_mantissa = tarval_ieee754_get_mantissa_size(a_mode);
+
+ if (float_mantissa >= int_mantissa) {
n = b;
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
return n;
if (! is_Phi(n) || get_irn_arity(n) == 0)
return 0;
- for (i = get_irn_arity(n) - 1; i >= 0; --i)
+ for (i = get_irn_arity(n) - 1; i >= 0; --i) {
if (! is_Const(get_irn_n(n, i)))
return 0;
- return 1;
+ }
+ return 1;
} /* is_const_Phi */
typedef tarval *(*tarval_sub_type)(tarval *a, tarval *b, ir_mode *mode);
else if (proj_nr == pn_Cmp_Le || proj_nr == pn_Cmp_Lt) {
if (tv != tarval_bad) {
/* c >= 0 : Abs(a) <= c ==> (unsigned)(a + c) <= 2*c */
- if (get_irn_op(left) == op_Abs) { // TODO something is missing here
+ if (is_Abs(left)) { // TODO something is missing here
}
}
}
*/
static ir_node *transform_node_Conv(ir_node *n) {
ir_node *c, *oldn = n;
- ir_node *a = get_Conv_op(n);
+ ir_mode *mode = get_irn_mode(n);
+ ir_node *a = get_Conv_op(n);
- if (is_const_Phi(a)) {
- c = apply_conv_on_phi(a, get_irn_mode(n));
+ if (mode != mode_b && is_const_Phi(a)) {
+ /* Do NOT optimize mode_b Conv's, this leads to remaining
+ * Phib nodes later, because the conv_b_lower operation
+ * is instantly reverted, when it tries to insert a Convb.
+ */
+ c = apply_conv_on_phi(a, mode);
if (c) {
DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI);
return c;
}
if (is_Unknown(a)) { /* Conv_A(Unknown_B) -> Unknown_A */
- ir_mode *mode = get_irn_mode(n);
return new_r_Unknown(current_ir_graph, mode);
}
+ if (mode_is_reference(mode) &&
+ get_mode_size_bits(mode) == get_mode_size_bits(get_irn_mode(a)) &&
+ is_Add(a)) {
+ ir_node *l = get_Add_left(a);
+ ir_node *r = get_Add_right(a);
+ dbg_info *dbgi = get_irn_dbg_info(a);
+ ir_node *block = get_nodes_block(n);
+ if(is_Conv(l)) {
+ ir_node *lop = get_Conv_op(l);
+ if(get_irn_mode(lop) == mode) {
+ /* ConvP(AddI(ConvI(P), x)) -> AddP(P, x) */
+ n = new_rd_Add(dbgi, current_ir_graph, block, lop, r, mode);
+ return n;
+ }
+ }
+ if(is_Conv(r)) {
+ ir_node *rop = get_Conv_op(r);
+ if(get_irn_mode(rop) == mode) {
+ /* ConvP(AddI(x, ConvI(P))) -> AddP(x, P) */
+ n = new_rd_Add(dbgi, current_ir_graph, block, l, rop, mode);
+ return n;
+ }
+ }
+ }
+
return n;
} /* transform_node_Conv */
} else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) {
continue;
}
- /* FIXME: beabi need to keep a Proj(M) */
- if (is_Phi(ka) || is_irn_keep(ka) || is_Proj(ka))
- in[j++] = ka;
+ in[j++] = ka;
}
if (j != n_keepalives)
set_End_keepalives(n, j, in);