added edge verification routines
[libfirm] / ir / ir / iropt.c
index ea0b9d7..dcc0a90 100644 (file)
@@ -6,7 +6,7 @@
  * Modified by: Goetz Lindenmaier, Michael Beck
  * Created:
  * CVS-ID:      $Id$
- * Copyright:   (c) 1998-2005 Universität Karlsruhe
+ * Copyright:   (c) 1998-2006 Universität Karlsruhe
  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
  */
 
@@ -58,7 +58,8 @@ static tarval *computed_value_Const(ir_node *n) {
  * Return the value of a 'sizeof' or 'alignof' SymConst.
  */
 static tarval *computed_value_SymConst(ir_node *n) {
-  ir_type *type;
+  ir_type   *type;
+  ir_entity *ent;
 
   switch (get_SymConst_kind(n)) {
   case symconst_type_size:
@@ -71,6 +72,12 @@ static tarval *computed_value_SymConst(ir_node *n) {
     if (get_type_state(type) == layout_fixed)
       return new_tarval_from_long(get_type_alignment_bytes(type), get_irn_mode(n));
     break;
+  case symconst_ofs_ent:
+    ent  = get_SymConst_entity(n);
+    type = get_entity_owner(ent);
+    if (get_type_state(type) == layout_fixed)
+      return new_tarval_from_long(get_entity_offset(ent), get_irn_mode(n));
+    break;
   default:
     break;
   }
@@ -654,7 +661,7 @@ tarval *computed_value(ir_node *n) {
  * @return
  *    The operations.
  */
-static ir_op_ops *firm_set_default_computed_value(opcode code, ir_op_ops *ops)
+static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                               \
   case iro_##a:                               \
@@ -1602,7 +1609,7 @@ ir_node *equivalent_node(ir_node *n) {
  * @return
  *    The operations.
  */
-static ir_op_ops *firm_set_default_equivalent_node(opcode code, ir_op_ops *ops)
+static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                                 \
   case iro_##a:                                 \
@@ -2032,7 +2039,8 @@ static ir_node *transform_node_Sub(ir_node *n)
   if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
     return n;
 
-  if (mode_is_num(mode) && (classify_Const(a) == CNST_NULL)) {
+  /* Beware of Sub(P, P) which cannot be optimized into a simple Minus ... */
+  if (mode_is_num(mode) && mode == get_irn_mode(a) && (classify_Const(a) == CNST_NULL)) {
     n = new_rd_Minus(
           get_irn_dbg_info(n),
           current_ir_graph,
@@ -3417,7 +3425,7 @@ static ir_node *transform_node(ir_node *n)
  * @return
  *    The operations.
  */
-static ir_op_ops *firm_set_default_transform_node(opcode code, ir_op_ops *ops)
+static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                                 \
   case iro_##a:                                 \
@@ -3558,7 +3566,7 @@ static int node_cmp_attr_Confirm(ir_node *a, ir_node *b) {
  * @return
  *    The operations.
  */
-static ir_op_ops *firm_set_default_node_cmp_attr(opcode code, ir_op_ops *ops)
+static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
 {
 #define CASE(a)                              \
   case iro_##a:                              \
@@ -3676,6 +3684,10 @@ void del_identities(pset *value_table) {
 
 /**
  * Return the canonical node computing the same value as n.
+ *
+ * @param value_table  The value table
+ * @param n            The node to lookup
+ *
  * Looks up the node in a hash table.
  *
  * For Const nodes this is performed in the constructor, too.  Const
@@ -3799,7 +3811,13 @@ static INLINE ir_node *gigo(ir_node *node)
         if (!is_Bad(get_irn_n(block, i)))
           break;
       }
-      if (i == irn_arity) return new_Bad();
+      if (i == irn_arity) {
+        ir_graph *irg = get_irn_irg(block);
+        /* the start block is never dead */
+        if(block != get_irg_start_block(irg)
+                  && block != get_irg_end_block(irg))
+          return new_Bad();
+      }
     }
   }
 
@@ -3852,13 +3870,15 @@ static INLINE ir_node *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.
  *
+ * @param n   The node to optimize
+ *
  * current_ir_graph must be set to the graph of the node!
  */
 ir_node *optimize_node(ir_node *n)
 {
   tarval *tv;
   ir_node *oldn = n;
-  opcode iro = get_irn_opcode(n);
+  ir_opcode iro = get_irn_opcode(n);
 
   /* Always optimize Phi nodes: part of the construction. */
   if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
@@ -3967,7 +3987,7 @@ ir_node *optimize_in_place_2(ir_node *n)
 {
   tarval *tv;
   ir_node *oldn = n;
-  opcode iro = get_irn_opcode(n);
+  ir_opcode iro = get_irn_opcode(n);
 
   if (!get_opt_optimize() && (get_irn_op(n) != op_Phi)) return n;
 
@@ -4044,8 +4064,7 @@ ir_node *optimize_in_place_2(ir_node *n)
 /**
  * Wrapper for external use, set proper status bits after optimization.
  */
-ir_node *optimize_in_place(ir_node *n)
-{
+ir_node *optimize_in_place(ir_node *n) {
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
 
@@ -4063,8 +4082,7 @@ ir_node *optimize_in_place(ir_node *n)
 /*
  * Sets the default operation for an ir_ops.
  */
-ir_op_ops *firm_set_default_operations(opcode code, ir_op_ops *ops)
-{
+ir_op_ops *firm_set_default_operations(ir_opcode code, ir_op_ops *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);