removed exc.h from libfirm interface
[libfirm] / ir / ir / iropt.c
index 4ce8c62..77e0c82 100644 (file)
@@ -1,12 +1,14 @@
-/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
-* All rights reserved.
-*
-* Authors: Christian Schaefer, Goetz Lindenmaier
-*
-* iropt --- optimizations intertwined with IR construction.
-*/
-
-/* $Id$ */
+/*
+ * Project:     libFIRM
+ * File name:   ir/ir/iropt.c
+ * Purpose:     iropt --- optimizations intertwined with IR construction.
+ * Author:      Christian Schaefer
+ * Modified by: Goetz Lindenmaier
+ * Created:
+ * CVS-ID:      $Id$
+ * Copyright:   (c) 1998-2003 Universität Karlsruhe
+ * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -19,9 +21,8 @@
 # include "irgmod.h"
 # include "irvrfy.h"
 # include "tv.h"
-# include "tune.h"
 # include "dbginfo_t.h"
-# include "iropt_dbg.c"
+# include "iropt_dbg.h"
 
 /* Make types visible to allow most efficient access */
 # include "entity_t.h"
@@ -171,7 +172,7 @@ computed_value (ir_node *n)
     break;
   case iro_Not:
     if ((ta != tarval_bad)) {
-      res = tarval_neg (ta);
+      res = tarval_not (ta);
     }
     break;
   case iro_Shl:
@@ -240,23 +241,23 @@ computed_value (ir_node *n)
             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)
+                       && (mode_is_reference(get_irn_mode(aa)))
                         && (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) == get_mode_null(mode_P)))
+                            && (mode_is_reference(get_irn_mode(ab)))
+                            && (get_Const_tarval(ab) == get_mode_null(get_irn_mode(ab))))
                        || (/* ab is other Alloc */
                                (get_irn_op(ab) == op_Proj)
-                           && (get_irn_mode(ab) == mode_P)
+                           && (mode_is_reference(get_irn_mode(ab)))
                             && (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) == get_mode_null(mode_P))
+                    && (mode_is_reference(get_irn_mode(aa)))
+                    && (get_Const_tarval(aa) == get_mode_null(get_irn_mode(aa)))
                     && (get_irn_op(ab) == op_Proj)
-                   && (get_irn_mode(ab) == mode_P)
+                   && (mode_is_reference(get_irn_mode(ab)))
                     && (get_irn_op(aba) == op_Alloc)))
              /* 3.: */
              res = new_tarval_from_long (get_Proj_proj(n) & Ne, mode_b);
@@ -287,8 +288,8 @@ computed_value (ir_node *n)
 static bool
 different_identity (ir_node *a, ir_node *b)
 {
-  assert (get_irn_mode (a) == mode_P
-          && get_irn_mode (b) == mode_P);
+  assert (mode_is_reference(get_irn_mode (a))
+          && mode_is_reference(get_irn_mode (b)));
 
   if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
     ir_node *a1 = get_Proj_pred (a);
@@ -654,7 +655,7 @@ transform_node (ir_node *n)
   case iro_Mod: {
     ta = computed_value(n);
     if (ta != tarval_bad) {
-      /* Turn Div into a tuple (mem, bad, value) */
+      /* Turn Mod into a tuple (mem, bad, value) */
       ir_node *mem = get_Mod_mem(n);
       turn_into_tuple(n, 3);
       set_Tuple_pred(n, 0, mem);
@@ -844,6 +845,10 @@ transform_node (ir_node *n)
 
 /* **************** Common Subexpression Elimination **************** */
 
+/** The size of the hash table used, should estimate the number of nodes
+    in a graph. */
+#define N_IR_NODES 512
+
 /* Compare function for two nodes in the hash table.   Gets two       */
 /* nodes as parameters.  Returns 0 if the nodes are a cse.            */
 static int
@@ -877,7 +882,8 @@ vt_cmp (const void *elt, const void *key)
 
   switch (get_irn_opcode(a)) {
   case iro_Const:
-    return get_irn_const_attr (a) != get_irn_const_attr (b);
+    return (get_Const_tarval(a) != get_Const_tarval(b))
+      || (get_Const_type(a) != get_Const_type(b));
   case iro_Proj:
     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
   case iro_Filter:
@@ -900,6 +906,8 @@ vt_cmp (const void *elt, const void *key)
       || (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);
+  case iro_Cast:
+    return get_Cast_type(a) != get_Cast_type(b);
   default: ;
   }
 
@@ -931,7 +939,7 @@ ir_node_hash (ir_node *node)
 pset *
 new_identities (void)
 {
-  return new_pset (vt_cmp, TUNE_NIR_NODES);
+  return new_pset (vt_cmp, N_IR_NODES);
 }
 
 void
@@ -1018,6 +1026,20 @@ gigo (ir_node *node)
   int i;
   ir_op* op = get_irn_op(node);
 
+#if 1
+  /* remove garbage blocks by looking at control flow that leaves the block
+     and replacing the control flow by Bad. */
+  if (get_irn_mode(node) == mode_X) {
+    ir_node *block = get_nodes_block(node);
+    if (get_irn_op(block) == op_Block && get_Block_matured(block)) {
+      for (i = 0; i < get_irn_arity(block); i++) {
+       if (!is_Bad(get_irn_n(block, i))) break;
+      }
+      if (i == get_irn_arity(block)) return new_Bad();
+    }
+  }
+#endif
+
   /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
      blocks predecessors is dead. */
   if ( op != op_Block && op != op_Phi && op != op_Tuple) {
@@ -1028,13 +1050,15 @@ gigo (ir_node *node)
     }
   }
 #if 0
+  /* With this code we violate the agreement that local_optimize
+     only leaves Bads in Block, Phi and Tuple nodes. */
   /* If Block has only Bads as predecessors it's garbage. */
   /* If Phi has only Bads as predecessors it's garbage. */
-  if (op == op_Block || op == op_Phi)  {
+  if ((op == op_Block && get_Block_matured(node)) || op == op_Phi)  {
     for (i = 0; i < get_irn_arity(node); i++) {
       if (!is_Bad(get_irn_n(node, i))) break;
     }
-    if (i = get_irn_arity(node)) node = new_Bad();
+    if (i == get_irn_arity(node)) node = new_Bad();
   }
 #endif
   return node;