diff options
author | Richard Biener <rguenther@suse.de> | 2018-05-18 10:12:20 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-05-18 10:12:20 +0000 |
commit | 6b9fc1782effc67dd9f6def16207653d79647553 (patch) | |
tree | fd645ec37779713599dd830519f77baa421a0e2a /gcc/tree-dfa.c | |
parent | 5f007d14ce68073906656b725938a3be2625435b (diff) | |
download | gcc-6b9fc1782effc67dd9f6def16207653d79647553.zip gcc-6b9fc1782effc67dd9f6def16207653d79647553.tar.gz gcc-6b9fc1782effc67dd9f6def16207653d79647553.tar.bz2 |
tree-dfa.c (get_ref_base_and_extent): Use range-info to refine results when processing array refs with variable index.
2018-05-18 Richard Biener <rguenther@suse.de>
* tree-dfa.c (get_ref_base_and_extent): Use range-info to refine
results when processing array refs with variable index.
* gcc.dg/tree-ssa/ssa-dse-35.c: New testcase.
* gcc.dg/graphite/scop-10.c: Adjust to avoid dead code.
* gcc.dg/graphite/scop-6.c: Likewise.
* gcc.dg/graphite/scop-7.c: Likewise.
* gcc.dg/graphite/scop-8.c: Likewise.
* gcc.dg/graphite/scop-9.c: Likewise.
From-SVN: r260354
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index a121b88..00aa75f 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -529,6 +529,49 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset, /* Remember that we have seen an array ref with a variable index. */ seen_variable_array_ref = true; + + wide_int min, max; + if (TREE_CODE (index) == SSA_NAME + && (low_bound = array_ref_low_bound (exp), + poly_int_tree_p (low_bound)) + && (unit_size = array_ref_element_size (exp), + TREE_CODE (unit_size) == INTEGER_CST) + && get_range_info (index, &min, &max) == VR_RANGE) + { + poly_offset_int lbound = wi::to_poly_offset (low_bound); + /* Try to constrain maxsize with range information. */ + offset_int omax + = offset_int::from (max, TYPE_SIGN (TREE_TYPE (index))); + if (known_lt (lbound, omax)) + { + poly_offset_int rmaxsize; + rmaxsize = (omax - lbound + 1) + * wi::to_offset (unit_size) << LOG2_BITS_PER_UNIT; + if (!known_size_p (maxsize) + || known_lt (rmaxsize, maxsize)) + { + /* If we know an upper bound below the declared + one this is no longer variable. */ + if (known_size_p (maxsize)) + seen_variable_array_ref = false; + maxsize = rmaxsize; + } + } + /* Try to adjust bit_offset with range information. */ + offset_int omin + = offset_int::from (min, TYPE_SIGN (TREE_TYPE (index))); + if (known_le (lbound, omin)) + { + poly_offset_int woffset + = wi::sext (omin - lbound, + TYPE_PRECISION (TREE_TYPE (index))); + woffset *= wi::to_offset (unit_size); + woffset <<= LOG2_BITS_PER_UNIT; + bit_offset += woffset; + if (known_size_p (maxsize)) + maxsize -= woffset; + } + } } } break; |