aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2012-05-07 18:57:23 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2012-05-07 18:57:23 +0000
commitb48e22b2bd028164829281f676a1e39ede8c3910 (patch)
tree1e60a64abff9d4b063851acc1b758950b2694142
parent62beea506bd1a5c688e7b88457408411c8272635 (diff)
downloadgcc-b48e22b2bd028164829281f676a1e39ede8c3910.zip
gcc-b48e22b2bd028164829281f676a1e39ede8c3910.tar.gz
gcc-b48e22b2bd028164829281f676a1e39ede8c3910.tar.bz2
tree-dfa.c (get_ref_base_and_extent): Do the offset computation using the precision of the index type.
* tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset computation using the precision of the index type. * gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise. (fold_array_ctor_reference): Do index computations in the index type. From-SVN: r187268
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/gimple-fold.c36
-rw-r--r--gcc/tree-dfa.c21
3 files changed, 49 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 251edc6..0978365 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,11 @@
-2012-05-07 Georg-Johann Lay <avr@gjlay.de>
+2012-05-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset
+ computation using the precision of the index type.
+ * gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise.
+ (fold_array_ctor_reference): Do index computations in the index type.
+
+2012-05-07 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.c (avr_prologue_setup_frame): Fix mode passed
down to plus_constant.
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 90405e6..55e7344 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2745,7 +2745,7 @@ fold_array_ctor_reference (tree type, tree ctor,
double_int low_bound, elt_size;
double_int index, max_index;
double_int access_index;
- tree domain_type = NULL_TREE;
+ tree domain_type = NULL_TREE, index_type = NULL_TREE;
HOST_WIDE_INT inner_offset;
/* Compute low bound and elt size. */
@@ -2755,6 +2755,7 @@ fold_array_ctor_reference (tree type, tree ctor,
{
/* Static constructors for variably sized objects makes no sense. */
gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
+ index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
low_bound = tree_to_double_int (TYPE_MIN_VALUE (domain_type));
}
else
@@ -2778,6 +2779,10 @@ fold_array_ctor_reference (tree type, tree ctor,
access_index = double_int_udiv (uhwi_to_double_int (offset / BITS_PER_UNIT),
elt_size, TRUNC_DIV_EXPR);
access_index = double_int_add (access_index, low_bound);
+ if (index_type)
+ access_index = double_int_ext (access_index,
+ TYPE_PRECISION (index_type),
+ TYPE_UNSIGNED (index_type));
/* And offset within the access. */
inner_offset = offset % (double_int_to_uhwi (elt_size) * BITS_PER_UNIT);
@@ -2788,6 +2793,11 @@ fold_array_ctor_reference (tree type, tree ctor,
return NULL_TREE;
index = double_int_sub (low_bound, double_int_one);
+ if (index_type)
+ index = double_int_ext (index,
+ TYPE_PRECISION (index_type),
+ TYPE_UNSIGNED (index_type));
+
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
/* Array constructor might explicitely set index, or specify range
@@ -2805,7 +2815,14 @@ fold_array_ctor_reference (tree type, tree ctor,
}
}
else
- max_index = index = double_int_add (index, double_int_one);
+ {
+ index = double_int_add (index, double_int_one);
+ if (index_type)
+ index = double_int_ext (index,
+ TYPE_PRECISION (index_type),
+ TYPE_UNSIGNED (index_type));
+ max_index = index;
+ }
/* Do we have match? */
if (double_int_cmp (access_index, index, 1) >= 0
@@ -2960,18 +2977,23 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
&& valueize
&& (idx = (*valueize) (TREE_OPERAND (t, 1)))
- && host_integerp (idx, 0))
+ && TREE_CODE (idx) == INTEGER_CST)
{
tree low_bound, unit_size;
+ double_int doffset;
/* If the resulting bit-offset is constant, track it. */
if ((low_bound = array_ref_low_bound (t),
- host_integerp (low_bound, 0))
+ TREE_CODE (low_bound) == INTEGER_CST)
&& (unit_size = array_ref_element_size (t),
- host_integerp (unit_size, 1)))
+ host_integerp (unit_size, 1))
+ && (doffset = double_int_sext
+ (double_int_sub (TREE_INT_CST (idx),
+ TREE_INT_CST (low_bound)),
+ TYPE_PRECISION (TREE_TYPE (idx))),
+ double_int_fits_in_shwi_p (doffset)))
{
- offset = TREE_INT_CST_LOW (idx);
- offset -= TREE_INT_CST_LOW (low_bound);
+ offset = double_int_to_shwi (doffset);
offset *= TREE_INT_CST_LOW (unit_size);
offset *= BITS_PER_UNIT;
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 0ecec81..3494fc9 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -814,21 +814,24 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
{
tree index = TREE_OPERAND (exp, 1);
tree low_bound, unit_size;
+ double_int doffset;
/* If the resulting bit-offset is constant, track it. */
if (TREE_CODE (index) == INTEGER_CST
- && host_integerp (index, 0)
&& (low_bound = array_ref_low_bound (exp),
- host_integerp (low_bound, 0))
+ TREE_CODE (low_bound) == INTEGER_CST)
&& (unit_size = array_ref_element_size (exp),
- host_integerp (unit_size, 1)))
+ host_integerp (unit_size, 1))
+ && (doffset = double_int_sext
+ (double_int_sub (TREE_INT_CST (index),
+ TREE_INT_CST (low_bound)),
+ TYPE_PRECISION (TREE_TYPE (index))),
+ double_int_fits_in_shwi_p (doffset)))
{
- HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
-
- hindex -= TREE_INT_CST_LOW (low_bound);
- hindex *= TREE_INT_CST_LOW (unit_size);
- hindex *= BITS_PER_UNIT;
- bit_offset += hindex;
+ HOST_WIDE_INT hoffset = double_int_to_shwi (doffset);
+ hoffset *= TREE_INT_CST_LOW (unit_size);
+ hoffset *= BITS_PER_UNIT;
+ bit_offset += hoffset;
/* An array ref with a constant index up in the structure
hierarchy will constrain the size of any variable array ref