* [PATCH][mem-ref2] Even more array-ref folding
@ 2010-06-19 21:27 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-06-19 21:27 UTC (permalink / raw)
To: gcc-patches
This fixes the remaining array-bounds and objsize fails by
relaxing the array-refs we can create from maybe_fold_offset_to_array_ref.
On the trunk we are doing the same foldings but via fold_binary
or via forwprop. Thus this aligns the third copy of array-ref
folding (ugh) to what the others do. Merging them is for
further excercising.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
the branch.
No major show-stoppers remain. IMHO the branch is ready to merge.
Richard.
2010-06-19 Richard Guenther <rguenther@suse.de>
* gimple-fold.c (maybe_fold_offset_to_array_ref): Allow
possibly out-of bounds accesses if the array has just
one dimension. Remove always true parameter.
(maybe_fold_offset_to_reference): Update caller.
(maybe_fold_offset_to_address): Likewise.
(maybe_fold_stmt_addition): Likewise.
* tree-object-size.c (plus_stmt_object_size): Handle MEM_REF.
(collect_object_sizes_for): Dispatch to plus_stmt_object_size
for &MEM_REF.
Index: mem-ref2/gcc/gimple-fold.c
===================================================================
*** mem-ref2.orig/gcc/gimple-fold.c 2010-06-19 18:28:50.000000000 +0200
--- mem-ref2/gcc/gimple-fold.c 2010-06-19 18:28:55.000000000 +0200
*************** may_propagate_address_into_dereference (
*** 113,120 ****
LOC is the location of the original expression. */
static tree
! maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset,
! bool allow_negative_idx)
{
tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
tree array_type, elt_type, elt_size;
--- 113,119 ----
LOC is the location of the original expression. */
static tree
! maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset)
{
tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
tree array_type, elt_type, elt_size;
*************** maybe_fold_offset_to_array_ref (location
*** 215,248 ****
char *(c[4]);
c[3][2];
should not be simplified into (*c)[14] or tree-vrp will
! give false warnings. The same is true for
! struct A { long x; char d[0]; } *a;
! (char *)a - 4;
! which should be not folded to &a->d[-8]. */
! if (domain_type
! && TYPE_MAX_VALUE (domain_type)
! && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST)
! {
! tree up_bound = TYPE_MAX_VALUE (domain_type);
!
! if (tree_int_cst_lt (up_bound, idx)
! /* Accesses after the end of arrays of size 0 (gcc
! extension) and 1 are likely intentional ("struct
! hack"). */
! && compare_tree_int (up_bound, 1) > 0)
return NULL_TREE;
! }
! if (domain_type
! && TYPE_MIN_VALUE (domain_type))
! {
! if (!allow_negative_idx
! && TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST
! && tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type)))
return NULL_TREE;
}
- else if (!allow_negative_idx
- && compare_tree_int (idx, 0) < 0)
- return NULL_TREE;
{
tree t = build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
--- 214,235 ----
char *(c[4]);
c[3][2];
should not be simplified into (*c)[14] or tree-vrp will
! give false warnings.
! This is only an issue for multi-dimensional arrays. */
! if (TREE_CODE (elt_type) == ARRAY_TYPE
! && domain_type)
! {
! if (TYPE_MAX_VALUE (domain_type)
! && TREE_CODE (TYPE_MAX_VALUE (domain_type)) == INTEGER_CST
! && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type), idx))
return NULL_TREE;
! else if (TYPE_MIN_VALUE (domain_type)
! && TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST
! && tree_int_cst_lt (idx, TYPE_MIN_VALUE (domain_type)))
! return NULL_TREE;
! else if (compare_tree_int (idx, 0) < 0)
return NULL_TREE;
}
{
tree t = build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
*************** maybe_fold_offset_to_reference (location
*** 272,278 ****
&& integer_zerop (offset))
return base;
! ret = maybe_fold_offset_to_array_ref (loc, base, offset, true);
if (ret && useless_type_conversion_p (orig_type, TREE_TYPE (ret)))
return ret;
return NULL_TREE;
--- 259,265 ----
&& integer_zerop (offset))
return base;
! ret = maybe_fold_offset_to_array_ref (loc, base, offset);
if (ret && useless_type_conversion_p (orig_type, TREE_TYPE (ret)))
return ret;
return NULL_TREE;
*************** maybe_fold_offset_to_address (location_t
*** 291,297 ****
if (TREE_CODE (addr) != ADDR_EXPR)
return NULL_TREE;
base = TREE_OPERAND (addr, 0);
! ret = maybe_fold_offset_to_array_ref (loc, base, offset, true);
if (ret)
{
ret = build_fold_addr_expr (ret);
--- 278,284 ----
if (TREE_CODE (addr) != ADDR_EXPR)
return NULL_TREE;
base = TREE_OPERAND (addr, 0);
! ret = maybe_fold_offset_to_array_ref (loc, base, offset);
if (ret)
{
ret = build_fold_addr_expr (ret);
*************** maybe_fold_stmt_addition (location_t loc
*** 529,535 ****
ptd_type = TREE_TYPE (TREE_TYPE (op0));
/* At which point we can try some of the same things as for indirects. */
! t = maybe_fold_offset_to_array_ref (loc, op0, op1, true);
if (t)
{
t = build_fold_addr_expr (t);
--- 516,522 ----
ptd_type = TREE_TYPE (TREE_TYPE (op0));
/* At which point we can try some of the same things as for indirects. */
! t = maybe_fold_offset_to_array_ref (loc, op0, op1);
if (t)
{
t = build_fold_addr_expr (t);
Index: mem-ref2/gcc/tree-object-size.c
===================================================================
*** mem-ref2.orig/gcc/tree-object-size.c 2010-06-19 18:31:10.000000000 +0200
--- mem-ref2/gcc/tree-object-size.c 2010-06-19 18:31:12.000000000 +0200
*************** plus_stmt_object_size (struct object_siz
*** 762,771 ****
unsigned HOST_WIDE_INT bytes;
tree op0, op1;
! gcc_assert (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR);
!
! op0 = gimple_assign_rhs1 (stmt);
! op1 = gimple_assign_rhs2 (stmt);
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
--- 762,781 ----
unsigned HOST_WIDE_INT bytes;
tree op0, op1;
! if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
! {
! op0 = gimple_assign_rhs1 (stmt);
! op1 = gimple_assign_rhs2 (stmt);
! }
! else if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
! {
! tree rhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
! gcc_assert (TREE_CODE (rhs) == MEM_REF);
! op0 = TREE_OPERAND (rhs, 0);
! op1 = TREE_OPERAND (rhs, 1);
! }
! else
! gcc_unreachable ();
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
*************** collect_object_sizes_for (struct object_
*** 913,925 ****
{
case GIMPLE_ASSIGN:
{
! if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
reexamine = plus_stmt_object_size (osi, var, stmt);
else if (gimple_assign_single_p (stmt)
|| gimple_assign_unary_nop_p (stmt))
{
- tree rhs = gimple_assign_rhs1 (stmt);
-
if (TREE_CODE (rhs) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (rhs)))
reexamine = merge_object_sizes (osi, var, rhs, 0);
--- 923,936 ----
{
case GIMPLE_ASSIGN:
{
! tree rhs = gimple_assign_rhs1 (stmt);
! if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
! || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
! && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
reexamine = plus_stmt_object_size (osi, var, stmt);
else if (gimple_assign_single_p (stmt)
|| gimple_assign_unary_nop_p (stmt))
{
if (TREE_CODE (rhs) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (rhs)))
reexamine = merge_object_sizes (osi, var, rhs, 0);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-06-19 17:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-19 21:27 [PATCH][mem-ref2] Even more array-ref folding Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).