Remove .*_ptr variants of firm-types
[libfirm] / ir / ir / iropt.c
index 2ca74a4..ec61a82 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"
@@ -588,6 +586,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;
 }
@@ -720,16 +727,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 +766,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
 }
@@ -1608,16 +1604,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 +1642,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
 }
@@ -4080,27 +4065,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 +4095,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);
                        }
                }
        }
@@ -4685,7 +4666,7 @@ is_bittest: {
                                        } else {
                                                dbg_info *dbgi  = get_irn_dbg_info(n);
                                                ir_node  *block = get_nodes_block(n);
-                                               ir_node  *notn  =  new_rd_Not(dbgi, block, cond, mode_b);
+                                               ir_node  *notn  = new_rd_Not(dbgi, block, cond, mode_b);
                                                return notn;
                                        }
                                }
@@ -5278,9 +5259,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 +5347,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;
 }
 
 /**
@@ -5890,6 +5868,92 @@ bool ir_is_optimizable_mux(const ir_node *sel, const ir_node *mux_false,
        return false;
 }
 
+/**
+ * Optimize a Mux(c, 0, 1) node (sometimes called a "set" instruction)
+ */
+static ir_node *transform_Mux_set(ir_node *n)
+{
+       ir_node    *cond = get_Mux_sel(n);
+       ir_mode    *dest_mode;
+       ir_mode    *mode;
+       ir_node    *left;
+       ir_node    *right;
+       ir_relation relation;
+       bool        need_not;
+       dbg_info   *dbgi;
+       ir_node    *block;
+       ir_graph   *irg;
+       ir_node    *a;
+       ir_node    *b;
+       unsigned    bits;
+       ir_tarval  *tv;
+       ir_node    *shift_cnt;
+       ir_node    *res;
+
+       if (!is_Cmp(cond))
+               return n;
+       left = get_Cmp_left(cond);
+       mode = get_irn_mode(left);
+       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)
+                && relation != ir_relation_greater))
+           return n;
+
+       need_not = false;
+       switch (relation) {
+       case ir_relation_less:
+               /* a < b  ->  (a - b) >> 31 */
+               a = left;
+               b = right;
+               break;
+       case ir_relation_less_equal:
+               /* a <= b  -> ~(a - b) >> 31 */
+               a        = right;
+               b        = left;
+               need_not = true;
+               break;
+       case ir_relation_greater:
+               /* a > b   -> (b - a) >> 31 */
+               a = right;
+               b = left;
+               break;
+       case ir_relation_greater_equal:
+               /* a >= b   -> ~(a - b) >> 31 */
+               a        = left;
+               b        = right;
+               need_not = true;
+               break;
+       default:
+               return n;
+       }
+
+       dbgi      = get_irn_dbg_info(n);
+       block     = get_nodes_block(n);
+       irg       = get_irn_irg(block);
+       bits      = get_mode_size_bits(dest_mode);
+       tv        = new_tarval_from_long(bits-1, mode_Iu);
+       shift_cnt = new_rd_Const(dbgi, irg, tv);
+
+       if (mode != dest_mode) {
+               a = new_rd_Conv(dbgi, block, a, dest_mode);
+               b = new_rd_Conv(dbgi, block, b, dest_mode);
+       }
+
+       res = new_rd_Sub(dbgi, block, a, b, dest_mode);
+       if (need_not) {
+               res = new_rd_Not(dbgi, block, res, dest_mode);
+       }
+       res = new_rd_Shr(dbgi, block, res, shift_cnt, dest_mode);
+       return res;
+}
+
 /**
  * Optimize a Mux into some simpler cases.
  */
@@ -5938,7 +6002,13 @@ 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)) {
+               n = transform_Mux_set(n);
+               if (n != oldn)
+                       return n;
        }
 
        /* the following optimisations create new mode_b nodes, so only do them
@@ -5952,23 +6022,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);
@@ -5978,23 +6040,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);
                        }
                }
 
@@ -6035,28 +6089,6 @@ static ir_node *transform_node_Mux(ir_node *n)
                                }
                        }
                }
-
-               /* more normalization: Mux(sel, 0, 1) is simply a conv from the mode_b
-                * value to integer. */
-               if (is_Const(t) && is_Const(f) && mode_is_int(mode)) {
-                       ir_tarval *a = get_Const_tarval(t);
-                       ir_tarval *b = get_Const_tarval(f);
-
-                       if (tarval_is_one(a) && tarval_is_null(b)) {
-                               ir_node *block = get_nodes_block(n);
-                               ir_node *conv  = new_r_Conv(block, sel, mode);
-                               n = conv;
-                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_CONV);
-                               return n;
-                       } else if (tarval_is_null(a) && tarval_is_one(b)) {
-                               ir_node *block = get_nodes_block(n);
-                               ir_node *not_  = new_r_Not(block, sel, mode_b);
-                               ir_node *conv  = new_r_Conv(block, not_, mode);
-                               n = conv;
-                               DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_CONV);
-                               return n;
-                       }
-               }
        }
 
        if (is_Cmp(sel) && mode_is_int(mode) && is_cmp_equality_zero(sel)) {
@@ -6301,40 +6333,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:                                       \
@@ -6368,7 +6367,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);
@@ -6384,13 +6382,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 **************** */
 
@@ -6450,7 +6502,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);
 }
@@ -6576,7 +6628,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;
@@ -6639,16 +6692,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:                              \
@@ -6682,8 +6726,6 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
                /* leave NULL */
                break;
        }
-
-       return ops;
 #undef CASE
 }
 
@@ -6956,12 +6998,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)
@@ -6979,67 +7022,40 @@ ir_node *optimize_node(ir_node *n)
  */
 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)
@@ -7093,16 +7109,7 @@ static unsigned hash_SymConst(const ir_node *node)
        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:                                  \
@@ -7111,7 +7118,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);
@@ -7120,23 +7127,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;
-}