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-ssa-ccp.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-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 80 |
1 files changed, 71 insertions, 9 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index d30bd8b..5b6c0db 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -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 |