aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssanames.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-10-31 14:55:31 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-10-31 14:55:31 +0100
commitc853f62af3d69969bfca8e29c2ee17cb77fc6b1a (patch)
tree3f7b240bb836007eb44a47aff2ecae17e1a2a5ef /gcc/tree-ssanames.c
parentd8202b848c1d8b270fb9f82c8e91b507ec266cdb (diff)
downloadgcc-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.c60
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.