Fixed wrong array declaration
[libfirm] / ir / opt / opt_confirms.c
index f4e7927..ee23ee5 100644 (file)
@@ -20,6 +20,7 @@
 #include "iropt_t.h"
 #include "iropt_dbg.h"
 #include "opt_confirms.h"
+#include "irflag_t.h"
 #include "irprintf.h"
 
 enum range_tags {
@@ -76,7 +77,7 @@ static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn
 
 #endif /* DEBUG_CONFIRM */
 
-/**
+/*
  * Check, if the value of a node is != 0.
  *
  * This is a often needed case, so we handle here Confirm
@@ -93,7 +94,7 @@ int value_not_zero(ir_node *n)
   while (get_irn_op(n) == op_Confirm) {
     /*
      * Note: A Confirm is never after a Const. So,
-     * we simply can check the bound for beeing a Const
+     * we simply can check the bound for being a Const
      * without the fear that is might be hidden by a further Confirm.
      */
     tv = value_of(get_Confirm_bound(n));
@@ -143,6 +144,39 @@ int value_not_zero(ir_node *n)
 #undef RET_ON
 }
 
+/*
+ * Check, if the value of a node cannot represent a NULL pointer.
+ *
+ * - Casts are skipped
+ * - If sel_based_null_check_elim is enabled, all
+ *   Sel nodes can be skipped.
+ * - A SymConst(entity) is NEVER a NULL pointer
+ * - Confirms are evaluated
+ */
+int value_not_null(ir_node *n)
+{
+  ir_op *op;
+
+  n  = skip_Cast(n);
+  op = get_irn_op(n);
+  assert(mode_is_reference(get_irn_mode(n)));
+  if (get_opt_sel_based_null_check_elim()) {
+    /* skip all Sel nodes and Cast's */
+    while (op == op_Sel) {
+      n = skip_Cast(get_Sel_ptr(n));
+      op = get_irn_op(n);
+    }
+  }
+  if (op == op_SymConst && get_SymConst_kind(n) == symconst_addr_ent)
+    return 1;
+  if (op == op_Confirm) {
+    if (get_Confirm_cmp(n) == pn_Cmp_Lg &&
+        classify_Const(get_Confirm_bound(n)) == CNST_NULL)
+      return 1;
+  }
+  return 0;
+}
+
 /*
  * Check, if the value of a node can be confirmed >= 0 or <= 0,
  * If the mode of the value did not honor signed zeros, else
@@ -285,7 +319,7 @@ static interval_t *get_interval_from_tv(interval_t *iv, tarval *tv)
  *
  * @param iv     an empty interval, will be filled
  * @param bound  the bound value
- * @param pnc    the Confirm pnc relation
+ * @param pnc    the Confirm compare relation
  *
  * @return the filled interval or NULL if no interval
  *         can be created (happens only on floating point
@@ -430,28 +464,28 @@ static tarval *(compare_iv)(const interval_t *l_iv, const interval_t *r_iv, pn_C
     if (l_iv->min == l_iv->max && r_iv->min == r_iv->max)
       return tarval_cmp(l_iv->min, r_iv->min) == pn_Cmp_Eq ? tv_true : tv_false;
 
-    /* if both interval do not intersect, it is never equal */
+    /* if both intervals do not intersect, it is never equal */
     res = tarval_cmp(l_iv->max, r_iv->min);
 
     /* b < c ==> [a,b] != [c,d] */
     if (res == pn_Cmp_Lt)
-            return tv_false;
+      return tv_false;
 
     /* b <= c ==> [a,b) != [c,d]  AND [a,b] != (c,d] */
     if ((l_iv->flags & MAX_EXCLUDED || r_iv->flags & MIN_EXCLUDED)
-              && (res == pn_Cmp_Eq))
-            return tv_false;
+        && (res == pn_Cmp_Eq))
+      return tv_false;
 
     res = tarval_cmp(r_iv->max, l_iv->min);
 
     /* d < a ==> [c,d] != [a,b] */
     if (res == pn_Cmp_Lt)
-            return tv_false;
+      return tv_false;
 
     /* d <= a ==> [c,d) != [a,b]  AND [c,d] != (a,b] */
     if ((r_iv->flags & MAX_EXCLUDED || l_iv->flags & MIN_EXCLUDED)
-            && (res == pn_Cmp_Eq))
-            return tv_false;
+        && (res == pn_Cmp_Eq))
+      return tv_false;
     break;
 
   case pn_Cmp_Lg:
@@ -527,8 +561,10 @@ static int is_transitive(pn_Cmp pnc) {
  * Return the value of a Cmp if one or both predecessors
  * are Confirm nodes.
  *
+ * @param cmp    the Cmp node
  * @param left   the left operand of the Cmp
  * @param right  the right operand of the Cmp
+ * @param pnc    the compare relation
  */
 tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc)
 {
@@ -696,6 +732,10 @@ tarval *computed_value_Cmp_Confirm(ir_node *cmp, ir_node *left, ir_node *right,
 #ifdef DEBUG_CONFIRM
 /**
  * For debugging. Prints an interval into a string.
+ *
+ * @param buf   address of a string buffer
+ * @param len   length of the string buffer
+ * @param iv    the interval
  */
 static int iv_snprintf(char *buf, size_t len, const interval_t *iv) {
   char smin[64], smax[64];
@@ -719,7 +759,11 @@ static int iv_snprintf(char *buf, size_t len, const interval_t *iv) {
 }
 
 /**
- * For debugging. Prints an interval compare
+ * For debugging. Prints an interval compare.
+ *
+ * @param l_iv  the left interval
+ * @param r_iv  the right interval
+ * @param pnc   the compare relation
  */
 static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
 {
@@ -732,7 +776,11 @@ static void print_iv_cmp(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp
 }
 
 /**
- * For debugging. call *compare_iv() and prints inputs and result
+ * For debugging. call *compare_iv() and prints inputs and result.
+ *
+ * @param l_iv  the left interval
+ * @param r_iv  the right interval
+ * @param pnc   the compare relation
  */
 static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn_Cmp pnc)
 {
@@ -744,7 +792,7 @@ static tarval *compare_iv_dbg(const interval_t *l_iv, const interval_t *r_iv, pn
   ir_printf("In %e:\n", get_irg_entity(current_ir_graph));
   print_iv_cmp(l_iv, r_iv, pnc);
   ir_printf(" = %T\n", tv);
-       return tv;
+  return tv;
 }
 
 #endif /* DEBUG_CONFIRM */