# include "irflag_t.h"
# include "firmstat.h"
# include "irarch.h"
+# include "hashptr.h"
/* Make types visible to allow most efficient access */
# include "entity_t.h"
+# ifdef DO_HEAPANALYSIS
+/* heapanal can't cope with NoMems */
+# else /* if defined DO_HEAPANALYSIS */
+# define USE_NOMEM
+# endif /* defined DO_HEAPANALYSIS */
+
/**
* Trivial INLINEable routine for copy propagation.
* Does follow Ids, needed to optimize INLINEd code.
tarval *ta = value_of(a);
tarval *tb = value_of(b);
- if ((ta != tarval_bad) && (tb != tarval_bad)
- && (get_irn_mode(a) == get_irn_mode(b))
- && !(get_mode_sort(get_irn_mode(a)) == irms_reference)) {
+ if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b)))
return tarval_add(ta, tb);
- }
+
return tarval_bad;
}
ta = value_of(a);
tb = value_of(b);
- if ((ta != tarval_bad) && (tb != tarval_bad)
- && (get_irn_mode(a) == get_irn_mode(b))
- && !(get_mode_sort(get_irn_mode(a)) == irms_reference)) {
+ if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b)))
return tarval_sub(ta, tb);
- }
+
return tarval_bad;
}
/* a*0 = 0 or 0*b = 0:
calls computed_value recursive and returns the 0 with proper
mode. */
- tarval *v;
-
- if ( ( ((v = ta) != tarval_bad)
- && (v == get_mode_null(get_tarval_mode(v))) )
- || ( ((v = tb) != tarval_bad)
- && (v == get_mode_null(get_tarval_mode(v))) )) {
- return v;
- }
+ if ((ta != tarval_bad) && (ta == get_mode_null(get_tarval_mode(ta))))
+ return ta;
+ if ((tb != tarval_bad) && (tb == get_mode_null(get_tarval_mode(tb))))
+ return tb;
}
return tarval_bad;
}
tarval *tb = value_of(b);
/* Compute c1 / c2 or 0 / a, a != 0 */
- if ((ta != tarval_bad) && (tb != get_mode_null(get_irn_mode(b)))) {
- if (tb != tarval_bad) /* div by zero: return tarval_bad */
+ if (ta != tarval_bad) {
+ if ((tb != tarval_bad) && (tb != get_mode_null(get_irn_mode(b)))) /* div by zero: return tarval_bad */
return tarval_div(ta, tb);
else if (ta == get_mode_null(get_tarval_mode(ta))) /* 0 / b == 0 */
return ta;
} else {
tarval *v;
- if ( (classify_tarval ((v = computed_value (a))) == TV_CLASSIFY_NULL)
- || (classify_tarval ((v = computed_value (b))) == TV_CLASSIFY_NULL)) {
+ if ( (classify_tarval ((v = ta)) == TV_CLASSIFY_NULL)
+ || (classify_tarval ((v = tb)) == TV_CLASSIFY_NULL)) {
return v;
}
}
return tarval_or (ta, tb);
} else {
tarval *v;
- if ( (classify_tarval ((v = computed_value (a))) == TV_CLASSIFY_ALL_ONE)
- || (classify_tarval ((v = computed_value (b))) == TV_CLASSIFY_ALL_ONE)) {
+ if ( (classify_tarval ((v = ta)) == TV_CLASSIFY_ALL_ONE)
+ || (classify_tarval ((v = tb)) == TV_CLASSIFY_ALL_ONE)) {
return v;
}
}
ir_node *a = get_Eor_left(n);
ir_node *b = get_Eor_right(n);
- tarval *ta = value_of(a);
- tarval *tb = value_of(b);
+ tarval *ta, *tb;
+
+ if (a == b)
+ return get_tarval_null(get_irn_mode(n));
+
+ ta = value_of(a);
+ tb = value_of(b);
if ((ta != tarval_bad) && (tb != tarval_bad)) {
return tarval_eor (ta, tb);
ab = get_Cmp_right(a);
proj_nr = get_Proj_proj(n);
- if (aa == ab) { /* 1.: */
+ if (aa == ab && !mode_is_float(get_irn_mode(aa))) { /* 1.: */
+ /* BEWARE: a == a is NOT always True for floating Point!!! */
/* This is a trick with the bits used for encoding the Cmp
Proj numbers, the following statement is not the same:
return new_tarval_from_long (proj_nr == Eq, mode_b) */
return new_tarval_from_long (proj_nr & Eq, mode_b);
} else {
- tarval *taa = computed_value (aa);
- tarval *tab = computed_value (ab);
+ tarval *taa = value_of(aa);
+ tarval *tab = value_of(ab);
if ((taa != tarval_bad) && (tab != tarval_bad)) { /* 2.: */
/* strange checks... */
return n;
}
-/**
- * Use algebraic simplification a v a = a.
- */
-static ir_node *equivalent_node_Or(ir_node *n)
-{
- ir_node *oldn = n;
-
- ir_node *a = get_Or_left(n);
- ir_node *b = get_Or_right(n);
-
- /* remove a v a */
- if (a == b) {
- n = a;
-
- DBG_OPT_ALGSIM1(oldn, a, b, n);
- }
-
- return n;
-}
-
/**
* optimize operations that are commutative and have neutral 0,
* so a op 0 = 0 op a = a.
/* After running compute_node there is only one constant predecessor.
Find this predecessors value and remember the other node: */
- if ((tv = computed_value(a)) != tarval_bad) {
+ if ((tv = value_of(a)) != tarval_bad) {
on = b;
- } else if ((tv = computed_value(b)) != tarval_bad) {
+ } else if ((tv = value_of(b)) != tarval_bad) {
on = a;
} else
return n;
ir_node *a = get_binop_left(n);
ir_node *b = get_binop_right(n);
- if (classify_tarval(computed_value(b)) == TV_CLASSIFY_NULL) {
+ if (classify_tarval(value_of(b)) == TV_CLASSIFY_NULL) {
n = a;
DBG_OPT_ALGSIM1(oldn, a, b, n);
ir_node *b = get_Mul_right(n);
/* Mul is commutative and has again an other neutral element. */
- if (classify_tarval (computed_value (a)) == TV_CLASSIFY_ONE) {
+ if (classify_tarval(value_of(a)) == TV_CLASSIFY_ONE) {
n = b;
DBG_OPT_ALGSIM1(oldn, a, b, n);
- } else if (classify_tarval (computed_value (b)) == TV_CLASSIFY_ONE) {
+ } else if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) {
n = a;
DBG_OPT_ALGSIM1(oldn, a, b, n);
}
ir_node *b = get_Div_right(n);
/* Div is not commutative. */
- if (classify_tarval(computed_value(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
+ if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
/* Turn Div into a tuple (mem, bad, a) */
ir_node *mem = get_Div_mem(n);
turn_into_tuple(n, 3);
ir_node *b = get_DivMod_right(n);
/* Div is not commutative. */
- if (classify_tarval(computed_value(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
+ if (classify_tarval(value_of(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
/* Turn DivMod into a tuple (mem, bad, a, 0) */
ir_node *mem = get_Div_mem(n);
ir_mode *mode = get_irn_mode(b);
return n;
}
+/**
+ * Use algebraic simplification a | a = a | 0 = 0 | a = a.
+ */
+static ir_node *equivalent_node_Or(ir_node *n)
+{
+ ir_node *oldn = n;
+
+ ir_node *a = get_Or_left(n);
+ ir_node *b = get_Or_right(n);
+
+ if (a == b) {
+ n = a; /* Or has it's own neutral element */
+ } else if (classify_tarval(value_of(a)) == TV_CLASSIFY_NULL) {
+ n = b;
+ DBG_OPT_ALGSIM1(oldn, a, b, n);
+ } else if (classify_tarval(value_of(b)) == TV_CLASSIFY_NULL) {
+ n = a;
+ DBG_OPT_ALGSIM1(oldn, a, b, n);
+ }
+
+ return n;
+}
+
/**
* Optimize a & 0b1...1 = 0b1...1 & a = a & a = a.
*/
if (a == b) {
n = a; /* And has it's own neutral element */
- } else if (classify_tarval(computed_value(a)) == TV_CLASSIFY_ALL_ONE) {
+ } else if (classify_tarval(value_of(a)) == TV_CLASSIFY_ALL_ONE) {
n = b;
DBG_OPT_ALGSIM1(oldn, a, b, n);
- } else if (classify_tarval(computed_value(b)) == TV_CLASSIFY_ALL_ONE) {
+ } else if (classify_tarval(value_of(b)) == TV_CLASSIFY_ALL_ONE) {
n = a;
DBG_OPT_ALGSIM1(oldn, a, b, n);
}
if (n_mode == b_mode) {
if (n_mode == mode_b) {
n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
- DBG_OPT_ALGSIM1(oldn, a, b, n);
+ DBG_OPT_ALGSIM1(oldn, a, b, n);
}
else if (mode_is_int(n_mode) || mode_is_character(n_mode)) {
if (smaller_mode(b_mode, a_mode)){
n = b; /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
- DBG_OPT_ALGSIM1(oldn, a, b, n);
+ DBG_OPT_ALGSIM1(oldn, a, b, n);
}
}
}
return n;
}
+/**
+ * A Cast may be removed if the type of the previous node
+ * is already to type of the Cast.
+ */
+static ir_node *equivalent_node_Cast(ir_node *n) {
+ ir_node *pred = get_Cast_op(n);
+ if (get_irn_type(pred) == get_Cast_type(n))
+ n = pred;
+ return n;
+}
+
+/* Several optimizations:
+ - no Phi in start block.
+ - remove Id operators that are inputs to Phi
+ - fold Phi-nodes, iff they have only one predecessor except
+ themselves.
+*/
static ir_node *equivalent_node_Phi(ir_node *n)
{
- /* Several optimizations:
- - no Phi in start block.
- - remove Id operators that are inputs to Phi
- - fold Phi-nodes, iff they have only one predecessor except
- themselves.
- */
int i, n_preds;
ir_node *oldn = n;
CASE(DivMod);
CASE(And);
CASE(Conv);
+ CASE(Cast);
CASE(Phi);
CASE(Proj);
CASE(Id);
} /* end switch */
}
-static ir_node *transform_node_Mul(ir_node *n)
-{
+/**
+ * Transform AddP(P, ConvIs(Iu)), AddP(P, ConvIu(Is)) and
+ * SubP(P, ConvIs(Iu)), SubP(P, ConvIu(Is)) if possible.
+ */
+static ir_node *transform_node_AddSub(ir_node *n)
+{
+ ir_mode *mode = get_irn_mode(n);
+
+ if (mode_is_reference(mode)) {
+ ir_node *left = get_binop_left(n);
+ ir_node *right = get_binop_right(n);
+ int ref_bits = get_mode_size_bits(mode);
+
+ if (get_irn_op(left) == op_Conv) {
+ ir_mode *mode = get_irn_mode(left);
+ int bits = get_mode_size_bits(mode);
+
+ if (ref_bits == bits &&
+ mode_is_int(mode) &&
+ get_mode_arithmetic(mode) == irma_twos_complement) {
+ ir_node *pre = get_Conv_op(left);
+ ir_mode *pre_mode = get_irn_mode(pre);
+
+ if (mode_is_int(pre_mode) &&
+ get_mode_size_bits(pre_mode) == bits &&
+ get_mode_arithmetic(pre_mode) == irma_twos_complement) {
+ /* ok, this conv just changes to sign, moreover the calculation
+ * is done with same number of bits as our address mode, so
+ * we can ignore the conv as address calculation can be viewed
+ * as either signed or unsigned
+ */
+ set_binop_left(n, pre);
+ }
+ }
+ }
+
+ if (get_irn_op(right) == op_Conv) {
+ ir_mode *mode = get_irn_mode(right);
+ int bits = get_mode_size_bits(mode);
+
+ if (ref_bits == bits &&
+ mode_is_int(mode) &&
+ get_mode_arithmetic(mode) == irma_twos_complement) {
+ ir_node *pre = get_Conv_op(right);
+ ir_mode *pre_mode = get_irn_mode(pre);
+
+ if (mode_is_int(pre_mode) &&
+ get_mode_size_bits(pre_mode) == bits &&
+ get_mode_arithmetic(pre_mode) == irma_twos_complement) {
+ /* ok, this conv just changes to sign, moreover the calculation
+ * is done with same number of bits as our address mode, so
+ * we can ignore the conv as address calculation can be viewed
+ * as either signed or unsigned
+ */
+ set_binop_right(n, pre);
+ }
+ }
+ }
+ }
+ return n;
+}
+
+#define transform_node_Add transform_node_AddSub
+#define transform_node_Sub transform_node_AddSub
+
+/** Do architecture dependend optimizations on Mul nodes */
+static ir_node *transform_node_Mul(ir_node *n) {
return arch_dep_replace_mul_with_shifts(n);
}
static ir_node *transform_node_Div(ir_node *n)
{
- tarval *tv = computed_value(n);
+ tarval *tv = value_of(n);
ir_node *value = n;
/* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
static ir_node *transform_node_Mod(ir_node *n)
{
- tarval *tv = computed_value(n);
+ tarval *tv = value_of(n);
ir_node *value = n;
/* BEWARE: it is NOT possible to optimize a%a to 0, as this may cause a exception */
add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_block(n));
} else if ((get_irn_op(a) == op_Eor)
&& (get_irn_mode(a) == mode_b)
- && (classify_tarval(computed_value(get_Eor_right(a))) == TV_CLASSIFY_ONE)) {
+ && (classify_tarval(value_of(get_Eor_right(a))) == TV_CLASSIFY_ONE)) {
/* The Eor is a negate. Generate a new Cond without the negate,
simulate the negate by exchanging the results. */
set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_block(n),
return n;
}
+/**
+ * Transform an Eor.
+ */
static ir_node *transform_node_Eor(ir_node *n)
{
ir_node *a = get_Eor_left(n);
if ((get_irn_mode(n) == mode_b)
&& (get_irn_op(a) == op_Proj)
&& (get_irn_mode(a) == mode_b)
- && (classify_tarval (computed_value (b)) == TV_CLASSIFY_ONE)
+ && (classify_tarval (value_of(b)) == TV_CLASSIFY_ONE)
&& (get_irn_op(get_Proj_pred(a)) == op_Cmp))
/* The Eor negates a Cmp. The Cmp has the negated result anyways! */
n = new_r_Proj(current_ir_graph, get_nodes_block(n), get_Proj_pred(a),
mode_b, get_negated_pnc(get_Proj_proj(a)));
else if ((get_irn_mode(n) == mode_b)
- && (classify_tarval (computed_value (b)) == TV_CLASSIFY_ONE))
+ && (classify_tarval (value_of(b)) == TV_CLASSIFY_ONE))
/* The Eor is a Not. Replace it by a Not. */
/* ????!!!Extend to bitfield 1111111. */
n = new_r_Not(current_ir_graph, get_nodes_block(n), a, mode_b);
return n;
}
+/**
+ * Transform a Cast of a Const into a new Const
+ */
+static ir_node *transform_node_Cast(ir_node *n) {
+ ir_node *pred = get_Cast_op(n);
+ type *tp = get_irn_type(pred);
+
+ if (get_irn_op(pred) == op_Const && get_Const_type(pred) != tp) {
+ n = new_rd_Const_type(NULL, current_ir_graph, get_nodes_block(pred), get_irn_mode(pred),
+ get_Const_tarval(pred), tp);
+ } else if ((get_irn_op(pred) == op_SymConst) && (get_SymConst_value_type(pred) != tp)) {
+ n = new_rd_SymConst_type(NULL, current_ir_graph, get_nodes_block(pred), get_SymConst_symbol(pred),
+ get_SymConst_kind(pred), tp);
+ }
+ return n;
+}
+
/**
* Transform a Div/Mod/DivMod with a non-zero constant. Must be
- * done here instead of equivalent node because in creates new
+ * done here instead of equivalent node because it creates new
* nodes.
- * Removes the exceptions and routes the memory to the initial mem.
+ * Removes the exceptions and routes the memory to the NoMem node.
*
* Further, it optimizes jump tables by removing all impossible cases.
*/
switch (get_irn_opcode(n)) {
case iro_Div:
b = get_Div_right(n);
- tb = computed_value(b);
+ tb = value_of(b);
if (tb != tarval_bad && classify_tarval(tb) != TV_CLASSIFY_NULL) { /* div(x, c) && c != 0 */
proj_nr = get_Proj_proj(proj);
if (proj_nr == pn_Div_X_except) {
/* we found an exception handler, remove it */
return new_Bad();
- }
- else {
- /* the memory Proj can be removed */
+ } else {
+ /* the memory Proj can be removed */
ir_node *res = get_Div_mem(n);
- set_Div_mem(n, get_irg_initial_mem(current_ir_graph));
-
- if (proj_nr == pn_Div_M)
+# ifdef USE_NOMEM
+ set_Div_mem(n, get_irg_no_mem(current_ir_graph));
+# endif /* defined USE_NOMEM */
+ if (proj_nr == pn_Div_M)
return res;
}
}
break;
case iro_Mod:
b = get_Mod_right(n);
- tb = computed_value(b);
+ tb = value_of(b);
if (tb != tarval_bad && classify_tarval(tb) != TV_CLASSIFY_NULL) { /* mod(x, c) && c != 0 */
proj_nr = get_Proj_proj(proj);
if (proj_nr == pn_Mod_X_except) {
/* we found an exception handler, remove it */
return new_Bad();
- }
- else {
- /* the memory Proj can be removed */
+ } else {
+ /* the memory Proj can be removed */
ir_node *res = get_Mod_mem(n);
- set_Mod_mem(n, get_irg_initial_mem(current_ir_graph));
+# ifdef USE_NOMEM
+ set_Mod_mem(n, get_irg_no_mem(current_ir_graph));
+# endif /* defined USE_NOMEM */
if (proj_nr == pn_Mod_M)
- return res;
+ return res;
}
}
break;
case iro_DivMod:
b = get_DivMod_right(n);
- tb = computed_value(b);
+ tb = value_of(b);
if (tb != tarval_bad && classify_tarval(tb) != TV_CLASSIFY_NULL) { /* DivMod(x, c) && c != 0 */
proj_nr = get_Proj_proj(proj);
return new_Bad();
}
else {
- /* the memory Proj can be removed */
+ /* the memory Proj can be removed */
ir_node *res = get_DivMod_mem(n);
- set_DivMod_mem(n, get_irg_initial_mem(current_ir_graph));
+# ifdef USE_NOMEM
+ set_DivMod_mem(n, get_irg_no_mem(current_ir_graph));
+# endif /* defined USE_NOMEM */
if (proj_nr == pn_DivMod_M)
- return res;
+ return res;
}
}
break;
case iro_Cond:
if (get_opt_unreachable_code()) {
b = get_Cond_selector(n);
- tb = computed_value(b);
+ tb = value_of(b);
if (tb != tarval_bad && mode_is_int(get_tarval_mode(tb))) {
/* we have a constant switch */
if (get_irn_op(left) != get_irn_op(n))
return n;
- tv1 = computed_value(get_binop_right(n));
+ tv1 = value_of(get_binop_right(n));
if (tv1 == tarval_bad)
return n;
- tv2 = computed_value(get_binop_right(left));
- if (tv1 == tarval_bad)
+ tv2 = value_of(get_binop_right(left));
+ if (tv2 == tarval_bad)
return n;
res = tarval_add(tv1, tv2);
break
switch (op->code) {
+ CASE(Add);
+ CASE(Sub);
CASE(Mul);
CASE(Div);
CASE(Mod);
CASE(Cond);
CASE(Eor);
CASE(Not);
+ CASE(Cast);
CASE(Proj);
CASE(Or);
case iro_Shr:
static int node_cmp_attr_SymConst(ir_node *a, ir_node *b)
{
return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
- || (get_irn_symconst_attr(a).sym.type_p != get_irn_symconst_attr(b).sym.type_p);
+ || (get_irn_symconst_attr(a).sym.type_p != get_irn_symconst_attr(b).sym.type_p)
+ || (get_irn_symconst_attr(a).tp != get_irn_symconst_attr(b).tp);
}
/** Compares the attributes of two Call nodes. */
return (get_irn_call_attr(a) != get_irn_call_attr(b));
}
-/** Compares the attributes of two FuncCall nodes. */
-static int node_cmp_attr_FuncCall(ir_node *a, ir_node *b)
-{
- return (get_irn_funccall_attr(a) != get_irn_funccall_attr(b));
-}
-
/** Compares the attributes of two Sel nodes. */
static int node_cmp_attr_Sel(ir_node *a, ir_node *b)
{
CASE(Free);
CASE(SymConst);
CASE(Call);
- CASE(FuncCall);
CASE(Sel);
CASE(Phi);
CASE(Cast);
if ((get_irn_op(a) != get_irn_op(b)) ||
(get_irn_mode(a) != get_irn_mode(b))) return 1;
- /* compare if a's in and b's in are equal */
- irn_arity_a = get_irn_arity (a);
- if (irn_arity_a != get_irn_arity(b))
+ /* compare if a's in and b's in are of equal length */
+ irn_arity_a = get_irn_intra_arity (a);
+ if (irn_arity_a != get_irn_intra_arity(b))
return 1;
/* for block-local cse and op_pin_state_pinned nodes: */
if (!get_opt_global_cse() || (get_irn_pinned(a) == op_pin_state_pinned)) {
- if (get_irn_n(a, -1) != get_irn_n(b, -1))
+ if (get_irn_intra_n(a, -1) != get_irn_intra_n(b, -1))
return 1;
}
/* compare a->in[0..ins] with b->in[0..ins] */
for (i = 0; i < irn_arity_a; i++)
- if (get_irn_n(a, i) != get_irn_n(b, i))
+ if (get_irn_intra_n(a, i) != get_irn_intra_n(b, i))
return 1;
/*
if (node->op == op_Const) {
/* special value for const, as they only differ in their tarval. */
- h = ((unsigned) node->attr.con.tv)>>3 ;
- h = 9*h + (unsigned)get_irn_mode(node);
+ h = HASH_PTR(node->attr.con.tv);
+ h = 9*h + HASH_PTR(get_irn_mode(node));
} else if (node->op == op_SymConst) {
/* special value for const, as they only differ in their symbol. */
- h = ((unsigned) node->attr.i.sym.type_p)>>3 ;
- h = 9*h + (unsigned)get_irn_mode(node);
+ h = HASH_PTR(node->attr.i.sym.type_p);
+ h = 9*h + HASH_PTR(get_irn_mode(node));
} else {
/* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
- h = irn_arity = get_irn_arity(node);
+ h = irn_arity = get_irn_intra_arity(node);
- /* consider all in nodes... except the block. */
- for (i = 0; i < irn_arity; i++) {
- h = 9*h + (unsigned)get_irn_n(node, i);
+ /* consider all in nodes... except the block if not a control flow. */
+ for (i = is_cfop(node) ? -1 : 0; i < irn_arity; i++) {
+ h = 9*h + HASH_PTR(get_irn_intra_n(node, i));
}
/* ...mode,... */
- h = 9*h + (unsigned) get_irn_mode (node);
+ h = 9*h + HASH_PTR(get_irn_mode(node));
/* ...and code */
- h = 9*h + (unsigned) get_irn_op (node);
+ h = 9*h + HASH_PTR(get_irn_op(node));
}
return h;
}
pset *
-new_identities (void)
-{
- return new_pset (vt_cmp, N_IR_NODES);
+new_identities(void) {
+ return new_pset(vt_cmp, N_IR_NODES);
}
void
-del_identities (pset *value_table)
-{
- del_pset (value_table);
+del_identities(pset *value_table) {
+ del_pset(value_table);
}
/**
ir_node *oldn = n;
opcode iro = get_irn_opcode(n);
- /* Always optimize Phi nodes: part of the construction. */
+ type *old_tp = get_irn_type(n);
+ {
+ int i, arity = get_irn_arity(n);
+ for (i = 0; i < arity && !old_tp; ++i)
+ old_tp = get_irn_type(get_irn_n(n, i));
+ }
+
+ /* Allways optimize Phi nodes: part of the construction. */
if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
/* constant expression evaluation / constant folding */
/* constants can not be evaluated */
if (iro != iro_Const) {
/* try to evaluate */
- tv = computed_value (n);
+ tv = computed_value(n);
if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
/*
* we MUST copy the node here temporary, because it's still needed
- * for DBG_OPT_ALGSIM0
+ * for DBG_OPT_CSTEVAL
*/
int node_size = offsetof(ir_node, attr) + n->op->attr_size;
oldn = alloca(node_size);
memcpy(oldn, n, node_size);
- CLONE_ARR_A(ir_node *, oldn->in, n->in);
+ CLONE_ARR_A(ir_node *, oldn->in, n->in);
- /* ARG, copy the in array, we need it for statistics */
- memcpy(oldn->in, n->in, ARR_LEN(n->in) * sizeof(n->in[0]));
+ /* ARG, copy the in array, we need it for statistics */
+ memcpy(oldn->in, n->in, ARR_LEN(n->in) * sizeof(n->in[0]));
/* evaluation was successful -- replace the node. */
obstack_free (current_ir_graph->obst, n);
n = new_Const (get_tarval_mode (tv), tv);
-
- DBG_OPT_ALGSIM0(oldn, n);
+ if (old_tp && get_type_mode(old_tp) == get_tarval_mode (tv))
+ set_Const_type(n, old_tp);
+ DBG_OPT_CSTEVAL(oldn, n);
return n;
}
}
ir_node *oldn = n;
opcode iro = get_irn_opcode(n);
+ type *old_tp = get_irn_type(n);
+ {
+ int i, arity = get_irn_arity(n);
+ for (i = 0; i < arity && !old_tp; ++i)
+ old_tp = get_irn_type(get_irn_n(n, i));
+ }
+
if (!get_opt_optimize() && (get_irn_op(n) != op_Phi)) return n;
/* if not optimize return n */
return n;
}
-
/* constant expression evaluation / constant folding */
if (get_opt_constant_folding()) {
/* constants can not be evaluated */
if (iro != iro_Const) {
/* try to evaluate */
- tv = computed_value (n);
+ tv = computed_value(n);
if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
/* evaluation was successful -- replace the node. */
n = new_Const (get_tarval_mode (tv), tv);
- DBG_OPT_ALGSIM0(oldn, n);
+ if (old_tp && get_type_mode(old_tp) == get_tarval_mode (tv))
+ set_Const_type(n, old_tp);
+
+ DBG_OPT_CSTEVAL(oldn, n);
return n;
}
}