diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-16 13:41:13 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-16 13:41:13 +0000 |
commit | db812c94e0a17bff65551c01ad88eea8549b2847 (patch) | |
tree | 85a0b59e6028d56e1f2946e68d742d5259cd6aff /gcc | |
parent | e34df749c2b4bfa08fa90a76be51e16c0ef2120a (diff) | |
download | gcc-db812c94e0a17bff65551c01ad88eea8549b2847.tar.gz |
2008-01-16 Jakub Jelinek <jakub@redhat.com>
Richard Guenther <rguenther@suse.de>
PR c/34668
* gimplify.c (fold_indirect_ref_rhs): Rename to ...
(gimple_fold_indirect_ref_rhs): ... this.
(gimple_fold_indirect_ref): New function with foldings
that preserve lvalueness.
(gimplify_modify_expr_rhs): Call gimple_fold_indirect_ref_rhs.
* tree-flow.h (gimple_fold_indirect_ref): Declare.
* tree-inline.c (copy_body_r): Use gimple_fold_indirect_ref
to fold an INDIRECT_REF, fall back to the old use of
fold_indirect_ref_1.
* gcc.dg/pr34668-1.c: New test.
* gcc.dg/pr34668-2.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131572 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/gimplify.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr34668-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr34668-2.c | 5 | ||||
-rw-r--r-- | gcc/tree-flow.h | 1 | ||||
-rw-r--r-- | gcc/tree-inline.c | 11 |
7 files changed, 79 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82edafa4ba8..909008b3fa9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2008-01-16 Jakub Jelinek <jakub@redhat.com> + Richard Guenther <rguenther@suse.de> + + PR c/34668 + * gimplify.c (fold_indirect_ref_rhs): Rename to ... + (gimple_fold_indirect_ref_rhs): ... this. + (gimple_fold_indirect_ref): New function with foldings + that preserve lvalueness. + (gimplify_modify_expr_rhs): Call gimple_fold_indirect_ref_rhs. + * tree-flow.h (gimple_fold_indirect_ref): Declare. + * tree-inline.c (copy_body_r): Use gimple_fold_indirect_ref + to fold an INDIRECT_REF, fall back to the old use of + fold_indirect_ref_1. + 2008-01-16 Sebastian Pop <sebastian.pop@amd.com> * tree-data-ref.c (subscript_dependence_tester_1): Call diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 52547415c0a..1075d654427 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1,6 +1,6 @@ /* Tree lowering pass. This pass converts the GENERIC functions-as-trees tree representation into the GIMPLE form. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Major work done by Sebastian Pop <s.pop@laposte.net>, Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>. @@ -3449,13 +3449,12 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, /* 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. */ + possible. 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 +gimple_fold_indirect_ref (tree t) { tree type = TREE_TYPE (TREE_TYPE (t)); tree sub = t; @@ -3473,9 +3472,10 @@ fold_indirect_ref_rhs (tree t) /* *&p => p */ if (useless_type_conversion_p (type, optype)) return op; + /* *(foo *)&fooarray => fooarray[0] */ - else if (TREE_CODE (optype) == ARRAY_TYPE - && useless_type_conversion_p (type, TREE_TYPE (optype))) + if (TREE_CODE (optype) == ARRAY_TYPE + && useless_type_conversion_p (type, TREE_TYPE (optype))) { tree type_domain = TYPE_DOMAIN (optype); tree min_val = size_zero_node; @@ -3492,7 +3492,7 @@ fold_indirect_ref_rhs (tree t) tree type_domain; tree min_val = size_zero_node; tree osub = sub; - sub = fold_indirect_ref_rhs (sub); + sub = gimple_fold_indirect_ref (sub); if (! sub) sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub); type_domain = TYPE_DOMAIN (TREE_TYPE (sub)); @@ -3504,6 +3504,19 @@ fold_indirect_ref_rhs (tree t) return NULL_TREE; } +/* 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 +gimple_fold_indirect_ref_rhs (tree t) +{ + return gimple_fold_indirect_ref (t); +} + /* 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. */ @@ -3557,7 +3570,7 @@ 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_rhs (TREE_OPERAND (*from_p, 0)); + tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)); if (t) { *from_p = t; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e2748361e74..c0e2196f027 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-01-16 Jakub Jelinek <jakub@redhat.com> + Richard Guenther <rguenther@suse.de> + + PR c/34668 + * gcc.dg/pr34668-1.c: New test. + * gcc.dg/pr34668-2.c: Likewise. + 2008-01-16 Richard Guenther <rguenther@suse.de> PR c++/33819 diff --git a/gcc/testsuite/gcc.dg/pr34668-1.c b/gcc/testsuite/gcc.dg/pr34668-1.c new file mode 100644 index 00000000000..5763bb61027 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr34668-1.c @@ -0,0 +1,19 @@ +/* PR c/34668 */ +/* { dg-do compile } */ +/* { dg-options "--combine -O2" } */ +/* { dg-additional-sources "pr34668-2.c" } */ + +struct optab { unsigned code; }; +extern struct optab optab_table[1]; + +void +init_optab (struct optab *op) +{ + op->code = 0xdead; +} + +void +set_conv_libfunc (void) +{ + init_optab (&optab_table[0]); +} diff --git a/gcc/testsuite/gcc.dg/pr34668-2.c b/gcc/testsuite/gcc.dg/pr34668-2.c new file mode 100644 index 00000000000..fab8f173fd3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr34668-2.c @@ -0,0 +1,5 @@ +/* PR c/34668 */ +/* { dg-do compile } */ + +struct optab { unsigned code; }; +extern struct optab optab_table[1]; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index fae04041151..a96f8b2e083 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -1125,6 +1125,7 @@ extern void register_jump_thread (edge, edge); tree force_gimple_operand (tree, tree *, bool, tree); tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree, bool, enum bsi_iterator_update); +tree gimple_fold_indirect_ref (tree); /* In tree-ssa-structalias.c */ bool find_what_p_points_to (tree); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index f825c5d88fb..6ac367ef0ce 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -696,11 +696,18 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) tree type = TREE_TYPE (TREE_TYPE (*n)); new = unshare_expr (*n); old = *tp; - *tp = fold_indirect_ref_1 (type, new); + *tp = gimple_fold_indirect_ref (new); if (! *tp) { if (TREE_CODE (new) == ADDR_EXPR) - *tp = TREE_OPERAND (new, 0); + { + *tp = fold_indirect_ref_1 (type, new); + /* ??? We should either assert here or build + a VIEW_CONVERT_EXPR instead of blindly leaking + incompatible types to our IL. */ + if (! *tp) + *tp = TREE_OPERAND (new, 0); + } else { *tp = build1 (INDIRECT_REF, type, new); |