X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=e4647288f4cefdafc37ede8baccd7bdc4e9de2bd;hb=e1c33a238578342a072e1c95ff12eefe6d0acd37;hp=35bacda0bbf87375762917525042f98f107b95e0;hpb=2080968df998886ef494ff80bac44cac5773eb14;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 35bacda0b..e4647288f 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -59,9 +59,22 @@ static tarval *computed_value_Const(ir_node *n) */ static tarval *computed_value_SymConst(ir_node *n) { - if ((get_SymConst_kind(n) == symconst_size) && - (get_type_state(get_SymConst_type(n))) == layout_fixed) - return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(n)), get_irn_mode(n)); + ir_type *type; + + switch (get_SymConst_kind(n)) { + case symconst_type_size: + type = get_SymConst_type(n); + if (get_type_state(type) == layout_fixed) + return new_tarval_from_long(get_type_size_bytes(type), get_irn_mode(n)); + break; + case symconst_type_align: + type = get_SymConst_type(n); + if (get_type_state(type) == layout_fixed) + return new_tarval_from_long(get_type_alignment_bytes(type), get_irn_mode(n)); + break; + default: + break; + } return tarval_bad; } @@ -557,7 +570,6 @@ static tarval *computed_value_Proj_Cmp(ir_node *n) return new_tarval_from_long(proj_nr & pn_Cmp_Ne, mode_b); } } - return computed_value_Cmp_Confirm(a, aa, ab, proj_nr); } @@ -625,6 +637,8 @@ static tarval *computed_value_Mux(ir_node *n) */ static tarval *computed_value_Psi(ir_node *n) { + if (is_Mux(n)) + return computed_value_Mux(n); return tarval_bad; } @@ -805,7 +819,7 @@ static ir_node *equivalent_node_Block(ir_node *n) /** * Returns a equivalent node for a Jmp, a Bad :-) - * Of course this only happens if the Block of the Jmp is Bad. + * Of course this only happens if the Block of the Jmp is dead. */ static ir_node *equivalent_node_Jmp(ir_node *n) { @@ -816,7 +830,7 @@ static ir_node *equivalent_node_Jmp(ir_node *n) return n; } -/* Same for op_Raise */ +/** Raise is handled in the same way as Jmp. */ #define equivalent_node_Raise equivalent_node_Jmp @@ -864,6 +878,9 @@ static ir_node *equivalent_node_neutral_zero(ir_node *n) return n; } +/** + * Eor is commutative and has neutral 0. + */ #define equivalent_node_Eor equivalent_node_neutral_zero /* @@ -1008,10 +1025,10 @@ static ir_node *equivalent_node_idempotent_unop(ir_node *n) return n; } -/* Not(Not(x)) == x */ +/** Not(Not(x)) == x */ #define equivalent_node_Not equivalent_node_idempotent_unop -/* --x == x */ /* ??? Is this possible or can --x raise an +/** --x == x ??? Is this possible or can --x raise an out of bounds exception if min =! max? */ #define equivalent_node_Minus equivalent_node_idempotent_unop @@ -1434,11 +1451,13 @@ static ir_node *equivalent_node_Mux(ir_node *n) } /** - * Returns a equivalent node of a Psi: if a condition is true + * Returns a equivalent node of a Psi: if a condition is true * and all previous conditions are false we know its value. * If all conditions are false its value is the default one. */ static ir_node *equivalent_node_Psi(ir_node *n) { + if (is_Mux(n)) + return equivalent_node_Mux(n); return n; } @@ -1538,26 +1557,25 @@ static ir_node *equivalent_node_Bound(ir_node *n) * lower <= pred_lower && pred_upper <= upper. */ ir_node *upper = get_Bound_upper(n); - if (get_Bound_lower(pred) == lower && - get_Bound_upper(pred) == upper) { - /* - * One could expect that we simple return the previous - * Bound here. However, this would be wrong, as we could - * add an exception Proj to a new location than. - * So, we must turn in into a tuple - */ - ret_tuple = 1; - } + if (get_Bound_lower(pred) == lower && + get_Bound_upper(pred) == upper) { + /* + * One could expect that we simply return the previous + * Bound here. However, this would be wrong, as we could + * add an exception Proj to a new location than. + * So, we must turn in into a tuple + */ + ret_tuple = 1; + } } } if (ret_tuple) { /* Turn Bound into a tuple (mem, bad, idx) */ ir_node *mem = get_Bound_mem(n); turn_into_tuple(n, pn_Bound_max); - set_Tuple_pred(n, pn_Bound_M_regular, mem); - set_Tuple_pred(n, pn_Bound_X_except, new_Bad()); /* no exception */ - set_Tuple_pred(n, pn_Bound_res, idx); - set_Tuple_pred(n, pn_Bound_M_except, mem); + set_Tuple_pred(n, pn_Bound_M, mem); + set_Tuple_pred(n, pn_Bound_X_except, new_Bad()); /* no exception */ + set_Tuple_pred(n, pn_Bound_res, idx); } return n; } @@ -1664,6 +1682,18 @@ optimize_preds(ir_node *n) { } /* end switch */ } +/** + * Returns non-zero if all Phi predecessors are constants + */ +static int is_const_Phi(ir_node *phi) { + int i; + + for (i = get_irn_arity(phi) - 1; i >= 0; --i) + if (! is_Const(get_irn_n(phi, i))) + return 0; + return 1; +} + /** * Transform AddP(P, ConvIs(Iu)), AddP(P, ConvIu(Is)) and * SubP(P, ConvIs(Iu)), SubP(P, ConvIu(Is)). @@ -2398,7 +2428,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) proj_nr = get_inversed_pnc(proj_nr); changed |= 1; } - else if (left > right) { + else if (get_irn_idx(left) > get_irn_idx(right)) { ir_node *t = left; left = right; @@ -2621,6 +2651,42 @@ static ir_node *transform_node_Proj(ir_node *proj) } } +/** + * Move Confirms down through Phi nodes. + */ +static ir_node *transform_node_Phi(ir_node *phi) { + int i, n; + ir_mode *mode = get_irn_mode(phi); + + if (mode_is_reference(mode)) { + n = get_irn_arity(phi); + + /* Beware of Phi0 */ + if (n > 0) { + ir_node *pred = get_irn_n(phi, 0); + ir_node *bound; + pn_Cmp pnc; + + if (! is_Confirm(pred)) + return phi; + + bound = get_Confirm_bound(pred); + pnc = get_Confirm_cmp(pred); + + for (i = 1; i < n; ++i) { + pred = get_irn_n(phi, i); + + if (! is_Confirm(pred) || + get_Confirm_bound(pred) != bound || + get_Confirm_cmp(pred) != pnc) + return phi; + } + return new_r_Confirm(current_ir_graph, get_irn_n(phi, -1), phi, bound, pnc); + } + } + return phi; +} + /** * returns the operands of a commutative bin-op, if one operand is * a const, it is returned as the second one. @@ -3117,6 +3183,7 @@ static ir_op_ops *firm_set_default_transform_node(opcode code, ir_op_ops *ops) CASE(Not); CASE(Cast); CASE(Proj); + CASE(Phi); CASE(Sel); CASE(Or); CASE(Shr); @@ -3369,8 +3436,7 @@ del_identities(pset *value_table) { * nodes are extremely time critical because of their frequent use in * constant string arrays. */ -static INLINE ir_node * -identify (pset *value_table, ir_node *n) +static INLINE ir_node *identify(pset *value_table, ir_node *n) { ir_node *o = NULL; @@ -3382,14 +3448,14 @@ identify (pset *value_table, ir_node *n) ir_node *r = get_binop_right(n); /* for commutative operators perform a OP b == b OP a */ - if (l > r) { + if (get_irn_idx(l) > get_irn_idx(r)) { set_binop_left(n, r); set_binop_right(n, l); } } } - o = pset_find (value_table, n, ir_node_hash (n)); + o = pset_find(value_table, n, ir_node_hash (n)); if (!o) return n; DBG_OPT_CSE(n, o); @@ -3402,8 +3468,7 @@ identify (pset *value_table, ir_node *n) * optimization is performed. The flag turning on procedure global cse could * be changed between two allocations. This way we are safe. */ -static INLINE ir_node * -identify_cons (pset *value_table, ir_node *n) { +static INLINE ir_node *identify_cons(pset *value_table, ir_node *n) { ir_node *old = n; n = identify(value_table, n); @@ -3417,8 +3482,7 @@ identify_cons (pset *value_table, ir_node *n) { * Looks up the node in a hash table, enters it in the table * if it isn't there yet. */ -ir_node * -identify_remember (pset *value_table, ir_node *n) +ir_node *identify_remember(pset *value_table, ir_node *n) { ir_node *o = NULL; @@ -3447,18 +3511,28 @@ identify_remember (pset *value_table, ir_node *n) return o; } -void -add_identities (pset *value_table, ir_node *node) { - if (get_opt_cse() && (get_irn_opcode(node) != iro_Block)) - identify_remember (value_table, node); +/* Add a node to the identities value table. */ +void add_identities(pset *value_table, ir_node *node) { + if (get_opt_cse() && is_no_Block(node)) + identify_remember(value_table, node); +} + +/* Visit each node in the value table of a graph. */ +void visit_all_identities(ir_graph *irg, irg_walk_func visit, void *env) { + ir_node *node; + ir_graph *rem = current_ir_graph; + + current_ir_graph = irg; + foreach_pset(irg->value_table, node) + visit(node, env); + current_ir_graph = rem; } /** * garbage in, garbage out. If a node has a dead input, i.e., the * Bad node is input to the node, return the Bad node. */ -static INLINE ir_node * -gigo (ir_node *node) +static INLINE ir_node *gigo(ir_node *node) { int i, irn_arity; ir_op *op = get_irn_op(node); @@ -3527,7 +3601,6 @@ gigo (ir_node *node) return node; } - /** * These optimizations deallocate nodes from the obstack. * It can only be called if it is guaranteed that no other nodes @@ -3535,8 +3608,7 @@ gigo (ir_node *node) * * current_ir_graph must be set to the graph of the node! */ -ir_node * -optimize_node(ir_node *n) +ir_node *optimize_node(ir_node *n) { tarval *tv; ir_node *oldn = n; @@ -3646,8 +3718,7 @@ optimize_node(ir_node *n) * nodes lying on the obstack. Remove these by a dead node elimination, * i.e., a copying garbage collection. */ -ir_node * -optimize_in_place_2 (ir_node *n) +ir_node *optimize_in_place_2(ir_node *n) { tarval *tv; ir_node *oldn = n; @@ -3729,8 +3800,7 @@ optimize_in_place_2 (ir_node *n) /** * Wrapper for external use, set proper status bits after optimization. */ -ir_node * -optimize_in_place (ir_node *n) +ir_node *optimize_in_place(ir_node *n) { /* Handle graph state */ assert(get_irg_phase_state(current_ir_graph) != phase_building);