becopyilp: Do not advertise the switch to dump the solution, because this is not...
[libfirm] / ir / ana / vrp.c
index f6e01cd..fdc3b70 100644 (file)
@@ -1,27 +1,12 @@
 /*
- * 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.
  */
 
 /**
  * @file
  * @brief   analyze graph to provide value range information
  * @author  Jonas Fietz
- * @version $Id$
  */
 #include "config.h"
 
@@ -52,13 +37,12 @@ typedef struct vrp_env_t {
 
 static vrp_attr *vrp_get_or_set_info(ir_vrp_info *info, const ir_node *node)
 {
-       vrp_attr *attr = ir_nodemap_get(&info->infos, node);
+       vrp_attr *attr = ir_nodemap_get(vrp_attr, &info->infos, node);
        if (attr == NULL) {
                ir_mode *mode = get_irn_mode(node);
                assert(mode_is_int(mode));
 
-               attr = obstack_alloc(&info->obst, sizeof(*attr));
-               memset(attr, 0, sizeof(*attr));
+               attr = OALLOCZ(&info->obst, vrp_attr);
                attr->range_type   = VRP_UNDEFINED;
                attr->bits_set     = get_mode_null(mode);
                attr->bits_not_set = get_mode_all_one(mode);
@@ -75,7 +59,7 @@ vrp_attr *vrp_get_info(const ir_node *node)
        ir_graph *irg = get_irn_irg(node);
        if (irg->vrp.infos.data == NULL)
                return NULL;
-       return (vrp_attr*) ir_nodemap_get(&irg->vrp.infos, node);
+       return ir_nodemap_get(vrp_attr, &irg->vrp.infos, node);
 }
 
 static int vrp_update_node(ir_vrp_info *info, ir_node *node)
@@ -121,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;
        }
@@ -155,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;
        }
@@ -394,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)
@@ -424,7 +409,7 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
        /* Merge the newly calculated values with those that might already exist*/
        if (new_bits_set != tarval_bad) {
                new_bits_set = tarval_or(new_bits_set, vrp->bits_set);
-               if (tarval_cmp(new_bits_set, vrp->bits_set) != ir_relation_equal) {
+               if (new_bits_set != vrp->bits_set) {
                        something_changed = 1;
                        vrp->bits_set = new_bits_set;
                }
@@ -432,7 +417,7 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
        if (new_bits_not_set != tarval_bad) {
                new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set);
 
-               if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != ir_relation_equal) {
+               if (new_bits_not_set != vrp->bits_not_set) {
                        something_changed = 1;
                        vrp->bits_not_set = new_bits_not_set;
                }
@@ -516,7 +501,6 @@ static void vrp_first_pass(ir_node *n, void *e)
 
        vrp_update_node(env->info, n);
 
-       assure_irg_outs(get_current_ir_graph());
        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))) {
@@ -571,7 +555,7 @@ void set_vrp_data(ir_graph *irg)
                register_hook(hook_node_info, &dump_hook);
        }
 
-       env = obstack_alloc(&irg->vrp.obst, sizeof(*env));
+       env = OALLOCZ(&irg->vrp.obst, vrp_env_t);
        env->workqueue = new_waitq();
        env->info      = info;