added edge verification routines
[libfirm] / ir / ir / iropt.c
index 0e0c8ea..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;
   }
@@ -553,7 +560,8 @@ static tarval *computed_value_Proj_Cmp(ir_node *n)
 }  /* computed_value_Proj_Cmp */
 
 /**
- * Return the value of a Proj, handle Proj(Cmp), Proj(Div), Proj(Mod), Proj(DivMod).
+ * Return the value of a Proj, handle Proj(Cmp), Proj(Div), Proj(Mod),
+ * Proj(DivMod) and Proj(Quot).
  */
 static tarval *computed_value_Proj(ir_node *n) {
   ir_node *a = get_Proj_pred(n);
@@ -582,6 +590,11 @@ static tarval *computed_value_Proj(ir_node *n) {
       return computed_value(a);
     break;
 
+  case iro_Quot:
+    if (get_Proj_proj(n) == pn_Quot_res)
+      return computed_value(a);
+    break;
+
   default:
     return tarval_bad;
   }
@@ -648,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:                               \
@@ -1596,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:                                 \
@@ -1738,8 +1751,8 @@ static ir_node *apply_binop_on_phi(ir_node *phi, tarval *other, tarval *(*eval)(
   irg  = current_ir_graph;
   for (i = 0; i < n; ++i) {
     pred = get_irn_n(phi, i);
-    res[i] = new_r_Const_type(irg, get_nodes_block(pred),
-                            mode, res[i], get_Const_type(pred));
+    res[i] = new_r_Const_type(irg, get_irg_start_block(irg),
+                              mode, res[i], get_Const_type(pred));
   }
   return new_r_Phi(irg, get_nodes_block(phi), n, (ir_node **)res, mode);
 }  /* apply_binop_on_phi */
@@ -1776,8 +1789,8 @@ static ir_node *apply_unop_on_phi(ir_node *phi, tarval *(*eval)(tarval *)) {
   irg  = current_ir_graph;
   for (i = 0; i < n; ++i) {
     pred = get_irn_n(phi, i);
-    res[i] = new_r_Const_type(irg, get_nodes_block(pred),
-                            mode, res[i], get_Const_type(pred));
+    res[i] = new_r_Const_type(irg, get_irg_start_block(irg),
+                              mode, res[i], get_Const_type(pred));
   }
   return new_r_Phi(irg, get_nodes_block(phi), n, (ir_node **)res, mode);
 }  /* apply_unop_on_phi */
@@ -2026,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,
@@ -3411,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:                                 \
@@ -3552,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:                              \
@@ -3670,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
@@ -3793,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();
+      }
     }
   }
 
@@ -3846,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;
@@ -3961,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;
 
@@ -4038,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);
 
@@ -4057,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);