summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-16 13:41:13 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-01-16 13:41:13 +0000
commitdb812c94e0a17bff65551c01ad88eea8549b2847 (patch)
tree85a0b59e6028d56e1f2946e68d742d5259cd6aff /gcc
parente34df749c2b4bfa08fa90a76be51e16c0ef2120a (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--gcc/gimplify.c35
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/pr34668-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr34668-2.c5
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-inline.c11
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);