mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-23 21:31:54 +08:00
tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Remove special casing of constant qualifiers.
2008-03-20 Richard Guenther <rguenther@suse.de> * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Remove special casing of constant qualifiers. * tree-ssa.c (useless_type_conversion_p_1): Instead do not care about them in general. * tree-ssa-ccp.c (ccp_fold): Addresses are constant or not regardless of their type. (fold_stmt_r): Forcefully fold *& if we end up with that. * gcc.dg/tree-ssa/ssa-ccp-17.c: New testcase. From-SVN: r133400
This commit is contained in:
parent
44b6c54658
commit
16ac857550
@ -1,3 +1,13 @@
|
||||
2008-03-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Remove
|
||||
special casing of constant qualifiers.
|
||||
* tree-ssa.c (useless_type_conversion_p_1): Instead do not
|
||||
care about them in general.
|
||||
* tree-ssa-ccp.c (ccp_fold): Addresses are constant or not
|
||||
regardless of their type.
|
||||
(fold_stmt_r): Forcefully fold *& if we end up with that.
|
||||
|
||||
2008-03-20 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config.gcc (arm*-*-uclinux*): Remove duplicate arm/uclinux-elf.h.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-03-20 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-ccp-17.c: New testcase.
|
||||
|
||||
2008-03-20 Victor Kaplansky <victork@gcc.gnu.org>
|
||||
Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
|
32
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-17.c
Normal file
32
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-17.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-ccp1" } */
|
||||
|
||||
int foo(void)
|
||||
{
|
||||
int i = 0;
|
||||
char *p = (char *)&i;
|
||||
return *(int *)p;
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
int i;
|
||||
} f;
|
||||
|
||||
int bar(void)
|
||||
{
|
||||
char *p = (char *)&f;
|
||||
return ((struct Foo *)p)->i;
|
||||
}
|
||||
|
||||
const struct Foo g;
|
||||
|
||||
int foobar(void)
|
||||
{
|
||||
struct Foo *p = (struct Foo *)&g;
|
||||
return ((const struct Foo *)p)->i;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "= i;" "ccp1" } } */
|
||||
/* { dg-final { scan-tree-dump "= f.i;" "ccp1" } } */
|
||||
/* { dg-final { scan-tree-dump "= g.i;" "ccp1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "ccp1" } } */
|
@ -947,8 +947,15 @@ ccp_fold (tree stmt)
|
||||
op0 = get_value (op0)->value;
|
||||
}
|
||||
|
||||
/* Conversions are useless for CCP purposes if they are
|
||||
value-preserving. Thus the restrictions that
|
||||
useless_type_conversion_p places for pointer type conversions do
|
||||
not apply here. Substitution later will only substitute to
|
||||
allowed places. */
|
||||
if ((code == NOP_EXPR || code == CONVERT_EXPR)
|
||||
&& useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (op0)))
|
||||
&& ((POINTER_TYPE_P (TREE_TYPE (rhs))
|
||||
&& POINTER_TYPE_P (TREE_TYPE (op0)))
|
||||
|| useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (op0))))
|
||||
return op0;
|
||||
return fold_unary (code, TREE_TYPE (rhs), op0);
|
||||
}
|
||||
@ -2160,6 +2167,11 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
|
||||
|
||||
t = maybe_fold_stmt_indirect (expr, TREE_OPERAND (expr, 0),
|
||||
integer_zero_node);
|
||||
if (!t
|
||||
&& TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
|
||||
/* If we had a good reason for propagating the address here,
|
||||
make sure we end up with valid gimple. See PR34989. */
|
||||
t = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
|
||||
break;
|
||||
|
||||
case NOP_EXPR:
|
||||
|
@ -601,14 +601,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
|
||||
propagate the ADDR_EXPR into the use of NAME and fold the result. */
|
||||
if (TREE_CODE (lhs) == INDIRECT_REF
|
||||
&& TREE_OPERAND (lhs, 0) == name
|
||||
/* This will not allow stripping const qualification from
|
||||
pointers which we want to allow specifically here to clean up
|
||||
the IL for initialization of constant objects. */
|
||||
&& (useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (lhs, 0)),
|
||||
TREE_TYPE (def_rhs))
|
||||
/* So explicitly check for this here. */
|
||||
|| (TYPE_QUALS (TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0))))
|
||||
^ TYPE_QUALS (TREE_TYPE (TREE_TYPE (def_rhs)))) == TYPE_QUAL_CONST)
|
||||
&& useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (lhs, 0)),
|
||||
TREE_TYPE (def_rhs))
|
||||
/* ??? This looks redundant, but is required for bogus types
|
||||
that can sometimes occur. */
|
||||
&& useless_type_conversion_p (TREE_TYPE (lhs),
|
||||
@ -635,13 +629,10 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
|
||||
propagate the ADDR_EXPR into the use of NAME and fold the result. */
|
||||
if (TREE_CODE (rhs) == INDIRECT_REF
|
||||
&& TREE_OPERAND (rhs, 0) == name
|
||||
/* ??? This doesn't allow stripping const qualification to
|
||||
streamline the IL for reads from non-constant objects. */
|
||||
&& (useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (rhs, 0)),
|
||||
TREE_TYPE (def_rhs))
|
||||
/* So explicitly check for this here. */
|
||||
|| (TYPE_QUALS (TREE_TYPE (TREE_TYPE (TREE_OPERAND (rhs, 0))))
|
||||
^ TYPE_QUALS (TREE_TYPE (TREE_TYPE (def_rhs)))) == TYPE_QUAL_CONST)
|
||||
&& useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (rhs, 0)),
|
||||
TREE_TYPE (def_rhs))
|
||||
/* ??? This looks redundant, but is required for bogus types
|
||||
that can sometimes occur. */
|
||||
&& useless_type_conversion_p (TREE_TYPE (rhs),
|
||||
TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
|
||||
{
|
||||
|
@ -1117,12 +1117,8 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
|
||||
!= get_alias_set (TREE_TYPE (outer_type))))
|
||||
return false;
|
||||
|
||||
/* Do not lose casts from const qualified to non-const
|
||||
qualified. */
|
||||
if ((TYPE_READONLY (TREE_TYPE (outer_type))
|
||||
!= TYPE_READONLY (TREE_TYPE (inner_type)))
|
||||
&& TYPE_READONLY (TREE_TYPE (inner_type)))
|
||||
return false;
|
||||
/* We do not care for const qualification of the pointed-to types
|
||||
as const qualification has no semantic value to the middle-end. */
|
||||
|
||||
/* Do not lose casts to restrict qualified pointers. */
|
||||
if ((TYPE_RESTRICT (outer_type)
|
||||
|
Loading…
x
Reference in New Issue
Block a user