diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-27 17:23:30 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-27 17:23:30 +0000 |
commit | 51fc648ffc1a616d7a4233332b443033308d7855 (patch) | |
tree | 62ea9650b917f6874d18e3dfbb1662d57f77d04b /gcc/gimplify.c | |
parent | 0fc97fb009a8b5d085a5050cb8e01db0c8dde3e6 (diff) | |
download | gcc-51fc648ffc1a616d7a4233332b443033308d7855.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100267 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 9452973004e..657d5311e5b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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; |