[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:
parent
46aad78f22
commit
30d2e94365
4 changed files with 94 additions and 14 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue