[multiple changes]

2005-05-18  Richard Guenther  <rguenth@gcc.gnu.org>

        * tree-inline.c (copy_body_r): Manually fold *& to deal
        with ADDR_EXPRs with mismatched types for now.

2005-05-17  Richard Guenther  <rguenth@gcc.gnu.org>

        * gimplify.c (fold_indirect_ref_rhs): New function.
        (gimplify_modify_expr_rhs): Use it instead of pessimistic
        fold_indirect_ref.

2005-05-15  Richard Guenther  <rguenth@gcc.gnu.org>

        * fold-const.c (fold_indirect_ref_1): Add type argument;
        make sure the resulting expression is of this type.
        (build_fold_indirect_ref, fold_indirect_ref): Adjust callers.

From-SVN: r100267
This commit is contained in:
Richard Guenther 2005-05-27 17:23:30 +00:00 committed by Jeff Law
parent 46aad78f22
commit 30d2e94365
4 changed files with 94 additions and 14 deletions

View file

@ -1,3 +1,16 @@
2005-05-27 Richard Guenther <rguenth@gcc.gnu.org>
* tree-inline.c (copy_body_r): Manually fold *& to deal
with ADDR_EXPRs with mismatched types for now.
* gimplify.c (fold_indirect_ref_rhs): New function.
(gimplify_modify_expr_rhs): Use it instead of pessimistic
fold_indirect_ref.
* fold-const.c (fold_indirect_ref_1): Add type argument;
make sure the resulting expression is of this type.
(build_fold_indirect_ref, fold_indirect_ref): Adjust callers.
2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/21658

View file

@ -11451,14 +11451,14 @@ build_fold_addr_expr (tree t)
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
}
/* Given a pointer value T, return a simplified version of an indirection
through T, or NULL_TREE if no simplification is possible. */
/* Given a pointer value OP0 and a type TYPE, return a simplified version
of an indirection through OP0, or NULL_TREE if no simplification is
possible. */
static tree
fold_indirect_ref_1 (tree t)
fold_indirect_ref_1 (tree type, tree op0)
{
tree type = TREE_TYPE (TREE_TYPE (t));
tree sub = t;
tree sub = op0;
tree subtype;
STRIP_NOPS (sub);
@ -11471,11 +11471,11 @@ fold_indirect_ref_1 (tree t)
tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op);
/* *&p => p */
if (lang_hooks.types_compatible_p (type, optype))
if (type == optype)
return op;
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
&& type == TREE_TYPE (optype))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
@ -11487,7 +11487,7 @@ fold_indirect_ref_1 (tree t)
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
&& type == TREE_TYPE (TREE_TYPE (subtype)))
{
tree type_domain;
tree min_val = size_zero_node;
@ -11507,12 +11507,13 @@ fold_indirect_ref_1 (tree t)
tree
build_fold_indirect_ref (tree t)
{
tree sub = fold_indirect_ref_1 (t);
tree type = TREE_TYPE (TREE_TYPE (t));
tree sub = fold_indirect_ref_1 (type, t);
if (sub)
return sub;
else
return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
return build1 (INDIRECT_REF, type, t);
}
/* Given an INDIRECT_REF T, return either T or a simplified version. */
@ -11520,7 +11521,7 @@ build_fold_indirect_ref (tree t)
tree
fold_indirect_ref (tree t)
{
tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
if (sub)
return sub;

View file

@ -2846,6 +2846,62 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
return GS_ALL_DONE;
}
/* Given a pointer value OP0, return a simplified version of an
indirection through OP0, or NULL_TREE if no simplification is
possible. This may only be applied to a rhs of an expression.
Note that the resulting type may be different from the type pointed
to in the sense that it is still compatible from the langhooks
point of view. */
static tree
fold_indirect_ref_rhs (tree t)
{
tree type = TREE_TYPE (TREE_TYPE (t));
tree sub = t;
tree subtype;
STRIP_NOPS (sub);
subtype = TREE_TYPE (sub);
if (!POINTER_TYPE_P (subtype))
return NULL_TREE;
if (TREE_CODE (sub) == ADDR_EXPR)
{
tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op);
/* *&p => p */
if (lang_hooks.types_compatible_p (type, optype))
return op;
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
if (type_domain && TYPE_MIN_VALUE (type_domain))
min_val = TYPE_MIN_VALUE (type_domain);
return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
}
}
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
&& lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
{
tree type_domain;
tree min_val = size_zero_node;
sub = fold_indirect_ref_rhs (sub);
if (! sub)
sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), sub);
type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
if (type_domain && TYPE_MIN_VALUE (type_domain))
min_val = TYPE_MIN_VALUE (type_domain);
return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
}
return NULL_TREE;
}
/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
based on the code of the RHS. We loop for as long as something changes. */
@ -2869,8 +2925,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
tree t = fold_indirect_ref (*from_p);
if (t != *from_p)
tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
if (t)
{
*from_p = t;
ret = GS_OK;

View file

@ -613,7 +613,17 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
if (n)
{
*tp = build_fold_indirect_ref ((tree)n->value);
/* If we happen to get an ADDR_EXPR in n->value, strip
it manually here as we'll eventually get ADDR_EXPRs
which lie about their types pointed to. In this case
build_fold_indirect_ref wouldn't strip the INDIRECT_REF,
but we absolutely rely on that. */
if (TREE_CODE ((tree)n->value) == ADDR_EXPR)
*tp = TREE_OPERAND ((tree)n->value, 0);
else
*tp = build1 (INDIRECT_REF,
TREE_TYPE (TREE_TYPE ((tree)n->value)),
(tree)n->value);
*walk_subtrees = 0;
return NULL;
}