cleanup: Remove duplicate MIN/MAX macros.
[libfirm] / ir / ana / vrp.c
index ac200f4..fdc3b70 100644 (file)
@@ -1,20 +1,6 @@
 /*
- * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
@@ -119,33 +105,34 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
        }
 
        case iro_Add: {
-               int overflow_top, overflow_bottom;
-               ir_tarval *new_top, *new_bottom;
-               const vrp_attr *vrp_left, *vrp_right;
-               vrp_left = vrp_get_or_set_info(info, get_Add_left(node));
-               vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
+               const vrp_attr *vrp_left  = vrp_get_or_set_info(info, get_Add_left(node));
+               const vrp_attr *vrp_right = vrp_get_or_set_info(info, get_Add_right(node));
 
-               if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
-                               VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
-                               vrp_right->range_type == VRP_VARYING) {
+               if (vrp_left->range_type == VRP_UNDEFINED
+                || vrp_right->range_type == VRP_UNDEFINED
+                || vrp_left->range_type == VRP_VARYING
+                || vrp_right->range_type == VRP_VARYING) {
                        return 0;
                }
 
-               new_top = tarval_add(vrp_left->range_top, vrp_right->range_top);
-               overflow_top = tarval_carry();
-               new_bottom = tarval_add(vrp_left->range_bottom, vrp_right->range_bottom);
-               overflow_bottom = tarval_carry();
-
-               if (!overflow_top && !overflow_bottom && vrp_left->range_type == VRP_RANGE
-                               &&vrp_right->range_type == VRP_RANGE) {
-                       new_range_bottom = new_bottom;
-                       new_range_top = new_top;
-                       new_range_type = VRP_RANGE;
-               }
-
-               if (overflow_top || overflow_bottom) {
-                       /* TODO Implement overflow handling*/
-                       new_range_type = VRP_UNDEFINED;
+               if (vrp_left->range_type == VRP_RANGE
+                && vrp_right->range_type == VRP_RANGE) {
+                       tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
+                       tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
+                       ir_tarval *new_top
+                               = tarval_add(vrp_left->range_top, vrp_right->range_top);
+                       ir_tarval *new_bottom
+                               = tarval_add(vrp_left->range_bottom, vrp_right->range_bottom);
+                       tarval_set_integer_overflow_mode(rem);
+
+                       if (new_top != tarval_bad && new_bottom != tarval_bad) {
+                               new_range_bottom = new_bottom;
+                               new_range_top    = new_top;
+                               new_range_type   = VRP_RANGE;
+                       } else {
+                               /* TODO Implement overflow handling*/
+                               new_range_type = VRP_UNDEFINED;
+                       }
                }
                break;
        }
@@ -153,36 +140,36 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
        case iro_Sub: {
                ir_node *left  = get_Sub_left(node);
                ir_node *right = get_Sub_right(node);
-               int overflow_top, overflow_bottom;
-               ir_tarval *new_top, *new_bottom;
-               const vrp_attr *vrp_left, *vrp_right;
 
                if (!mode_is_int(get_irn_mode(left)))
                        return 0;
 
-               vrp_left  = vrp_get_or_set_info(info, left);
-               vrp_right = vrp_get_or_set_info(info, right);
+               const vrp_attr *vrp_left  = vrp_get_or_set_info(info, left);
+               const vrp_attr *vrp_right = vrp_get_or_set_info(info, right);
 
-               if (vrp_left->range_type == VRP_UNDEFINED || vrp_right->range_type ==
-                               VRP_UNDEFINED || vrp_left->range_type == VRP_VARYING ||
-                               vrp_right->range_type == VRP_VARYING) {
+               if (vrp_left->range_type == VRP_UNDEFINED
+                || vrp_right->range_type == VRP_UNDEFINED
+                || vrp_left->range_type == VRP_VARYING
+                || vrp_right->range_type == VRP_VARYING) {
                        return 0;
                }
 
-               new_top = tarval_sub(vrp_left->range_top, vrp_right->range_top, NULL);
-               overflow_top = tarval_carry();
-               new_bottom = tarval_sub(vrp_left->range_bottom, vrp_right->range_bottom, NULL);
-               overflow_bottom = tarval_carry();
-
-               if (!overflow_top && !overflow_bottom && vrp_left->range_type == VRP_RANGE
-                               &&vrp_right->range_type == VRP_RANGE) {
-                       new_range_bottom = new_bottom;
-                       new_range_top = new_top;
-                       new_range_type = VRP_RANGE;
-               }
-
-               if (overflow_top || overflow_bottom) {
-                       /* TODO Implement overflow handling*/
+               if (vrp_left->range_type == VRP_RANGE
+                && vrp_right->range_type == VRP_RANGE) {
+                       tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
+                       tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
+                       ir_tarval *new_top = tarval_sub(vrp_left->range_top, vrp_right->range_top, NULL);
+                       ir_tarval *new_bottom = tarval_sub(vrp_left->range_bottom, vrp_right->range_bottom, NULL);
+                       tarval_set_integer_overflow_mode(rem);
+
+                       if (new_top != tarval_bad && new_bottom != tarval_bad) {
+                               new_range_bottom = new_bottom;
+                               new_range_top = new_top;
+                               new_range_type = VRP_RANGE;
+                       } else {
+                               /* TODO Implement overflow handling*/
+                               new_range_type = VRP_UNDEFINED;
+                       }
                }
                break;
        }
@@ -392,7 +379,7 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
        /* TODO: Check, if there can be information derived from any of these:
        is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
        is_Break(node) is_Builtin(node) is_Call(node)
-       is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
+       is_Carry(node) is_Cmp(node) is_Cond(node)
        is_CopyB(node) is_Div(node) is_Dummy(node)
        is_End(node) is_Free(node)
        is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
@@ -514,7 +501,6 @@ static void vrp_first_pass(ir_node *n, void *e)
 
        vrp_update_node(env->info, n);
 
-       assure_irg_outs(get_irn_irg(n));
        for (i = get_irn_n_outs(n) - 1; i >=0; --i) {
                ir_node *succ = get_irn_out(n, i);
                if (bitset_is_set(env->visited, get_irn_idx(succ))) {