Use be_emit_irprintf("%T", x) instead of be_emit_tarval().
[libfirm] / ir / ir / iropt.c
index 67da26e..bd60eb8 100644 (file)
@@ -21,7 +21,6 @@
  * @file
  * @brief   iropt --- optimizations intertwined with IR construction.
  * @author  Christian Schaefer, Goetz Lindenmaier, Michael Beck
- * @version $Id$
  */
 #include "config.h"
 
@@ -44,7 +43,6 @@
 #include "irhooks.h"
 #include "irarch.h"
 #include "hashptr.h"
-#include "opt_polymorphy.h"
 #include "irtools.h"
 #include "irhooks.h"
 #include "array_t.h"
@@ -53,7 +51,6 @@
 #include "bitfiddle.h"
 #include "be.h"
 
-/* Make types visible to allow most efficient access */
 #include "entity_t.h"
 
 static bool is_Or_Eor_Add(const ir_node *node)
@@ -85,7 +82,6 @@ static ir_tarval *default_value_of(const ir_node *n)
 
 value_of_func value_of_ptr = default_value_of;
 
-/* * Set a new value_of function. */
 void set_value_of_func(value_of_func func)
 {
        if (func != NULL)
@@ -588,6 +584,15 @@ ir_relation ir_get_possible_cmp_relations(const ir_node *left,
        /* Alloc nodes never return null (but throw an exception) */
        if (is_Alloc(left) && tarval_is_null(tv_r))
                possible &= ~ir_relation_equal;
+       /* stuff known through confirm nodes */
+       if (is_Confirm(left) && get_Confirm_bound(left) == right) {
+               possible &= get_Confirm_relation(left);
+       }
+       if (is_Confirm(right) && get_Confirm_bound(right) == left) {
+               ir_relation relation = get_Confirm_relation(right);
+               relation = get_inversed_relation(relation);
+               possible &= relation;
+       }
 
        return possible;
 }
@@ -609,6 +614,17 @@ static ir_tarval *compute_cmp(const ir_node *cmp)
        return computed_value_Cmp_Confirm(cmp, left, right, relation);
 }
 
+/**
+ * some people want to call compute_cmp directly, in this case we have to
+ * test the constant folding flag again
+ */
+static ir_tarval *compute_cmp_ext(const ir_node *cmp)
+{
+       if (!get_opt_constant_folding())
+               return tarval_bad;
+       return compute_cmp(cmp);
+}
+
 /**
  * Return the value of a Cmp.
  *
@@ -720,16 +736,7 @@ ir_tarval *computed_value(const ir_node *n)
        return tarval_bad;
 }
 
-/**
- * Set the default computed_value evaluator in an ir_op_ops.
- *
- * @param code   the opcode for the default operation
- * @param ops    the operations initialized
- *
- * @return
- *    The operations.
- */
-static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops)
+void firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                                        \
        case iro_##a:                                      \
@@ -768,8 +775,6 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
                /* leave NULL */
                break;
        }
-
-       return ops;
 #undef CASE_PROJ
 #undef CASE
 }
@@ -1477,7 +1482,7 @@ static ir_node *equivalent_node_Mux(ir_node *n)
        if (ts == tarval_bad && is_Cmp(sel)) {
                /* try again with a direct call to compute_cmp, as we don't care
                 * about the MODEB_LOWERED flag here */
-               ts = compute_cmp(sel);
+               ts = compute_cmp_ext(sel);
        }
 
        /* Mux(true, f, t) == t */
@@ -1608,16 +1613,7 @@ ir_node *equivalent_node(ir_node *n)
        return n;
 }
 
-/**
- * Sets the default equivalent node operation for an ir_op_ops.
- *
- * @param code   the opcode for the default operation
- * @param ops    the operations initialized
- *
- * @return
- *    The operations.
- */
-static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *ops)
+void firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                                      \
        case iro_##a:                                    \
@@ -1655,8 +1651,6 @@ static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *op
                /* leave NULL */
                break;
        }
-
-       return ops;
 #undef CASE
 #undef CASE_PROJ
 }
@@ -3556,7 +3550,7 @@ static ir_node *transform_node_Cond(ir_node *n)
        if (ta == tarval_bad && is_Cmp(a)) {
                /* try again with a direct call to compute_cmp, as we don't care
                 * about the MODEB_LOWERED flag here */
-               ta = compute_cmp(a);
+               ta = compute_cmp_ext(a);
        }
 
        if (ta != tarval_bad && get_irn_mode(a) == mode_b) {
@@ -4080,27 +4074,25 @@ static ir_node *transform_node_Minus(ir_node *n)
  */
 static ir_node *transform_node_Proj_Load(ir_node *proj)
 {
-       if (get_opt_ldst_only_null_ptr_exceptions()) {
-               if (get_irn_mode(proj) == mode_X) {
-                       ir_node *load = get_Proj_pred(proj);
+       if (get_irn_mode(proj) == mode_X) {
+               ir_node *load = get_Proj_pred(proj);
 
-                       /* get the Load address */
-                       const ir_node *addr = get_Load_ptr(load);
-                       const ir_node *confirm;
+               /* get the Load address */
+               const ir_node *addr = get_Load_ptr(load);
+               const ir_node *confirm;
 
-                       if (value_not_null(addr, &confirm)) {
-                               if (confirm == NULL) {
-                                       /* this node may float if it did not depend on a Confirm */
-                                       set_irn_pinned(load, op_pin_state_floats);
-                               }
-                               if (get_Proj_proj(proj) == pn_Load_X_except) {
-                                       ir_graph *irg = get_irn_irg(proj);
-                                       DBG_OPT_EXC_REM(proj);
-                                       return new_r_Bad(irg, mode_X);
-                               } else {
-                                       ir_node *blk = get_nodes_block(load);
-                                       return new_r_Jmp(blk);
-                               }
+               if (value_not_null(addr, &confirm)) {
+                       if (confirm == NULL) {
+                               /* this node may float if it did not depend on a Confirm */
+                               set_irn_pinned(load, op_pin_state_floats);
+                       }
+                       if (get_Proj_proj(proj) == pn_Load_X_except) {
+                               ir_graph *irg = get_irn_irg(proj);
+                               DBG_OPT_EXC_REM(proj);
+                               return new_r_Bad(irg, mode_X);
+                       } else {
+                               ir_node *blk = get_nodes_block(load);
+                               return new_r_Jmp(blk);
                        }
                }
        }
@@ -4112,27 +4104,25 @@ static ir_node *transform_node_Proj_Load(ir_node *proj)
  */
 static ir_node *transform_node_Proj_Store(ir_node *proj)
 {
-       if (get_opt_ldst_only_null_ptr_exceptions()) {
-               if (get_irn_mode(proj) == mode_X) {
-                       ir_node *store = get_Proj_pred(proj);
+       if (get_irn_mode(proj) == mode_X) {
+               ir_node *store = get_Proj_pred(proj);
 
-                       /* get the load/store address */
-                       const ir_node *addr = get_Store_ptr(store);
-                       const ir_node *confirm;
+               /* get the load/store address */
+               const ir_node *addr = get_Store_ptr(store);
+               const ir_node *confirm;
 
-                       if (value_not_null(addr, &confirm)) {
-                               if (confirm == NULL) {
-                                       /* this node may float if it did not depend on a Confirm */
-                                       set_irn_pinned(store, op_pin_state_floats);
-                               }
-                               if (get_Proj_proj(proj) == pn_Store_X_except) {
-                                       ir_graph *irg = get_irn_irg(proj);
-                                       DBG_OPT_EXC_REM(proj);
-                                       return new_r_Bad(irg, mode_X);
-                               } else {
-                                       ir_node *blk = get_nodes_block(store);
-                                       return new_r_Jmp(blk);
-                               }
+               if (value_not_null(addr, &confirm)) {
+                       if (confirm == NULL) {
+                               /* this node may float if it did not depend on a Confirm */
+                               set_irn_pinned(store, op_pin_state_floats);
+                       }
+                       if (get_Proj_proj(proj) == pn_Store_X_except) {
+                               ir_graph *irg = get_irn_irg(proj);
+                               DBG_OPT_EXC_REM(proj);
+                               return new_r_Bad(irg, mode_X);
+                       } else {
+                               ir_node *blk = get_nodes_block(store);
+                               return new_r_Jmp(blk);
                        }
                }
        }
@@ -5278,9 +5268,6 @@ static ir_node *transform_node_Phi(ir_node *phi)
        return phi;
 }
 
-/* forward */
-static ir_node *transform_node(ir_node *n);
-
 /**
  * Optimize (a >> c1) >> c2), works for Shr, Shrs, Shl, Rotl.
  *
@@ -5369,7 +5356,7 @@ static ir_node *transform_node_shift(ir_node *n)
 
        DBG_OPT_ALGSIM0(n, irn, FS_OPT_REASSOC_SHIFT);
 
-       return transform_node(irn);
+       return irn;
 }
 
 /**
@@ -5919,10 +5906,13 @@ static ir_node *transform_Mux_set(ir_node *n)
        if (!mode_is_int(mode) && !mode_is_reference(mode))
                return n;
        dest_mode = get_irn_mode(n);
+       if (!mode_is_int(dest_mode) && !mode_is_reference(dest_mode))
+               return n;
        right     = get_Cmp_right(cond);
        relation  = get_Cmp_relation(cond) & ~ir_relation_unordered;
        if (get_mode_size_bits(mode) >= get_mode_size_bits(dest_mode)
-           && (!mode_is_signed(mode) || !is_Const(right) || !is_Const_null(right)))
+           && !(mode_is_signed(mode) && is_Const(right) && is_Const_null(right)
+                && relation != ir_relation_greater))
            return n;
 
        need_not = false;
@@ -6021,7 +6011,7 @@ static ir_node *transform_node_Mux(ir_node *n)
                relation = get_negated_relation(relation);
                sel = new_rd_Cmp(seldbgi, block, get_Cmp_left(sel),
                                get_Cmp_right(sel), relation);
-               n = new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
+               return new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
        }
 
        if (is_Const(f) && is_Const_null(f) && is_Const(t) && is_Const_one(t)) {
@@ -6041,23 +6031,15 @@ static ir_node *transform_node_Mux(ir_node *n)
                        ir_node*  f1    = get_Mux_false(t);
                        if (f == f1) {
                                /* Mux(cond0, Mux(cond1, x, y), y) => Mux(cond0 && cond1, x, y) */
-                               ir_node* and_    = new_r_And(block, c0, c1, mode_b);
-                               ir_node* new_mux = new_r_Mux(block, and_, f1, t1, mode);
-                               n   = new_mux;
-                               sel = and_;
-                               f   = f1;
-                               t   = t1;
-                               DBG_OPT_ALGSIM0(oldn, t, FS_OPT_MUX_COMBINE);
+                               ir_node* and_ = new_r_And(block, c0, c1, mode_b);
+                               DBG_OPT_ALGSIM0(oldn, t1, FS_OPT_MUX_COMBINE);
+                               return new_r_Mux(block, and_, f1, t1, mode);
                        } else if (f == t1) {
                                /* Mux(cond0, Mux(cond1, x, y), x) */
                                ir_node* not_c1  = new_r_Not(block, c1, mode_b);
                                ir_node* and_    = new_r_And(block, c0, not_c1, mode_b);
-                               ir_node* new_mux = new_r_Mux(block, and_, t1, f1, mode);
-                               n   = new_mux;
-                               sel = and_;
-                               f   = t1;
-                               t   = f1;
-                               DBG_OPT_ALGSIM0(oldn, t, FS_OPT_MUX_COMBINE);
+                               DBG_OPT_ALGSIM0(oldn, f1, FS_OPT_MUX_COMBINE);
+                               return new_r_Mux(block, and_, t1, f1, mode);
                        }
                } else if (is_Mux(f)) {
                        ir_node*  block = get_nodes_block(n);
@@ -6067,23 +6049,15 @@ static ir_node *transform_node_Mux(ir_node *n)
                        ir_node*  f1    = get_Mux_false(f);
                        if (t == t1) {
                                /* Mux(cond0, x, Mux(cond1, x, y)) -> typical if (cond0 || cond1) x else y */
-                               ir_node* or_     = new_r_Or(block, c0, c1, mode_b);
-                               ir_node* new_mux = new_r_Mux(block, or_, f1, t1, mode);
-                               n   = new_mux;
-                               sel = or_;
-                               f   = f1;
-                               t   = t1;
-                               DBG_OPT_ALGSIM0(oldn, f, FS_OPT_MUX_COMBINE);
+                               ir_node* or_ = new_r_Or(block, c0, c1, mode_b);
+                               DBG_OPT_ALGSIM0(oldn, f1, FS_OPT_MUX_COMBINE);
+                               return new_r_Mux(block, or_, f1, t1, mode);
                        } else if (t == f1) {
                                /* Mux(cond0, x, Mux(cond1, y, x)) */
                                ir_node* not_c1  = new_r_Not(block, c1, mode_b);
                                ir_node* or_     = new_r_Or(block, c0, not_c1, mode_b);
-                               ir_node* new_mux = new_r_Mux(block, or_, t1, f1, mode);
-                               n   = new_mux;
-                               sel = or_;
-                               f   = t1;
-                               t   = f1;
-                               DBG_OPT_ALGSIM0(oldn, f, FS_OPT_MUX_COMBINE);
+                               DBG_OPT_ALGSIM0(oldn, t1, FS_OPT_MUX_COMBINE);
+                               return new_r_Mux(block, or_, t1, f1, mode);
                        }
                }
 
@@ -6368,40 +6342,7 @@ static ir_node *transform_node_Call(ir_node *call)
        return res;
 }
 
-/**
- * Tries several [inplace] [optimizing] transformations and returns an
- * equivalent node.  The difference to equivalent_node() is that these
- * transformations _do_ generate new nodes, and thus the old node must
- * not be freed even if the equivalent node isn't the old one.
- */
-static ir_node *transform_node(ir_node *n)
-{
-       ir_node *oldn;
-
-       /*
-        * Transform_node is the only "optimizing transformation" that might
-        * return a node with a different opcode. We iterate HERE until fixpoint
-        * to get the final result.
-        */
-       do {
-               oldn = n;
-               if (n->op->ops.transform_node != NULL)
-                       n = n->op->ops.transform_node(n);
-       } while (oldn != n);
-
-       return n;
-}
-
-/**
- * Sets the default transform node operation for an ir_op_ops.
- *
- * @param code   the opcode for the default operation
- * @param ops    the operations initialized
- *
- * @return
- *    The operations.
- */
-static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops)
+void firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                                         \
        case iro_##a:                                       \
@@ -6435,7 +6376,6 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops
        CASE(Phi);
        CASE(Proj);
        CASE(Rotl);
-       CASE(Sel);
        CASE(Shl);
        CASE(Shr);
        CASE(Shrs);
@@ -6451,13 +6391,67 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops
        default:
                break;
        }
-
-       return ops;
 #undef CASE_PROJ_EX
 #undef CASE_PROJ
 #undef CASE
 }
 
+/**
+ * Tries several [inplace] [optimizing] transformations and returns an
+ * equivalent node.  The difference to equivalent_node() is that these
+ * transformations _do_ generate new nodes, and thus the old node must
+ * not be freed even if the equivalent node isn't the old one.
+ */
+static ir_node *transform_node(ir_node *n)
+{
+       ir_node *old_n;
+       unsigned iro;
+restart:
+       old_n = n;
+       iro   = get_irn_opcode_(n);
+       /* constant expression evaluation / constant folding */
+       if (get_opt_constant_folding()) {
+               /* neither constants nor Tuple values can be evaluated */
+               if (iro != iro_Const && get_irn_mode(n) != mode_T) {
+                       /* try to evaluate */
+                       ir_tarval *tv = computed_value(n);
+                       if (tv != tarval_bad) {
+                               /* evaluation was successful -- replace the node. */
+                               ir_graph *irg = get_irn_irg(n);
+
+                               n = new_r_Const(irg, tv);
+
+                               DBG_OPT_CSTEVAL(old_n, n);
+                               return n;
+                       }
+               }
+       }
+
+       /* remove unnecessary nodes */
+       if (get_opt_constant_folding() ||
+               (iro == iro_Phi)  ||   /* always optimize these nodes. */
+               (iro == iro_Id)   ||   /* ... */
+               (iro == iro_Proj) ||   /* ... */
+               (iro == iro_Block)) {  /* Flags tested local. */
+               n = equivalent_node(n);
+               if (n != old_n)
+                       goto restart;
+       }
+
+       /* Some more constant expression evaluation. */
+       if (get_opt_algebraic_simplification() ||
+               (iro == iro_Cond) ||
+               (iro == iro_Proj)) {    /* Flags tested local. */
+               if (n->op->ops.transform_node != NULL) {
+                       n = n->op->ops.transform_node(n);
+                       if (n != old_n) {
+                               goto restart;
+                       }
+               }
+       }
+
+       return n;
+}
 
 /* **************** Common Subexpression Elimination **************** */
 
@@ -6517,7 +6511,7 @@ static int node_cmp_attr_Call(const ir_node *a, const ir_node *b)
 {
        const call_attr *pa = &a->attr.call;
        const call_attr *pb = &b->attr.call;
-       if (pa->type != pb->type || pa->tail_call != pb->tail_call)
+       if (pa->type != pb->type)
                return 1;
        return node_cmp_exception(a, b);
 }
@@ -6533,11 +6527,11 @@ static int node_cmp_attr_Sel(const ir_node *a, const ir_node *b)
 /** Compares the attributes of two Phi nodes. */
 static int node_cmp_attr_Phi(const ir_node *a, const ir_node *b)
 {
-       /* we can only enter this function if both nodes have the same number of inputs,
-          hence it is enough to check if one of them is a Phi0 */
-       if (is_Phi0(a)) {
-               /* check the Phi0 pos attribute */
-               return a->attr.phi.u.pos != b->attr.phi.u.pos;
+       (void) b;
+       /* do not CSE Phi-nodes without any inputs when building new graphs */
+       if (get_irn_arity(a) == 0 &&
+           get_irg_phase_state(get_irn_irg(a)) == phase_building) {
+           return 1;
        }
        return 0;
 }
@@ -6643,7 +6637,8 @@ static int node_cmp_attr_Builtin(const ir_node *a, const ir_node *b)
 /** Compares the attributes of two ASM nodes. */
 static int node_cmp_attr_ASM(const ir_node *a, const ir_node *b)
 {
-       int i, n;
+       size_t n;
+       size_t i;
        const ir_asm_constraint *ca;
        const ir_asm_constraint *cb;
        ident **cla, **clb;
@@ -6706,16 +6701,7 @@ static int node_cmp_attr_InstOf(const ir_node *a, const ir_node *b)
        return node_cmp_exception(a, b);
 }
 
-/**
- * Set the default node attribute compare operation for an ir_op_ops.
- *
- * @param code   the opcode for the default operation
- * @param ops    the operations initialized
- *
- * @return
- *    The operations.
- */
-static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
+void firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                              \
        case iro_##a:                              \
@@ -6749,15 +6735,9 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
                /* leave NULL */
                break;
        }
-
-       return ops;
 #undef CASE
 }
 
-/*
- * Compare function for two nodes in the value table. Gets two
- * nodes as parameters.  Returns 0 if the nodes are a Common Sub Expression.
- */
 int identities_cmp(const void *elt, const void *key)
 {
        ir_node *a = (ir_node *)elt;
@@ -6822,17 +6802,11 @@ int identities_cmp(const void *elt, const void *key)
        return 0;
 }
 
-/*
- * Calculate a hash value of a node.
- *
- * @param node  The IR-node
- */
 unsigned ir_node_hash(const ir_node *node)
 {
        return node->op->ops.hash(node);
 }
 
-
 void new_identities(ir_graph *irg)
 {
        if (irg->value_table != NULL)
@@ -6846,8 +6820,6 @@ void del_identities(ir_graph *irg)
                del_pset(irg->value_table);
 }
 
-/* Normalize a node by putting constants (and operands with larger
- * node index) on the right (operator side). */
 void ir_normalize_node(ir_node *n)
 {
        if (is_op_commutative(get_irn_op(n))) {
@@ -6866,16 +6838,6 @@ void ir_normalize_node(ir_node *n)
        }
 }
 
-/*
- * Return the canonical node computing the same value as n.
- * Looks up the node in a hash table, enters it in the table
- * if it isn't there yet.
- *
- * @param n            the node to look up
- *
- * @return a node that computes the same value as n or n if no such
- *         node could be found
- */
 ir_node *identify_remember(ir_node *n)
 {
        ir_graph *irg         = get_irn_irg(n);
@@ -6916,7 +6878,6 @@ static inline ir_node *identify_cons(ir_node *n)
        return n;
 }
 
-/* Add a node to the identities value table. */
 void add_identities(ir_node *node)
 {
        if (!get_opt_cse())
@@ -6927,7 +6888,6 @@ void add_identities(ir_node *node)
        identify_remember(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;
@@ -6940,13 +6900,6 @@ void visit_all_identities(ir_graph *irg, irg_walk_func visit, void *env)
        current_ir_graph = rem;
 }
 
-/**
- * These optimizations deallocate nodes from the obstack.
- * It can only be called if it is guaranteed that no other nodes
- * reference this one, i.e., right after construction of a node.
- *
- * @param n   The node to optimize
- */
 ir_node *optimize_node(ir_node *n)
 {
        ir_node   *oldn = n;
@@ -7023,12 +6976,13 @@ ir_node *optimize_node(ir_node *n)
           free the node. */
        iro = get_irn_opcode(n);
        if (get_opt_algebraic_simplification() ||
-           (iro == iro_Cond) ||
-           (iro == iro_Proj))     /* Flags tested local. */
+               (iro == iro_Cond) ||
+               (iro == iro_Proj)) {    /* Flags tested local. */
                n = transform_node(n);
+       }
 
        /* Now we have a legal, useful node. Enter it in hash table for CSE */
-       if (get_opt_cse() && (get_irn_opcode(n) != iro_Block)) {
+       if (get_opt_cse()) {
                ir_node *o = n;
                n = identify_remember(o);
                if (o != n)
@@ -7038,75 +6992,42 @@ ir_node *optimize_node(ir_node *n)
        return n;
 }
 
-
-/**
- * These optimizations never deallocate nodes (in place).  This can cause dead
- * 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_tarval *tv;
-       ir_node   *oldn = n;
-       unsigned   iro  = get_irn_opcode(n);
-
        if (!get_opt_optimize() && !is_Phi(n)) return n;
 
-       if (iro == iro_Deleted)
+       if (is_Deleted(n))
                return n;
 
-       /* constant expression evaluation / constant folding */
-       if (get_opt_constant_folding()) {
-               /* neither constants nor Tuple values can be evaluated */
-               if (iro != iro_Const && get_irn_mode(n) != mode_T) {
-                       /* try to evaluate */
-                       tv = computed_value(n);
-                       if (tv != tarval_bad) {
-                               /* evaluation was successful -- replace the node. */
-                               ir_graph *irg = get_irn_irg(n);
-
-                               n = new_r_Const(irg, tv);
-
-                               DBG_OPT_CSTEVAL(oldn, n);
-                               return n;
-                       }
-               }
-       }
-
-       /* remove unnecessary nodes */
-       if (get_opt_constant_folding() ||
-           (iro == iro_Phi)  ||   /* always optimize these nodes. */
-           (iro == iro_Id)   ||   /* ... */
-           (iro == iro_Proj) ||   /* ... */
-           (iro == iro_Block)  )  /* Flags tested local. */
-               n = equivalent_node(n);
-
        /** common subexpression elimination **/
        /* Checks whether n is already available. */
-       /* The block input is used to distinguish different subexpressions.  Right
-          now all nodes are op_pin_state_pinned to blocks, i.e., the cse only finds common
-          subexpressions within a block. */
+       /* The block input is used to distinguish different subexpressions.
+        * Right now all nodes are op_pin_state_pinned to blocks, i.e., the cse
+        * only finds common subexpressions within a block. */
        if (get_opt_cse()) {
                ir_node *o = n;
-               n = identify_remember(o);
-               if (o != n)
+               n = identify_remember(n);
+               if (n != o) {
                        DBG_OPT_CSE(o, n);
+                       /* we have another existing node now, we do not optimize it here */
+                       return n;
+               }
        }
 
-       /* Some more constant expression evaluation. */
-       iro = get_irn_opcode(n);
-       if (get_opt_constant_folding() ||
-               (iro == iro_Cond) ||
-               (iro == iro_Proj))     /* Flags tested local. */
-               n = transform_node(n);
+       n = transform_node(n);
 
        /* Now we can verify the node, as it has no dead inputs any more. */
        irn_verify(n);
 
        /* 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)) {
+        * Blocks should be unique anyways.  (Except the successor of start:
+        * is cse with the start block!)
+        *
+        * Note: This is only necessary because some of the optimisations
+        * operate in-place (set_XXX_bla, turn_into_tuple, ...) which is considered
+        * bad practice and should be fixed sometime.
+        */
+       if (get_opt_cse()) {
                ir_node *o = n;
                n = identify_remember(o);
                if (o != n)
@@ -7116,9 +7037,6 @@ ir_node *optimize_in_place_2(ir_node *n)
        return n;
 }
 
-/**
- * Wrapper for external use, set proper status bits after optimization.
- */
 ir_node *optimize_in_place(ir_node *n)
 {
        ir_graph *irg = get_irn_irg(n);
@@ -7142,7 +7060,7 @@ static unsigned hash_Const(const ir_node *node)
        unsigned h;
 
        /* special value for const, as they only differ in their tarval. */
-       h = HASH_PTR(node->attr.con.tarval);
+       h = hash_ptr(node->attr.con.tarval);
 
        return h;
 }
@@ -7155,21 +7073,12 @@ static unsigned hash_SymConst(const ir_node *node)
        unsigned h;
 
        /* all others are pointers */
-       h = HASH_PTR(node->attr.symc.sym.type_p);
+       h = hash_ptr(node->attr.symc.sym.type_p);
 
        return h;
 }
 
-/**
- * Set the default hash operation in an ir_op_ops.
- *
- * @param code   the opcode for the default operation
- * @param ops    the operations initialized
- *
- * @return
- *    The operations.
- */
-static ir_op_ops *firm_set_default_hash(unsigned code, ir_op_ops *ops)
+void firm_set_default_hash(unsigned code, ir_op_ops *ops)
 {
 #define CASE(a)                                    \
        case iro_##a:                                  \
@@ -7178,7 +7087,7 @@ static ir_op_ops *firm_set_default_hash(unsigned code, ir_op_ops *ops)
 
        /* hash function already set */
        if (ops->hash != NULL)
-               return ops;
+               return;
 
        switch (code) {
        CASE(Const);
@@ -7187,23 +7096,5 @@ static ir_op_ops *firm_set_default_hash(unsigned code, ir_op_ops *ops)
                /* use input/mode default hash if no function was given */
                ops->hash = firm_default_hash;
        }
-
-       return ops;
 #undef CASE
 }
-
-/*
- * Sets the default operation for an ir_ops.
- */
-ir_op_ops *firm_set_default_operations(unsigned code, ir_op_ops *ops)
-{
-       ops = firm_set_default_hash(code, ops);
-       ops = firm_set_default_computed_value(code, ops);
-       ops = firm_set_default_equivalent_node(code, ops);
-       ops = firm_set_default_transform_node(code, ops);
-       ops = firm_set_default_node_cmp_attr(code, ops);
-       ops = firm_set_default_get_type_attr(code, ops);
-       ops = firm_set_default_get_entity_attr(code, ops);
-
-       return ops;
-}