Commit 30d2e943 by Richard Guenther Committed by Jeff Law

[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
parent 46aad78f
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> 2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/21658 PR tree-optimization/21658
......
...@@ -11451,14 +11451,14 @@ build_fold_addr_expr (tree t) ...@@ -11451,14 +11451,14 @@ build_fold_addr_expr (tree t)
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (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 /* Given a pointer value OP0 and a type TYPE, return a simplified version
through T, or NULL_TREE if no simplification is possible. */ of an indirection through OP0, or NULL_TREE if no simplification is
possible. */
static tree 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 = op0;
tree sub = t;
tree subtype; tree subtype;
STRIP_NOPS (sub); STRIP_NOPS (sub);
...@@ -11471,11 +11471,11 @@ fold_indirect_ref_1 (tree t) ...@@ -11471,11 +11471,11 @@ fold_indirect_ref_1 (tree t)
tree op = TREE_OPERAND (sub, 0); tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op); tree optype = TREE_TYPE (op);
/* *&p => p */ /* *&p => p */
if (lang_hooks.types_compatible_p (type, optype)) if (type == optype)
return op; return op;
/* *(foo *)&fooarray => fooarray[0] */ /* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE 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 type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node; tree min_val = size_zero_node;
...@@ -11487,7 +11487,7 @@ fold_indirect_ref_1 (tree t) ...@@ -11487,7 +11487,7 @@ fold_indirect_ref_1 (tree t)
/* *(foo *)fooarrptr => (*fooarrptr)[0] */ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE 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 type_domain;
tree min_val = size_zero_node; tree min_val = size_zero_node;
...@@ -11507,12 +11507,13 @@ fold_indirect_ref_1 (tree t) ...@@ -11507,12 +11507,13 @@ fold_indirect_ref_1 (tree t)
tree tree
build_fold_indirect_ref (tree t) 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) if (sub)
return sub; return sub;
else 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. */ /* Given an INDIRECT_REF T, return either T or a simplified version. */
...@@ -11520,7 +11521,7 @@ build_fold_indirect_ref (tree t) ...@@ -11520,7 +11521,7 @@ build_fold_indirect_ref (tree t)
tree tree
fold_indirect_ref (tree t) 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) if (sub)
return sub; return sub;
......
...@@ -2846,6 +2846,62 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -2846,6 +2846,62 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
return GS_ALL_DONE; 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 /* 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. */ 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, ...@@ -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 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 a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */ to take advantage of the optimization below. */
tree t = fold_indirect_ref (*from_p); tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
if (t != *from_p) if (t)
{ {
*from_p = t; *from_p = t;
ret = GS_OK; ret = GS_OK;
......
...@@ -613,7 +613,17 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) ...@@ -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); n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
if (n) 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; *walk_subtrees = 0;
return NULL; return NULL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment