diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-10-31 14:55:31 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-10-31 14:55:31 +0100 |
commit | c853f62af3d69969bfca8e29c2ee17cb77fc6b1a (patch) | |
tree | 3f7b240bb836007eb44a47aff2ecae17e1a2a5ef /gcc/tree-ssanames.c | |
parent | d8202b848c1d8b270fb9f82c8e91b507ec266cdb (diff) | |
download | gcc-c853f62af3d69969bfca8e29c2ee17cb77fc6b1a.zip gcc-c853f62af3d69969bfca8e29c2ee17cb77fc6b1a.tar.gz gcc-c853f62af3d69969bfca8e29c2ee17cb77fc6b1a.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-ssanames.c')
-rw-r--r-- | gcc/tree-ssanames.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 435cdc7..00bd436 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -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. |