Added mode_sort prefix irms_, added new_ir_mode() function.
[libfirm] / ir / ir / iropt.c
index b2c506f..b5e5526 100644 (file)
@@ -1,9 +1,9 @@
 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
-** All rights reserved.
-**
-** Authors: Christian Schaefer, Goetz Lindenmaier
-**
-** iropt --- optimizations intertwined with IR construction.
+* All rights reserved.
+*
+* Authors: Christian Schaefer, Goetz Lindenmaier
+*
+* iropt --- optimizations intertwined with IR construction.
 */
 
 /* $Id$ */
 # include "tv.h"
 # include "tune.h"
 # include "dbginfo_t.h"
+# include "iropt_dbg.c"
 
 /* Make types visible to allow most efficient access */
 # include "entity_t.h"
 
-/* Trivial inlineable routine for copy propagation.
-   Does follow Ids, needed to optimize inlined code. */
-static inline ir_node *
+/* Trivial INLINEable routine for copy propagation.
+   Does follow Ids, needed to optimize INLINEd code. */
+static INLINE ir_node *
 follow_Id (ir_node *n)
 {
   while (get_irn_op (n) == op_Id) n = get_Id_pred (n);
   return n;
 }
 
-static inline tarval *
+static INLINE tarval *
 value_of (ir_node *n)
 {
   if ((n != NULL) && (get_irn_op(n) == op_Const))
-    return get_Const_tarval(n);
+    return get_Const_tarval(n); /* might return tarval_bad */
   else
-    return NULL;
+    return tarval_bad;
 }
 
 /* if n can be computed, return the value, else NULL. Performs
@@ -51,9 +52,10 @@ computed_value (ir_node *n)
   tarval *res;
 
   ir_node *a = NULL, *b = NULL;         /* initialized to shut up gcc */
-  tarval *ta = NULL, *tb = NULL; /* initialized to shut up gcc */
+  /* initialized to uniformly filter invalid constants */
+  tarval *ta = tarval_bad, *tb = tarval_bad;
 
-  res = NULL;
+  res = tarval_bad;
 
   /* get the operands we will work on for simple cases. */
   if (is_binop(n)) {
@@ -76,79 +78,83 @@ computed_value (ir_node *n)
   case iro_SymConst:
     if ((get_SymConst_kind(n) == size) &&
        (get_type_state(get_SymConst_type(n))) == layout_fixed)
-      res = tarval_from_long (mode_i, get_type_size(get_SymConst_type(n)));
+      res = new_tarval_from_long (get_type_size(get_SymConst_type(n)), mode_Is);
     break;
   case iro_Add:
-    if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
-       && (get_irn_mode(a) != mode_p)) {
+    if ((ta != tarval_bad) && (tb != tarval_bad)
+          && (get_irn_mode(a) == get_irn_mode(b))
+          && !(get_mode_sort(get_irn_mode(a)) == irms_reference)) {
       res = tarval_add (ta, tb);
     }
     break;
   case iro_Sub:
-    if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
-       && (get_irn_mode(a) != mode_p)) {
+    if ((ta != tarval_bad) && (tb != tarval_bad)
+          && (get_irn_mode(a) == get_irn_mode(b))
+          && !(get_mode_sort(get_irn_mode(a)) == irms_reference)) {
       res = tarval_sub (ta, tb);
-    } else if (a == b) {
-      res = tarval_mode_null [get_irn_modecode (n)];
     }
     break;
   case iro_Minus:
-      if (ta && mode_is_float(get_irn_mode(a)))
+      if ((ta != tarval_bad) && mode_is_signed(get_irn_mode(a)))
         res = tarval_neg (ta);
     break;
   case iro_Mul:
-    if (ta && tb) /* tarval_mul tests for equivalent modes itself */ {
+    if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
       res = tarval_mul (ta, tb);
     } else {
       /* a*0 = 0 or 0*b = 0:
         calls computed_value recursive and returns the 0 with proper
          mode. */
       tarval *v;
-      if (   (tarval_classify ((v = computed_value (a))) == 0)
-         || (tarval_classify ((v = computed_value (b))) == 0)) {
+      if ( ( ((v = computed_value (a)) != tarval_bad)
+               && (v == get_mode_null(get_tarval_mode(v))) )
+       || ( ((v = computed_value (b)) != tarval_bad)
+               && (v == get_mode_null(get_tarval_mode(v))) )) {
        res = v;
       }
     }
     break;
   case iro_Quot:
     /* This was missing in original implementation. Why? */
-    if (ta && tb  && (get_irn_mode(a) == get_irn_mode(b))) {
-      if (tarval_classify(tb) == 0) {res = NULL; break;}
+    if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
+      if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
       res = tarval_quo(ta, tb);
     }
     break;
   case iro_Div:
     /* This was missing in original implementation. Why? */
-    if (ta && tb  && (get_irn_mode(a) == get_irn_mode(b))) {
-      if (tarval_classify(tb) == 0) {res = NULL; break;}
+    if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
+      if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
       res = tarval_div(ta, tb);
     }
     break;
   case iro_Mod:
     /* This was missing in original implementation. Why? */
-    if (ta && tb  && (get_irn_mode(a) == get_irn_mode(b))) {
-      if (tarval_classify(tb) == 0) {res = NULL; break;}
+    if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
+      if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
       res = tarval_mod(ta, tb);
     }
     break;
   /* for iro_DivMod see iro_Proj */
   case iro_Abs:
-    if (ta)
+    if (ta != tarval_bad)
       res = tarval_abs (ta);
     break;
   case iro_And:
-    if (ta && tb) {
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
       res = tarval_and (ta, tb);
     } else {
       tarval *v;
-      if (   (tarval_classify ((v = computed_value (a))) == 0)
-         || (tarval_classify ((v = computed_value (b))) == 0)) {
+      if ( ( ((v = computed_value (a)) != tarval_bad)
+               && (v == get_mode_null(get_tarval_mode(v))) )
+       || ( ((v = computed_value (b)) != tarval_bad)
+               && (v == get_mode_null(get_tarval_mode(v))) )) {
        res = v;
       }
     }
     break;
   case iro_Or:
-    if (ta && tb) {
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
       res = tarval_or (ta, tb);
     } else {
       tarval *v;
@@ -158,14 +164,40 @@ computed_value (ir_node *n)
       }
     }
     break;
-  case iro_Eor: if (ta && tb) { res = tarval_eor (ta, tb); } break;
-  case iro_Not: if (ta)       { res = tarval_neg (ta); } break;
-  case iro_Shl: if (ta && tb) { res = tarval_shl (ta, tb); } break;
-    /* tarval_shr is faulty !! */
-  case iro_Shr: if (ta && tb) { res = tarval_shr (ta, tb); } break;
-  case iro_Shrs:if (ta && tb) { /*res = tarval_shrs (ta, tb)*/; } break;
-  case iro_Rot: if (ta && tb) { /*res = tarval_rot (ta, tb)*/; } break;
-  case iro_Conv:if (ta)       { res = tarval_convert_to (ta, get_irn_mode (n)); }
+  case iro_Eor:
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
+      res = tarval_eor (ta, tb);
+    }
+    break;
+  case iro_Not:
+    if ((ta != tarval_bad)) {
+      res = tarval_neg (ta);
+    }
+    break;
+  case iro_Shl:
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
+      res = tarval_shl (ta, tb);
+    }
+    break;
+  case iro_Shr:
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
+      res = tarval_shr (ta, tb);
+    }
+    break;
+  case iro_Shrs:
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
+     res = tarval_shrs (ta, tb);
+    }
+    break;
+  case iro_Rot:
+    if ((ta != tarval_bad) && (tb != tarval_bad)) {
+      /*res = tarval_rot (ta, tb)*/;
+    }
+    break;
+  case iro_Conv:
+    if (ta != tarval_bad) {
+      res = tarval_convert_to (ta, get_irn_mode (n));
+    }
     break;
   case iro_Proj:  /* iro_Cmp */
     {
@@ -179,8 +211,8 @@ computed_value (ir_node *n)
         only 1 is used.
          There are several case where we can evaluate a Cmp node:
          1. The nodes compared are both the same.  If we compare for
-            equal, this will return true, else it will return false.
-            This step relies on cse.
+            equal, greater equal, ... this will return true, else it
+           will return false.  This step relies on cse.
          2. The predecessors of Cmp are target values.  We can evaluate
             the Cmp.
          3. The predecessors are Allocs or void* constants.  Allocs never
@@ -192,49 +224,49 @@ computed_value (ir_node *n)
        if (aa == ab) { /* 1.: */
           /* This is a tric with the bits used for encoding the Cmp
              Proj numbers, the following statement is not the same:
-          res = tarval_from_long (mode_b, (get_Proj_proj(n) == Eq)):    */
-         res = tarval_from_long (mode_b, (get_Proj_proj(n) & irpn_Eq));
+          res = new_tarval_from_long ((get_Proj_proj(n) == Eq), mode_b) */
+         res = new_tarval_from_long ((get_Proj_proj(n) & Eq), mode_b);
        } else {
          tarval *taa = computed_value (aa);
          tarval *tab = computed_value (ab);
-         if (taa && tab) { /* 2.: */
+         if ((taa != tarval_bad) && (tab != tarval_bad)) { /* 2.: */
             /* strange checks... */
-           ir_pncmp flags = tarval_comp (taa, tab);
-           if (flags != irpn_False) {
-              res = tarval_from_long (mode_b, get_Proj_proj(n) & flags);
+           pnc_number flags = tarval_cmp (taa, tab);
+           if (flags != False) {
+              res = new_tarval_from_long (get_Proj_proj(n) & flags, mode_b);
            }
          } else {  /* check for 3.: */
             ir_node *aaa = skip_nop(skip_Proj(aa));
             ir_node *aba = skip_nop(skip_Proj(ab));
            if (   (   (/* aa is ProjP and aaa is Alloc */
                            (get_irn_op(aa) == op_Proj)
-                       && (get_irn_mode(aa) == mode_p)
+                       && (get_irn_mode(aa) == mode_P)
                         && (get_irn_op(aaa) == op_Alloc))
                     && (   (/* ab is constant void */
                                (get_irn_op(ab) == op_Const)
-                            && (get_irn_mode(ab) == mode_p)
-                            && (get_Const_tarval(ab) == tarval_p_void))
+                            && (get_irn_mode(ab) == mode_P)
+                            && (get_Const_tarval(ab) == get_mode_null(mode_P)))
                        || (/* ab is other Alloc */
                                (get_irn_op(ab) == op_Proj)
-                           && (get_irn_mode(ab) == mode_p)
+                           && (get_irn_mode(ab) == mode_P)
                             && (get_irn_op(aba) == op_Alloc)
                            && (aaa != aba))))
                || (/* aa is void and aba is Alloc */
                        (get_irn_op(aa) == op_Const)
-                    && (get_irn_mode(aa) == mode_p)
-                    && (get_Const_tarval(aa) == tarval_p_void)
+                    && (get_irn_mode(aa) == mode_P)
+                    && (get_Const_tarval(aa) == get_mode_null(mode_P))
                     && (get_irn_op(ab) == op_Proj)
-                   && (get_irn_mode(ab) == mode_p)
+                   && (get_irn_mode(ab) == mode_P)
                     && (get_irn_op(aba) == op_Alloc)))
              /* 3.: */
-             res = tarval_from_long (mode_b, get_Proj_proj(n) & irpn_Ne);
+             res = new_tarval_from_long (get_Proj_proj(n) & Ne, mode_b);
          }
        }
       } else if (get_irn_op(a) == op_DivMod) {
         ta = value_of(get_DivMod_left(a));
         tb = value_of(get_DivMod_right(a));
-       if (ta && tb  && (get_irn_mode(a) == get_irn_mode(b))) {
-         if (tarval_classify(tb) == 0) {res = NULL; break;}
+       if ((ta != tarval_bad)  && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
+         if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
          if (get_Proj_proj(n)== 0) /* Div */
            res = tarval_div(ta, tb);
          else /* Mod */
@@ -250,13 +282,13 @@ computed_value (ir_node *n)
 }  /* compute node */
 
 
-
+#if 0
 /* returns 1 if the a and b are pointers to different locations. */
-bool
+static bool
 different_identity (ir_node *a, ir_node *b)
 {
-  assert (get_irn_mode (a) == mode_p
-          && get_irn_mode (b) == mode_p);
+  assert (get_irn_mode (a) == mode_P
+          && get_irn_mode (b) == mode_P);
 
   if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
     ir_node *a1 = get_Proj_pred (a);
@@ -267,7 +299,7 @@ different_identity (ir_node *a, ir_node *b)
   }
   return 0;
 }
-
+#endif
 
 /* equivalent_node returns a node equivalent to N.  It skips all nodes that
    perform no actual computation, as, e.g., the Id nodes.  It does not create
@@ -281,6 +313,7 @@ equivalent_node (ir_node *n)
   ir_node *a = NULL; /* to shutup gcc */
   ir_node *b = NULL; /* to shutup gcc */
   ir_node *c = NULL; /* to shutup gcc */
+  ir_node *oldn = n;
 
   ins = get_irn_arity (n);
 
@@ -308,10 +341,11 @@ equivalent_node (ir_node *n)
         Remaining Phi nodes are just Ids. */
       if ((get_Block_n_cfgpreds(n) == 1) &&
          (get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) &&
-         (get_opt_control_flow())) {
-       n = get_nodes_Block(get_Block_cfgpred(n, 0));
+         (get_opt_control_flow_straightening())) {
+       n = get_nodes_Block(get_Block_cfgpred(n, 0));                     DBG_OPT_STG;
+
       } else if ((get_Block_n_cfgpreds(n) == 2) &&
-                (get_opt_control_flow())) {
+                (get_opt_control_flow_weak_simplification())) {
        /* Test whether Cond jumps twice to this block
           @@@ we could do this also with two loops finding two preds from several ones. */
        a = get_Block_cfgpred(n, 0);
@@ -319,10 +353,11 @@ equivalent_node (ir_node *n)
        if ((get_irn_op(a) == op_Proj) &&
            (get_irn_op(b) == op_Proj) &&
            (get_Proj_pred(a) == get_Proj_pred(b)) &&
-           (get_irn_op(get_Proj_pred(a)) == op_Cond)) {
+           (get_irn_op(get_Proj_pred(a)) == op_Cond) &&
+           (get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
          /* Also a single entry Block following a single exit Block.  Phis have
             twice the same operand and will be optimized away. */
-         n = get_nodes_Block(a);
+         n = get_nodes_Block(a);                                         DBG_OPT_IFSIM;
        }
       } else if (get_opt_unreachable_code() &&
                 (n != current_ir_graph->start_block) &&
@@ -349,24 +384,23 @@ equivalent_node (ir_node *n)
        /** remove stuff as x+0, x*1 x&true ... constant expression evaluation **/
   case iro_Or:  if (a == b) {n = a; break;}
   case iro_Add:
-  case iro_Eor:
-    { tarval *tv;
-       ir_node *on;
-       /* After running compute_node there is only one constant predecessor.
-          Find this predecessors value and remember the other node: */
-       if ((tv = computed_value (a))) {
-         on = b;
-       } else if ((tv = computed_value (b))) {
-         on = a;
-       } else break;
-
-       /* If this predecessors constant value is zero, the operation is
-          unnecessary. Remove it: */
-       if (tarval_classify (tv) == 0) {
-         n = on;
-       }
+  case iro_Eor: {
+    tarval *tv;
+    ir_node *on;
+    /* After running compute_node there is only one constant predecessor.
+       Find this predecessors value and remember the other node: */
+    if ((tv = computed_value (a))) {
+      on = b;
+    } else if ((tv = computed_value (b))) {
+      on = a;
+    } else break;
+
+    /* If this predecessors constant value is zero, the operation is
+       unnecessary. Remove it: */
+    if (tarval_classify (tv) == 0) {
+      n = on;                                                             DBG_OPT_ALGSIM1;
     }
-    break;
+  } break;
   case iro_Sub:
   case iro_Shl:
   case iro_Shr:
@@ -374,7 +408,7 @@ equivalent_node (ir_node *n)
   case iro_Rot:
     /* these operations are not commutative.  Test only one predecessor. */
     if (tarval_classify (computed_value (b)) == 0) {
-      n = a;
+      n = a;                                                              DBG_OPT_ALGSIM1;
       /* Test if b > #bits of a ==> return 0 / divide b by #bits
          --> transform node? */
     }
@@ -382,15 +416,16 @@ equivalent_node (ir_node *n)
   case iro_Not:   /* NotNot x == x */
   case iro_Minus: /* --x == x */  /* ??? Is this possible or can --x raise an
                                         out of bounds exception if min =! max? */
-    if (get_irn_op(get_unop_op(n)) == get_irn_op(n))
-      n = get_unop_op(get_unop_op(n));
+    if (get_irn_op(get_unop_op(n)) == get_irn_op(n)) {
+      n = get_unop_op(get_unop_op(n));                                    DBG_OPT_ALGSIM2;
+    }
     break;
   case iro_Mul:
     /* Mul is commutative and has again an other neutral element. */
     if (tarval_classify (computed_value (a)) == 1) {
-      n = b;
+      n = b;                                                              DBG_OPT_ALGSIM1;
     } else if (tarval_classify (computed_value (b)) == 1) {
-      n = a;
+      n = a;                                                              DBG_OPT_ALGSIM1;
     }
     break;
   case iro_Div:
@@ -404,26 +439,28 @@ equivalent_node (ir_node *n)
       set_Tuple_pred(n, 2, a);
     }
     break;
-    /* GL: Why are they skipped?  DivMod allocates new nodes --> it's
-       treated in transform node.
-          case iro_Mod, Quot, DivMod
-    */
+  /*
+  case iro_Mod, Quot, DivMod
+    DivMod allocates new nodes --> it's treated in transform node.
+    What about Quot, DivMod?
+  */
   case iro_And:
-    if (a == b) n = a;
-    /* And has it's own neutral element */
-    else if (tarval_classify (computed_value (a)) == -1) {
+    if (a == b) {
+      n = a;    /* And has it's own neutral element */
+    else if (tarval_classify (computed_value (a)) == -1) {
       n = b;
     } else if (tarval_classify (computed_value (b)) == -1) {
       n = a;
     }
+    if (n != oldn)                                                        DBG_OPT_ALGSIM1;
     break;
   case iro_Conv:
     if (get_irn_mode(n) == get_irn_mode(a)) { /* No Conv necessary */
-      n = a;
+      n = a;                                                              DBG_OPT_ALGSIM3;
     } else if (get_irn_mode(n) == mode_b) {
       if (get_irn_op(a) == op_Conv &&
-                 get_irn_mode (get_Conv_op(a)) == mode_b) {
-               n = get_Conv_op(a);     /* Convb(Conv*(xxxb(...))) == xxxb(...) */
+         get_irn_mode (get_Conv_op(a)) == mode_b) {
+       n = get_Conv_op(a);     /* Convb(Conv*(xxxb(...))) == xxxb(...) */ DBG_OPT_ALGSIM2;
       }
     }
     break;
@@ -442,9 +479,13 @@ equivalent_node (ir_node *n)
       ir_node *first_val = NULL; /* to shutup gcc */
       ir_node *scnd_val = NULL;  /* to shutup gcc */
 
+      if (!get_opt_normalize()) return n;
+
       n_preds = get_Phi_n_preds(n);
 
       block = get_nodes_Block(n);
+      /* @@@ fliegt 'raus, sollte aber doch immer wahr sein!!!
+        assert(get_irn_arity(block) == n_preds && "phi in wrong block!"); */
       if ((is_Bad(block)) ||                         /* Control dead */
          (block == current_ir_graph->start_block))  /* There should be no Phi nodes */
        return new_Bad();                            /* in the Start Block. */
@@ -503,7 +544,7 @@ equivalent_node (ir_node *n)
 
       /* Fold, if no multiple distinct non-self-referencing inputs */
       if (i >= n_preds) {
-       n = first_val;
+       n = first_val;                                     DBG_OPT_PHI;
       } else {
        /* skip the remaining Ids. */
        while (++i < n_preds) {
@@ -516,7 +557,7 @@ equivalent_node (ir_node *n)
   case iro_Load:
     {
 #if 0  /* Is an illegal transformation: different nodes can
-                 represent the same pointer value!! */
+         represent the same pointer value!! */
  a = skip_Proj(get_Load_mem(n));
  b = get_Load_ptr(n);
 
@@ -542,18 +583,17 @@ equivalent_node (ir_node *n)
           && get_Store_ptr(a) == b
           && skip_Proj(get_Store_value(a)) == c) {
         /* We have twice exactly the same store -- a write after write. */
-               n = a;
+       n = a;                                                         DBG_OPT_WAW;
       } else if (get_irn_op(c) == op_Load
                 && (a == c || skip_Proj(get_Load_mem(c)) == a)
-                 && get_Load_ptr(c) == b )
-       /* !!!??? and a cryptic test */ {
+                 && get_Load_ptr(c) == b ) {
         /* We just loaded the value from the same memory, i.e., the store
            doesn't change the memory -- a write after read. */
        a = get_Store_mem(n);
         turn_into_tuple(n, 2);
         set_Tuple_pred(n, 0, a);
-        set_Tuple_pred(n, 1, new_Bad());
-      }
+        set_Tuple_pred(n, 1, new_Bad());                               DBG_OPT_WAR;
+       }
     }
     break;
 
@@ -564,21 +604,21 @@ equivalent_node (ir_node *n)
       if ( get_irn_op(a) == op_Tuple) {
         /* Remove the Tuple/Proj combination. */
        if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
-         n = get_Tuple_pred(a, get_Proj_proj(n));
+         n = get_Tuple_pred(a, get_Proj_proj(n));                     DBG_OPT_TUPLE;
        } else {
           assert(0); /* This should not happen! */
          n = new_Bad();
        }
       } else if (get_irn_mode(n) == mode_X &&
                 is_Bad(get_nodes_Block(n))) {
-        /* Remove dead control flow. */
+        /* Remove dead control flow -- early gigo. */
        n = new_Bad();
       }
     }
     break;
 
   case iro_Id:
-    n = follow_Id (n);
+    n = follow_Id (n);                                                 DBG_OPT_ID;
     break;
 
   default: break;
@@ -602,24 +642,24 @@ transform_node (ir_node *n)
   switch (get_irn_opcode(n)) {
   case iro_Div: {
     ta = computed_value(n);
-    if (ta) {
+    if (ta != tarval_bad) {
       /* Turn Div into a tuple (mem, bad, value) */
       ir_node *mem = get_Div_mem(n);
       turn_into_tuple(n, 3);
       set_Tuple_pred(n, 0, mem);
       set_Tuple_pred(n, 1, new_Bad());
-      set_Tuple_pred(n, 2, new_Const(get_tv_mode(ta), ta));
+      set_Tuple_pred(n, 2, new_Const(get_tarval_mode(ta), ta));
     }
   } break;
   case iro_Mod: {
     ta = computed_value(n);
-    if (ta) {
+    if (ta != tarval_bad) {
       /* Turn Div into a tuple (mem, bad, value) */
       ir_node *mem = get_Mod_mem(n);
       turn_into_tuple(n, 3);
       set_Tuple_pred(n, 0, mem);
       set_Tuple_pred(n, 1, new_Bad());
-      set_Tuple_pred(n, 2, new_Const(get_tv_mode(ta), ta));
+      set_Tuple_pred(n, 2, new_Const(get_tarval_mode(ta), ta));
     }
   } break;
   case iro_DivMod: {
@@ -636,29 +676,29 @@ transform_node (ir_node *n)
       break;
 
     if (a == b) {
-      a = new_Const (mode, tarval_from_long (mode, 1));
-      b = new_Const (mode, tarval_from_long (mode, 0));
+      a = new_Const (mode, get_mode_one(mode));
+      b = new_Const (mode, get_mode_null(mode));
       evaluated = 1;
     } else {
       ta = value_of(a);
       tb = value_of(b);
 
-      if (tb) {
-       if (tarval_classify(tb) == 1) {
-         b = new_Const (mode, tarval_from_long (mode, 0));
+      if (tb != tarval_bad) {
+       if (tb == get_mode_one(get_tarval_mode(tb))) {
+         b = new_Const (mode, get_mode_null(mode));
          evaluated = 1;
-       } else if (ta) {
+       } else if (ta != tarval_bad) {
          tarval *resa, *resb;
           resa = tarval_div (ta, tb);
-          if (!resa) break; /* Causes exception!!! Model by replacing through
-                              Jmp for X result!? */
+          if (resa == tarval_bad) break; /* Causes exception!!! Model by replacing through
+                                           Jmp for X result!? */
           resb = tarval_mod (ta, tb);
-          if (!resb) break; /* Causes exception! */
+          if (resb == tarval_bad) break; /* Causes exception! */
          a = new_Const (mode, resa);
          b = new_Const (mode, resb);
          evaluated = 1;
        }
-      } else if (tarval_classify (ta) == 0) {
+      } else if (ta == get_mode_null(get_tarval_mode(ta))) {
         b = a;
        evaluated = 1;
       }
@@ -682,14 +722,14 @@ transform_node (ir_node *n)
     a = get_Cond_selector(n);
     ta = value_of(a);
 
-    if (ta &&
+    if ((ta != tarval_bad) &&
        (get_irn_mode(a) == mode_b) &&
        (get_opt_unreachable_code())) {
       /* It's a boolean Cond, branching on a boolean constant.
                 Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
       jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
       turn_into_tuple(n, 2);
-      if (tv_val_b(ta) == 1)  /* GL: I hope this returns 1 if true */ {
+      if (ta == tarval_b_true) {
                set_Tuple_pred(n, 0, new_Bad());
                set_Tuple_pred(n, 1, jmp);
       } else {
@@ -698,8 +738,8 @@ transform_node (ir_node *n)
       }
       /* We might generate an endless loop, so keep it alive. */
       add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
-    } else if (ta &&
-              (get_irn_mode(a) == mode_I) &&
+    } else if ((ta != tarval_bad) &&
+              (get_irn_mode(a) == mode_Iu) &&
               (get_Cond_kind(n) == dense) &&
               (get_opt_unreachable_code())) {
       /* I don't want to allow Tuples smaller than the biggest Proj.
@@ -745,12 +785,12 @@ transform_node (ir_node *n)
       else
         set_Proj_proj(n, 0);
     } else if ((get_irn_op(a) == op_Cond)
-              && (get_irn_mode(get_Cond_selector(a)) == mode_I)
+              && (get_irn_mode(get_Cond_selector(a)) == mode_Iu)
               && value_of(a)
               && (get_Cond_kind(a) == dense)
               && (get_opt_unreachable_code())) {
       /* The Cond is a Switch on a Constant */
-      if (get_Proj_proj(n) == tv_val_CHIL(value_of(a))) {
+      if (get_Proj_proj(n) == tarval_to_long(value_of(a))) {
         /* The always taken branch, reuse the existing Jmp. */
         if (!get_irn_link(a)) /* well, if it exists ;-> */
           set_irn_link(a, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
@@ -821,14 +861,6 @@ vt_cmp (const void *elt, const void *key)
       (get_irn_mode(a) != get_irn_mode(b))) return 1;
 
   /* compare if a's in and b's in are equal */
-  /* GL: we optimize only nodes with in arrays of fixed sizes.
-  if (get_irn_arity (a) != -2) {
-    ins = get_irn_arity (a);
-    if (ins != get_irn_arity (b)) return 1;
-    ain = get_irn_in (a);
-    bin = get_irn_in (b);
-  }
-  */
   if (get_irn_arity (a) != get_irn_arity(b))
     return 1;
 
@@ -848,6 +880,8 @@ vt_cmp (const void *elt, const void *key)
     return get_irn_const_attr (a) != get_irn_const_attr (b);
   case iro_Proj:
     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
+  case iro_Filter:
+    return get_Filter_proj(a) != get_Filter_proj(b);
   case iro_Alloc:
     return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
       || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
@@ -863,8 +897,7 @@ vt_cmp (const void *elt, const void *key)
       || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
       || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
       || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
-      || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type)
-      || (get_irn_sel_attr(a).ltyp != get_irn_sel_attr(b).ltyp);
+      || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type);
   case iro_Phi:
     return get_irn_phi_attr (a) != get_irn_phi_attr (b);
   default: ;
@@ -909,7 +942,7 @@ del_identities (pset *value_table)
 
 /* Return the canonical node computing the same value as n.
    Looks up the node in a hash table. */
-static inline ir_node *
+static INLINE ir_node *
 identify (pset *value_table, ir_node *n)
 {
   ir_node *o = NULL;
@@ -945,7 +978,7 @@ identify (pset *value_table, ir_node *n)
 /* During construction we set the pinned flag in the graph right when the
    optimizatin is performed.  The flag turning on procedure global cse could
    be changed between two allocations.  This way we are safe. */
-static inline ir_node *
+static INLINE ir_node *
 identify_cons (pset *value_table, ir_node *n) {
   ir_node *old = n;
   n = identify(value_table, n);
@@ -979,7 +1012,7 @@ add_identities (pset *value_table, ir_node *node) {
 
 /* 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 *
+static INLINE ir_node *
 gigo (ir_node *node)
 {
   int i;
@@ -1012,7 +1045,7 @@ gigo (ir_node *node)
    It can only be called if it is guaranteed that no other nodes
    reference this one, i.e., right after construction of a node.  */
 ir_node *
-optimize (ir_node *n)
+optimize_node (ir_node *n)
 {
   tarval *tv;
   ir_node *old_n = n;
@@ -1026,10 +1059,10 @@ optimize (ir_node *n)
     if  (get_irn_op(n) != op_Const) {
       /* try to evaluate */
       tv = computed_value (n);
-      if ((get_irn_mode(n) != mode_T) && (tv != NULL)) {
+      if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
         /* evaluation was succesful -- replace the node. */
        obstack_free (current_ir_graph->obst, n);
-       return new_Const (get_tv_mode (tv), tv);
+       return new_Const (get_tarval_mode (tv), tv);
       }
     }
   }
@@ -1103,12 +1136,11 @@ optimize_in_place_2 (ir_node *n)
     if  (get_irn_op(n) != op_Const) {
       /* try to evaluate */
       tv = computed_value (n);
-      if ((get_irn_mode(n) != mode_T) && (tv != NULL)) {
+      if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
         /* evaluation was succesful -- replace the node. */
-       n = new_Const (get_tv_mode (tv), tv);
-       __dbg_info_merge_pair(n, old_n, id_from_str("const_eval", 10));
+       n = new_Const (get_tarval_mode (tv), tv);
+       __dbg_info_merge_pair(n, old_n, dbg_const_eval);
        return n;
-        /* xprintf("* optimize: computed node %I\n", n->op->name);*/
       }
     }
   }
@@ -1117,8 +1149,8 @@ optimize_in_place_2 (ir_node *n)
   /*if (get_opt_constant_folding()) */
   if (get_opt_constant_folding() ||
       (get_irn_op(n) == op_Phi)  ||   /* always optimize these nodes. */
-      (get_irn_op(n) == op_Id)   ||
-      (get_irn_op(n) == op_Proj) ||
+      (get_irn_op(n) == op_Id)   ||   /* ... */
+      (get_irn_op(n) == op_Proj) ||   /* ... */
       (get_irn_op(n) == op_Block)  )  /* Flags tested local. */
     n = equivalent_node (n);