mirror of git://gcc.gnu.org/git/gcc.git
gimple-pretty-print.c (dump_ssaname_info): Print newline also in case of VR_VARYING.
* gimple-pretty-print.c (dump_ssaname_info): Print newline also in case of VR_VARYING. Print get_nonzero_bits if not all ones. * tree-ssanames.h (struct range_info_def): Add nonzero_bits field. (set_nonzero_bits, get_nonzero_bits): New prototypes. * tree-ssa-ccp.c (get_default_value): Use get_range_info to see if a default def isn't partially constant. (ccp_finalize): If after IPA, set_range_info if integral SSA_NAME is known to be partially zero. (evaluate_stmt): If we'd return otherwise VARYING, use get_range_info to see if a default def isn't partially constant. * tree-ssanames.c (set_range_info): Initialize nonzero_bits upon creation of a range, if VR_RANGE, try to improve nonzero_bits from the range. (set_nonzero_bits, get_nonzero_bits): New functions. * g++.dg/warn/pr33738.C (main): Initialize a2 again to make sure we warn about it already during VRP1 pass. From-SVN: r204256
This commit is contained in:
parent
d8202b848c
commit
c853f62af3
|
|
@ -1,5 +1,20 @@
|
|||
2013-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gimple-pretty-print.c (dump_ssaname_info): Print newline also
|
||||
in case of VR_VARYING. Print get_nonzero_bits if not all ones.
|
||||
* tree-ssanames.h (struct range_info_def): Add nonzero_bits field.
|
||||
(set_nonzero_bits, get_nonzero_bits): New prototypes.
|
||||
* tree-ssa-ccp.c (get_default_value): Use get_range_info to see if
|
||||
a default def isn't partially constant.
|
||||
(ccp_finalize): If after IPA, set_range_info if integral SSA_NAME
|
||||
is known to be partially zero.
|
||||
(evaluate_stmt): If we'd return otherwise VARYING, use get_range_info
|
||||
to see if a default def isn't partially constant.
|
||||
* tree-ssanames.c (set_range_info): Initialize nonzero_bits upon
|
||||
creation of a range, if VR_RANGE, try to improve nonzero_bits from
|
||||
the range.
|
||||
(set_nonzero_bits, get_nonzero_bits): New functions.
|
||||
|
||||
* tree-cfg.c (assert_unreachable_fallthru_edge_p): New function.
|
||||
* tree-cfg.h (assert_unreachable_fallthru_edge_p): New prototype.
|
||||
* tree-vrp.c (all_imm_uses_in_stmt_or_feed_cond): New function.
|
||||
|
|
|
|||
|
|
@ -1737,7 +1737,7 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
|
|||
if (!POINTER_TYPE_P (TREE_TYPE (node))
|
||||
&& SSA_NAME_RANGE_INFO (node))
|
||||
{
|
||||
double_int min, max;
|
||||
double_int min, max, nonzero_bits;
|
||||
value_range_type range_type = get_range_info (node, &min, &max);
|
||||
|
||||
if (range_type == VR_VARYING)
|
||||
|
|
@ -1750,8 +1750,20 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
|
|||
pp_printf (buffer, ", ");
|
||||
pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
|
||||
pp_printf (buffer, "]");
|
||||
newline_and_indent (buffer, spc);
|
||||
}
|
||||
nonzero_bits = get_nonzero_bits (node);
|
||||
if (nonzero_bits != double_int_minus_one
|
||||
&& (nonzero_bits
|
||||
!= double_int::mask (TYPE_PRECISION (TREE_TYPE (node)))))
|
||||
{
|
||||
pp_string (buffer, " NONZERO ");
|
||||
sprintf (pp_buffer (buffer)->digit_buffer,
|
||||
HOST_WIDE_INT_PRINT_DOUBLE_HEX,
|
||||
(unsigned HOST_WIDE_INT) nonzero_bits.high,
|
||||
nonzero_bits.low);
|
||||
pp_string (buffer, pp_buffer (buffer)->digit_buffer);
|
||||
}
|
||||
newline_and_indent (buffer, spc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2013-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* g++.dg/warn/pr33738.C (main): Initialize a2 again to make sure
|
||||
we warn about it already during VRP1 pass.
|
||||
|
||||
2013-10-31 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR rtl-optimization/58934
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ int main() {
|
|||
if (a2 == -1) { // { dg-warning "always false due" }
|
||||
link_error ();
|
||||
}
|
||||
a2 = static_cast<Alpha>(GetM1());
|
||||
if (-1 == a2) { // { dg-warning "always false due" }
|
||||
link_error ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,6 +260,19 @@ get_default_value (tree var)
|
|||
{
|
||||
val.lattice_val = VARYING;
|
||||
val.mask = double_int_minus_one;
|
||||
if (flag_tree_bit_ccp)
|
||||
{
|
||||
double_int nonzero_bits = get_nonzero_bits (var);
|
||||
double_int mask
|
||||
= double_int::mask (TYPE_PRECISION (TREE_TYPE (var)));
|
||||
if (nonzero_bits != double_int_minus_one && nonzero_bits != mask)
|
||||
{
|
||||
val.lattice_val = CONSTANT;
|
||||
val.value = build_zero_cst (TREE_TYPE (var));
|
||||
/* CCP wants the bits above precision set. */
|
||||
val.mask = nonzero_bits | ~mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_gimple_assign (stmt))
|
||||
|
|
@ -828,7 +841,8 @@ ccp_finalize (void)
|
|||
do_dbg_cnt ();
|
||||
|
||||
/* Derive alignment and misalignment information from partially
|
||||
constant pointers in the lattice. */
|
||||
constant pointers in the lattice or nonzero bits from partially
|
||||
constant integers. */
|
||||
for (i = 1; i < num_ssa_names; ++i)
|
||||
{
|
||||
tree name = ssa_name (i);
|
||||
|
|
@ -836,7 +850,11 @@ ccp_finalize (void)
|
|||
unsigned int tem, align;
|
||||
|
||||
if (!name
|
||||
|| !POINTER_TYPE_P (TREE_TYPE (name)))
|
||||
|| (!POINTER_TYPE_P (TREE_TYPE (name))
|
||||
&& (!INTEGRAL_TYPE_P (TREE_TYPE (name))
|
||||
/* Don't record nonzero bits before IPA to avoid
|
||||
using too much memory. */
|
||||
|| first_pass_instance)))
|
||||
continue;
|
||||
|
||||
val = get_value (name);
|
||||
|
|
@ -844,13 +862,24 @@ ccp_finalize (void)
|
|||
|| TREE_CODE (val->value) != INTEGER_CST)
|
||||
continue;
|
||||
|
||||
/* Trailing constant bits specify the alignment, trailing value
|
||||
bits the misalignment. */
|
||||
tem = val->mask.low;
|
||||
align = (tem & -tem);
|
||||
if (align > 1)
|
||||
set_ptr_info_alignment (get_ptr_info (name), align,
|
||||
TREE_INT_CST_LOW (val->value) & (align - 1));
|
||||
if (POINTER_TYPE_P (TREE_TYPE (name)))
|
||||
{
|
||||
/* Trailing mask bits specify the alignment, trailing value
|
||||
bits the misalignment. */
|
||||
tem = val->mask.low;
|
||||
align = (tem & -tem);
|
||||
if (align > 1)
|
||||
set_ptr_info_alignment (get_ptr_info (name), align,
|
||||
(TREE_INT_CST_LOW (val->value)
|
||||
& (align - 1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
double_int nonzero_bits = val->mask;
|
||||
nonzero_bits = nonzero_bits | tree_to_double_int (val->value);
|
||||
nonzero_bits &= get_nonzero_bits (name);
|
||||
set_nonzero_bits (name, nonzero_bits);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform substitutions based on the known constant values. */
|
||||
|
|
@ -1671,6 +1700,39 @@ evaluate_stmt (gimple stmt)
|
|||
is_constant = (val.lattice_val == CONSTANT);
|
||||
}
|
||||
|
||||
if (flag_tree_bit_ccp
|
||||
&& ((is_constant && TREE_CODE (val.value) == INTEGER_CST)
|
||||
|| (!is_constant && likelyvalue != UNDEFINED))
|
||||
&& gimple_get_lhs (stmt)
|
||||
&& TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME)
|
||||
{
|
||||
tree lhs = gimple_get_lhs (stmt);
|
||||
double_int nonzero_bits = get_nonzero_bits (lhs);
|
||||
double_int mask = double_int::mask (TYPE_PRECISION (TREE_TYPE (lhs)));
|
||||
if (nonzero_bits != double_int_minus_one && nonzero_bits != mask)
|
||||
{
|
||||
if (!is_constant)
|
||||
{
|
||||
val.lattice_val = CONSTANT;
|
||||
val.value = build_zero_cst (TREE_TYPE (lhs));
|
||||
/* CCP wants the bits above precision set. */
|
||||
val.mask = nonzero_bits | ~mask;
|
||||
is_constant = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
double_int valv = tree_to_double_int (val.value);
|
||||
if (!(valv & ~nonzero_bits & mask).is_zero ())
|
||||
val.value = double_int_to_tree (TREE_TYPE (lhs),
|
||||
valv & nonzero_bits);
|
||||
if (nonzero_bits.is_zero ())
|
||||
val.mask = double_int_zero;
|
||||
else
|
||||
val.mask = val.mask & (nonzero_bits | ~mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_constant)
|
||||
{
|
||||
/* The statement produced a nonconstant value. If the statement
|
||||
|
|
|
|||
|
|
@ -189,11 +189,30 @@ set_range_info (tree name, double_int min, double_int max)
|
|||
{
|
||||
ri = ggc_alloc_cleared_range_info_def ();
|
||||
SSA_NAME_RANGE_INFO (name) = ri;
|
||||
ri->nonzero_bits = double_int::mask (TYPE_PRECISION (TREE_TYPE (name)));
|
||||
}
|
||||
|
||||
/* Set the values. */
|
||||
ri->min = min;
|
||||
ri->max = 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)
|
||||
{
|
||||
int prec = TYPE_PRECISION (TREE_TYPE (name));
|
||||
double_int xorv;
|
||||
|
||||
min = min.zext (prec);
|
||||
max = max.zext (prec);
|
||||
xorv = min ^ max;
|
||||
if (xorv.high)
|
||||
xorv = double_int::mask (2 * HOST_BITS_PER_WIDE_INT
|
||||
- clz_hwi (xorv.high));
|
||||
else if (xorv.low)
|
||||
xorv = double_int::mask (HOST_BITS_PER_WIDE_INT
|
||||
- clz_hwi (xorv.low));
|
||||
ri->nonzero_bits = ri->nonzero_bits & (min | xorv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -233,6 +252,47 @@ get_range_info (tree name, double_int *min, double_int *max)
|
|||
return range_type;
|
||||
}
|
||||
|
||||
/* Change non-zero bits bitmask of NAME. */
|
||||
|
||||
void
|
||||
set_nonzero_bits (tree name, double_int mask)
|
||||
{
|
||||
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
|
||||
if (SSA_NAME_RANGE_INFO (name) == NULL)
|
||||
set_range_info (name,
|
||||
tree_to_double_int (TYPE_MIN_VALUE (TREE_TYPE (name))),
|
||||
tree_to_double_int (TYPE_MAX_VALUE (TREE_TYPE (name))));
|
||||
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
|
||||
ri->nonzero_bits
|
||||
= mask & double_int::mask (TYPE_PRECISION (TREE_TYPE (name)));
|
||||
}
|
||||
|
||||
/* Return a double_int with potentially non-zero bits in SSA_NAME
|
||||
NAME, or double_int_minus_one if unknown. */
|
||||
|
||||
double_int
|
||||
get_nonzero_bits (tree name)
|
||||
{
|
||||
if (POINTER_TYPE_P (TREE_TYPE (name)))
|
||||
{
|
||||
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
|
||||
if (pi && pi->align)
|
||||
{
|
||||
double_int al = double_int::from_uhwi (pi->align - 1);
|
||||
return ((double_int::mask (TYPE_PRECISION (TREE_TYPE (name))) & ~al)
|
||||
| double_int::from_uhwi (pi->misalign));
|
||||
}
|
||||
return double_int_minus_one;
|
||||
}
|
||||
|
||||
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
|
||||
if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
|
||||
> 2 * HOST_BITS_PER_WIDE_INT))
|
||||
return double_int_minus_one;
|
||||
|
||||
return ri->nonzero_bits;
|
||||
}
|
||||
|
||||
/* We no longer need the SSA_NAME expression VAR, release it so that
|
||||
it may be reused.
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ struct GTY (()) range_info_def {
|
|||
double_int min;
|
||||
/* Maximum for value range. */
|
||||
double_int max;
|
||||
/* Non-zero bits - bits not set are guaranteed to be always zero. */
|
||||
double_int nonzero_bits;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -68,10 +70,11 @@ struct GTY (()) range_info_def {
|
|||
enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
|
||||
|
||||
/* Sets the value range to SSA. */
|
||||
extern void set_range_info (tree ssa, double_int min, double_int max);
|
||||
extern void set_range_info (tree, double_int, double_int);
|
||||
/* Gets the value range from SSA. */
|
||||
extern enum value_range_type get_range_info (tree name, double_int *min,
|
||||
double_int *max);
|
||||
extern enum value_range_type get_range_info (tree, double_int *, double_int *);
|
||||
extern void set_nonzero_bits (tree, double_int);
|
||||
extern double_int get_nonzero_bits (tree);
|
||||
extern void init_ssanames (struct function *, int);
|
||||
extern void fini_ssanames (void);
|
||||
extern void ssanames_print_statistics (void);
|
||||
|
|
|
|||
Loading…
Reference in New Issue