Commit 3cc98a48 authored by Matthias Braun's avatar Matthias Braun
Browse files

tv: simplify tv overflow mode

Remove the unused OVERFLOW_SATURE case and switch the type to a simple
wrap_on_overflow bool.
parent bdfacec1
......@@ -287,24 +287,15 @@ FIRM_API ir_tarval *tarval_b_true;
/** Returns the mode_b tarval 'true'. */
FIRM_API ir_tarval *get_tarval_b_true(void);
/** Modes for handling integer overflows. */
typedef enum tarval_int_overflow_mode_t {
TV_OVERFLOW_BAD, /**< tarval module will return tarval_bad if an overflow occurs */
TV_OVERFLOW_WRAP, /**< overflow will be ignored, wrap around occurs */
TV_OVERFLOW_SATURATE /**< tarval module will saturate the overflow */
} tarval_int_overflow_mode_t;
/**
* Sets the overflow mode for integer operations.
*
* @param ov_mode one of the overflow modes
* Sets whether values should wrap on overflow or return the bad value.
*/
FIRM_API void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode);
FIRM_API void tarval_set_wrap_on_overflow(int wrap_on_overflow);
/**
* Returns the overflow mode for integer operations.
* Returns 0 if operations return bad on overflow, != 0 if they wrap around.
*/
FIRM_API tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void);
FIRM_API int tarval_get_wrap_on_overflow(void);
/**
* Compares two tarvals
......
......@@ -414,7 +414,7 @@ void dca_analyze(ir_graph *irg)
DB((dbg, LEVEL_1, "===> Performing don't care bit analysis on %+F\n", irg));
assert(tarval_get_integer_overflow_mode() == TV_OVERFLOW_WRAP);
assert(tarval_get_wrap_on_overflow());
assert(((ir_resources_reserved(irg) & IR_RESOURCE_IRN_LINK) != 0) &&
"user of dc analysis must reserve links");
......
......@@ -112,13 +112,13 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
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);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
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);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
if (new_top != tarval_bad && new_bottom != tarval_bad) {
new_range_bottom = new_bottom;
......@@ -151,11 +151,11 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
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);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
ir_tarval *new_top = tarval_sub(vrp_left->range_top, vrp_right->range_bottom, NULL);
ir_tarval *new_bottom = tarval_sub(vrp_left->range_bottom, vrp_right->range_top, NULL);
tarval_set_integer_overflow_mode(rem);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
if (new_top != tarval_bad && new_bottom != tarval_bad) {
new_range_bottom = new_bottom;
......
......@@ -75,8 +75,8 @@ static carry_result lower_add_carry(ir_node *left, ir_node *right, ir_mode *mode
ir_tarval *rmax = tarval_convert_to(bitinfo_max(bi_right), mode);
carry_result result = no_carry;
tarval_int_overflow_mode_t ofm = tarval_get_integer_overflow_mode();
tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
if (tarval_add(lmax, rmax) == tarval_bad) {
result = can_carry;
......@@ -85,7 +85,7 @@ static carry_result lower_add_carry(ir_node *left, ir_node *right, ir_mode *mode
}
}
tarval_set_integer_overflow_mode(ofm);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
return result;
}
......@@ -109,8 +109,8 @@ static carry_result lower_sub_borrow(ir_node *left, ir_node *right, ir_mode *mod
ir_tarval *rmax = tarval_convert_to(bitinfo_max(bi_right), mode);
carry_result result = no_carry;
tarval_int_overflow_mode_t ofm = tarval_get_integer_overflow_mode();
tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
if (tarval_sub(lmin, rmax, NULL) == tarval_bad) {
result = can_carry;
......@@ -119,7 +119,7 @@ static carry_result lower_sub_borrow(ir_node *left, ir_node *right, ir_mode *mod
}
}
tarval_set_integer_overflow_mode(ofm);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
return result;
}
......
......@@ -629,8 +629,7 @@ struct ms {
static struct ms magic(ir_tarval *d)
{
/* we need overflow mode to work correctly */
tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
assert(tarval_get_wrap_on_overflow());
ir_mode *mode = get_tarval_mode(d);
ir_mode *u_mode = find_unsigned_mode(mode);
......@@ -690,8 +689,6 @@ static struct ms magic(ir_tarval *d)
/* need a sub if d < 0 && M > 0 */
mag.need_sub = d_cmp & ir_relation_less && M_cmp & ir_relation_greater;
tarval_set_integer_overflow_mode(rem);
return mag;
}
......
......@@ -4872,12 +4872,10 @@ static ir_node *transform_node_Cmp(ir_node *n)
ir_mode *mode_left = get_irn_mode(op_left);
if (smaller_mode(mode_left, mode) && mode_left != mode_b) {
ir_tarval *tv = get_Const_tarval(right);
tarval_int_overflow_mode_t last_mode
= tarval_get_integer_overflow_mode();
ir_tarval *new_tv;
tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
new_tv = tarval_convert_to(tv, mode_left);
tarval_set_integer_overflow_mode(last_mode);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
ir_tarval *new_tv = tarval_convert_to(tv, mode_left);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
if (tarval_is_constant(new_tv)) {
left = op_left;
right = new_r_Const(irg, new_tv);
......
......@@ -1035,8 +1035,8 @@ static ir_node *apply_one_edge(ir_node *iv, ir_node *rc, ldtr_edge_t *e,
ir_tarval *tv_l = get_Const_tarval(rc);
ir_tarval *tv_r = get_Const_tarval(e->rc);
tarval_int_overflow_mode_t ovmode = tarval_get_integer_overflow_mode();
tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
tarval_set_wrap_on_overflow(false);
scc *pscc = get_iv_scc(iv, env);
ir_tarval *tv_incr = pscc->incr;
......@@ -1071,14 +1071,14 @@ static ir_node *apply_one_edge(ir_node *iv, ir_node *rc, ldtr_edge_t *e,
}
if (tv == tarval_bad || tv_init == tarval_bad) {
tarval_set_integer_overflow_mode(ovmode);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
DB((dbg, LEVEL_4, " = OVERFLOW"));
return NULL;
}
/* backwards counting in unsigned modes easily leads to overflow
* in the increment. TODO: improve this situation */
if (tv_incr == tarval_bad) {
tarval_set_integer_overflow_mode(ovmode);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
DB((dbg, LEVEL_4, " = OVERFLOW (incr)"));
return NULL;
}
......@@ -1091,7 +1091,7 @@ static ir_node *apply_one_edge(ir_node *iv, ir_node *rc, ldtr_edge_t *e,
tv_end = tarval_sub(tv, tv_incr, NULL);
}
tarval_set_integer_overflow_mode(ovmode);
tarval_set_wrap_on_overflow(old_wrap_on_overflow);
if (tv_end == tarval_bad) {
DB((dbg, LEVEL_4, " = OVERFLOW"));
......
......@@ -50,7 +50,7 @@ static struct set *tarvals = NULL;
static unsigned sc_value_length;
/** The integer overflow mode. */
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
static bool wrap_on_overflow = true;
/** Hash a value. Treat it as a byte array. */
static unsigned hash_val(unsigned char const *value, size_t length)
......@@ -130,10 +130,7 @@ static ir_tarval *get_tarval_overflow(const void *value, size_t length,
case irms_int_number:
if (sc_comp(value, get_mode_max(mode)->value) == ir_relation_greater) {
switch (tarval_get_integer_overflow_mode()) {
case TV_OVERFLOW_SATURATE:
return get_mode_max(mode);
case TV_OVERFLOW_WRAP: {
if (wrap_on_overflow) {
sc_word *temp = ALLOCAN(sc_word, sc_value_length);
memcpy(temp, value, sc_value_length);
unsigned bits = get_mode_size_bits(mode);
......@@ -144,26 +141,17 @@ static ir_tarval *get_tarval_overflow(const void *value, size_t length,
sc_zero_extend(temp, bits);
}
return get_tarval(temp, length, mode);
}
case TV_OVERFLOW_BAD:
} else {
return tarval_bad;
default:
return get_tarval(value, length, mode);
}
}
if (sc_comp(value, get_mode_min(mode)->value) == ir_relation_less) {
switch (tarval_get_integer_overflow_mode()) {
case TV_OVERFLOW_SATURATE:
return get_mode_min(mode);
case TV_OVERFLOW_WRAP: {
if (wrap_on_overflow) {
sc_word *temp = ALLOCAN(sc_word, sc_value_length);
memcpy(temp, value, sc_value_length);
return get_tarval(temp, length, mode);
}
case TV_OVERFLOW_BAD:
} else {
return tarval_bad;
default:
return get_tarval(value, length, mode);
}
}
break;
......@@ -1449,14 +1437,14 @@ int tarval_is_finite(const ir_tarval *tv)
return 1;
}
void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode)
void tarval_set_wrap_on_overflow(int new_wrap_on_overflow)
{
int_overflow_mode = ov_mode;
wrap_on_overflow = new_wrap_on_overflow;
}
tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void)
int tarval_get_wrap_on_overflow(void)
{
return int_overflow_mode;
return wrap_on_overflow;
}
static ir_tarval *make_b_tarval(unsigned char const val)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment