Commit f5c8b24c by Richard Sandiford Committed by Richard Sandiford

tree-core.h (tree_base): Document use of static_flag for SSA_NAME.

gcc/
	* tree-core.h (tree_base): Document use of static_flag for SSA_NAME.
	* tree.h (SSA_NAME_ANTI_RANGE_P, SSA_NAME_RANGE_TYPE): New macros.
	* tree-ssanames.h (set_range_info): Add range_type argument.
	(duplicate_ssa_name_range_info): Likewise.
	* tree-ssanames.c (set_range_info): Take the range type as argument
	and store it in SSA_NAME_ANTI_RANGE_P.
	(duplicate_ssa_name_range_info): Likewise.
	(get_range_info): Use SSA_NAME_ANTI_RANGE_P.
	(set_nonzero_bits): Update call to set_range_info.
	(duplicate_ssa_name_fn): Update call to duplicate_ssa_name_range_info.
	* tree-ssa-copy.c (fini_copy_prop): Likewise.
	* tree-vrp.c (remove_range_assertions): Update call to set_range_info.
	(vrp_finalize): Likewise, passing anti-ranges directly.

From-SVN: r205489
parent 3c716922
2013-11-28 Richard Sandiford <rdsandiford@googlemail.com>
* tree-core.h (tree_base): Document use of static_flag for SSA_NAME.
* tree.h (SSA_NAME_ANTI_RANGE_P, SSA_NAME_RANGE_TYPE): New macros.
* tree-ssanames.h (set_range_info): Add range_type argument.
(duplicate_ssa_name_range_info): Likewise.
* tree-ssanames.c (set_range_info): Take the range type as argument
and store it in SSA_NAME_ANTI_RANGE_P.
(duplicate_ssa_name_range_info): Likewise.
(get_range_info): Use SSA_NAME_ANTI_RANGE_P.
(set_nonzero_bits): Update call to set_range_info.
(duplicate_ssa_name_fn): Update call to duplicate_ssa_name_range_info.
* tree-ssa-copy.c (fini_copy_prop): Likewise.
* tree-vrp.c (remove_range_assertions): Update call to set_range_info.
(vrp_finalize): Likewise, passing anti-ranges directly.
2013-11-28 Richard Biener <rguenther@suse.de> 2013-11-28 Richard Biener <rguenther@suse.de>
PR tree-optimization/59330 PR tree-optimization/59330
...@@ -822,6 +822,9 @@ struct GTY(()) tree_base { ...@@ -822,6 +822,9 @@ struct GTY(()) tree_base {
TRANSACTION_EXPR_OUTER in TRANSACTION_EXPR_OUTER in
TRANSACTION_EXPR TRANSACTION_EXPR
SSA_NAME_ANTI_RANGE_P in
SSA_NAME
public_flag: public_flag:
TREE_OVERFLOW in TREE_OVERFLOW in
......
...@@ -576,6 +576,7 @@ fini_copy_prop (void) ...@@ -576,6 +576,7 @@ fini_copy_prop (void)
&& SSA_NAME_RANGE_INFO (var) && SSA_NAME_RANGE_INFO (var)
&& !SSA_NAME_RANGE_INFO (copy_of[i].value)) && !SSA_NAME_RANGE_INFO (copy_of[i].value))
duplicate_ssa_name_range_info (copy_of[i].value, duplicate_ssa_name_range_info (copy_of[i].value,
SSA_NAME_RANGE_TYPE (var),
SSA_NAME_RANGE_INFO (var)); SSA_NAME_RANGE_INFO (var));
} }
} }
......
...@@ -183,12 +183,14 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) ...@@ -183,12 +183,14 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
return t; return t;
} }
/* Store range information MIN, and MAX to tree ssa_name NAME. */ /* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name NAME. */
void void
set_range_info (tree name, double_int min, double_int max) set_range_info (tree name, enum value_range_type range_type, double_int min,
double_int max)
{ {
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
range_info_def *ri = SSA_NAME_RANGE_INFO (name); range_info_def *ri = SSA_NAME_RANGE_INFO (name);
/* Allocate if not available. */ /* Allocate if not available. */
...@@ -199,12 +201,16 @@ set_range_info (tree name, double_int min, double_int max) ...@@ -199,12 +201,16 @@ set_range_info (tree name, double_int min, double_int max)
ri->nonzero_bits = double_int::mask (TYPE_PRECISION (TREE_TYPE (name))); ri->nonzero_bits = double_int::mask (TYPE_PRECISION (TREE_TYPE (name)));
} }
/* Record the range type. */
if (SSA_NAME_RANGE_TYPE (name) != range_type)
SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
/* Set the values. */ /* Set the values. */
ri->min = min; ri->min = min;
ri->max = max; ri->max = max;
/* If it is a range, try to improve nonzero_bits from the min/max. */ /* If it is a range, try to improve nonzero_bits from the min/max. */
if (min.cmp (max, TYPE_UNSIGNED (TREE_TYPE (name))) != 1) if (range_type == VR_RANGE)
{ {
int prec = TYPE_PRECISION (TREE_TYPE (name)); int prec = TYPE_PRECISION (TREE_TYPE (name));
double_int xorv; double_int xorv;
...@@ -230,7 +236,6 @@ set_range_info (tree name, double_int min, double_int max) ...@@ -230,7 +236,6 @@ set_range_info (tree name, double_int min, double_int max)
enum value_range_type enum value_range_type
get_range_info (const_tree name, double_int *min, double_int *max) get_range_info (const_tree name, double_int *min, double_int *max)
{ {
enum value_range_type range_type;
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (min && max); gcc_assert (min && max);
range_info_def *ri = SSA_NAME_RANGE_INFO (name); range_info_def *ri = SSA_NAME_RANGE_INFO (name);
...@@ -241,22 +246,9 @@ get_range_info (const_tree name, double_int *min, double_int *max) ...@@ -241,22 +246,9 @@ get_range_info (const_tree name, double_int *min, double_int *max)
> 2 * HOST_BITS_PER_WIDE_INT)) > 2 * HOST_BITS_PER_WIDE_INT))
return VR_VARYING; return VR_VARYING;
/* If min > max, it is VR_ANTI_RANGE. */ *min = ri->min;
if (ri->min.cmp (ri->max, TYPE_UNSIGNED (TREE_TYPE (name))) == 1) *max = ri->max;
{ return SSA_NAME_RANGE_TYPE (name);
/* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1]. */
range_type = VR_ANTI_RANGE;
*min = ri->max + double_int_one;
*max = ri->min - double_int_one;
}
else
{
/* Otherwise (when min <= max), it is VR_RANGE. */
range_type = VR_RANGE;
*min = ri->min;
*max = ri->max;
}
return range_type;
} }
/* Change non-zero bits bitmask of NAME. */ /* Change non-zero bits bitmask of NAME. */
...@@ -266,7 +258,7 @@ set_nonzero_bits (tree name, double_int mask) ...@@ -266,7 +258,7 @@ set_nonzero_bits (tree name, double_int mask)
{ {
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
if (SSA_NAME_RANGE_INFO (name) == NULL) if (SSA_NAME_RANGE_INFO (name) == NULL)
set_range_info (name, set_range_info (name, VR_RANGE,
tree_to_double_int (TYPE_MIN_VALUE (TREE_TYPE (name))), tree_to_double_int (TYPE_MIN_VALUE (TREE_TYPE (name))),
tree_to_double_int (TYPE_MAX_VALUE (TREE_TYPE (name)))); tree_to_double_int (TYPE_MAX_VALUE (TREE_TYPE (name))));
range_info_def *ri = SSA_NAME_RANGE_INFO (name); range_info_def *ri = SSA_NAME_RANGE_INFO (name);
...@@ -495,15 +487,17 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) ...@@ -495,15 +487,17 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
SSA_NAME_PTR_INFO (name) = new_ptr_info; SSA_NAME_PTR_INFO (name) = new_ptr_info;
} }
/* Creates a duplicate of the range_info_def at RANGE_INFO for use by /* Creates a duplicate of the range_info_def at RANGE_INFO of type
the SSA name NAME. */ RANGE_TYPE for use by the SSA name NAME. */
void void
duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info) duplicate_ssa_name_range_info (tree name, enum value_range_type range_type,
struct range_info_def *range_info)
{ {
struct range_info_def *new_range_info; struct range_info_def *new_range_info;
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (!SSA_NAME_RANGE_INFO (name)); gcc_assert (!SSA_NAME_RANGE_INFO (name));
gcc_assert (!SSA_NAME_ANTI_RANGE_P (name));
if (!range_info) if (!range_info)
return; return;
...@@ -511,6 +505,8 @@ duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info) ...@@ -511,6 +505,8 @@ duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
new_range_info = ggc_alloc_range_info_def (); new_range_info = ggc_alloc_range_info_def ();
*new_range_info = *range_info; *new_range_info = *range_info;
gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
SSA_NAME_RANGE_INFO (name) = new_range_info; SSA_NAME_RANGE_INFO (name) = new_range_info;
} }
...@@ -535,7 +531,8 @@ duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt) ...@@ -535,7 +531,8 @@ duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name); struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
if (old_range_info) if (old_range_info)
duplicate_ssa_name_range_info (new_name, old_range_info); duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name),
old_range_info);
} }
return new_name; return new_name;
......
...@@ -70,7 +70,8 @@ struct GTY (()) range_info_def { ...@@ -70,7 +70,8 @@ struct GTY (()) range_info_def {
enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING }; enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
/* Sets the value range to SSA. */ /* Sets the value range to SSA. */
extern void set_range_info (tree, double_int, double_int); extern void set_range_info (tree, enum value_range_type, double_int,
double_int);
/* Gets the value range from SSA. */ /* Gets the value range from SSA. */
extern enum value_range_type get_range_info (const_tree, double_int *, extern enum value_range_type get_range_info (const_tree, double_int *,
double_int *); double_int *);
...@@ -93,7 +94,8 @@ extern struct ptr_info_def *get_ptr_info (tree); ...@@ -93,7 +94,8 @@ extern struct ptr_info_def *get_ptr_info (tree);
extern tree copy_ssa_name_fn (struct function *, tree, gimple); extern tree copy_ssa_name_fn (struct function *, tree, gimple);
extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
extern tree duplicate_ssa_name_fn (struct function *, tree, gimple); extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
extern void duplicate_ssa_name_range_info (tree, struct range_info_def *); extern void duplicate_ssa_name_range_info (tree, enum value_range_type,
struct range_info_def *);
extern void release_defs (gimple); extern void release_defs (gimple);
extern void replace_ssa_name_symbol (tree, tree); extern void replace_ssa_name_symbol (tree, tree);
......
...@@ -6596,7 +6596,8 @@ remove_range_assertions (void) ...@@ -6596,7 +6596,8 @@ remove_range_assertions (void)
&& all_imm_uses_in_stmt_or_feed_cond (var, stmt, && all_imm_uses_in_stmt_or_feed_cond (var, stmt,
single_pred (bb))) single_pred (bb)))
{ {
set_range_info (var, SSA_NAME_RANGE_INFO (lhs)->min, set_range_info (var, SSA_NAME_RANGE_TYPE (lhs),
SSA_NAME_RANGE_INFO (lhs)->min,
SSA_NAME_RANGE_INFO (lhs)->max); SSA_NAME_RANGE_INFO (lhs)->max);
maybe_set_nonzero_bits (bb, var); maybe_set_nonzero_bits (bb, var);
} }
...@@ -9602,36 +9603,12 @@ vrp_finalize (void) ...@@ -9602,36 +9603,12 @@ vrp_finalize (void)
continue; continue;
if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST) if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
&& (TREE_CODE (vr_value[i]->max) == INTEGER_CST)) && (TREE_CODE (vr_value[i]->max) == INTEGER_CST)
{ && (vr_value[i]->type == VR_RANGE
if (vr_value[i]->type == VR_RANGE) || vr_value[i]->type == VR_ANTI_RANGE))
set_range_info (name, set_range_info (name, vr_value[i]->type,
tree_to_double_int (vr_value[i]->min), tree_to_double_int (vr_value[i]->min),
tree_to_double_int (vr_value[i]->max)); tree_to_double_int (vr_value[i]->max));
else if (vr_value[i]->type == VR_ANTI_RANGE)
{
/* VR_ANTI_RANGE ~[min, max] is encoded compactly as
[max + 1, min - 1] without additional attributes.
When min value > max value, we know that it is
VR_ANTI_RANGE; it is VR_RANGE otherwise. */
/* ~[0,0] anti-range is represented as
range. */
if (TYPE_UNSIGNED (TREE_TYPE (name))
&& integer_zerop (vr_value[i]->min)
&& integer_zerop (vr_value[i]->max))
set_range_info (name,
double_int_one,
double_int::max_value
(TYPE_PRECISION (TREE_TYPE (name)), true));
else
set_range_info (name,
tree_to_double_int (vr_value[i]->max)
+ double_int_one,
tree_to_double_int (vr_value[i]->min)
- double_int_one);
}
}
} }
/* Free allocated memory. */ /* Free allocated memory. */
......
...@@ -1436,6 +1436,14 @@ extern void protected_set_expr_location (tree, location_t); ...@@ -1436,6 +1436,14 @@ extern void protected_set_expr_location (tree, location_t);
#define SSA_NAME_PTR_INFO(N) \ #define SSA_NAME_PTR_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.info.ptr_info SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
/* True if SSA_NAME_RANGE_INFO describes an anti-range. */
#define SSA_NAME_ANTI_RANGE_P(N) \
SSA_NAME_CHECK (N)->base.static_flag
/* The type of range described by SSA_NAME_RANGE_INFO. */
#define SSA_NAME_RANGE_TYPE(N) \
(SSA_NAME_ANTI_RANGE_P (N) ? VR_ANTI_RANGE : VR_RANGE)
/* Value range info attributes for SSA_NAMEs of non pointer-type variables. */ /* Value range info attributes for SSA_NAMEs of non pointer-type variables. */
#define SSA_NAME_RANGE_INFO(N) \ #define SSA_NAME_RANGE_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.info.range_info SSA_NAME_CHECK (N)->ssa_name.info.range_info
......
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