aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-02-07 12:09:31 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-02-07 12:09:31 +0000
commitc0aae19ce3ebff871fa2e611135353071aff4fca (patch)
tree7df86d53ae12dd81938cfb2a94969c03feab1395 /gcc
parente6d926d7d35a8675134b34e02a2932451d81bf1d (diff)
downloadgcc-c0aae19ce3ebff871fa2e611135353071aff4fca.zip
gcc-c0aae19ce3ebff871fa2e611135353071aff4fca.tar.gz
gcc-c0aae19ce3ebff871fa2e611135353071aff4fca.tar.bz2
re PR tree-optimization/47621 (Missed dependencies in address-taken optimization)
2011-02-07 Richard Guenther <rguenther@suse.de> PR tree-optimization/47621 * tree-ssa.c (non_rewritable_lvalue_p): New function, split out from two duplicates ... (execute_update_addresses_taken): ... here. Make it more conservative in what we accept. * gcc.dg/torture/pr47621.c: New testcase. From-SVN: r169881
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr47621.c14
-rw-r--r--gcc/tree-ssa.c83
4 files changed, 66 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2c86129..cc625d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-02-07 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/47621
+ * tree-ssa.c (non_rewritable_lvalue_p): New function, split out from
+ two duplicates ...
+ (execute_update_addresses_taken): ... here. Make it more
+ conservative in what we accept.
+
2011-02-06 Joseph Myers <joseph@codesourcery.com>
* config/sparc/freebsd.h (ASM_SPEC): Define.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe9a2f7..558f192 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-07 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/47621
+ * gcc.dg/torture/pr47621.c: New testcase.
+
2011-02-07 Uros Bizjak <ubizjak@gmail.com>
* gfortran.dg/transpose_optimization_2.f90: Cleanup original dump.
diff --git a/gcc/testsuite/gcc.dg/torture/pr47621.c b/gcc/testsuite/gcc.dg/torture/pr47621.c
new file mode 100644
index 0000000..882e67f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr47621.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int
+main (void)
+{
+ int data = 1;
+ struct ptr { int val; } *ptr = (struct ptr *) &data;
+ ptr->val = 0;
+ if (data != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 7bd01f8..90fb5dd 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1885,6 +1885,34 @@ non_rewritable_mem_ref_base (tree ref)
return NULL_TREE;
}
+/* For an lvalue tree LHS return true if it cannot be rewritten into SSA form.
+ Otherwise return true. */
+
+static bool
+non_rewritable_lvalue_p (tree lhs)
+{
+ /* A plain decl is always rewritable. */
+ if (DECL_P (lhs))
+ return false;
+
+ /* A decl that is wrapped inside a MEM-REF that covers
+ it full is also rewritable.
+ ??? The following could be relaxed allowing component
+ references that do not change the access size. */ ;
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
+ && integer_zerop (TREE_OPERAND (lhs, 1)))
+ {
+ tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
+ if (DECL_P (decl)
+ && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
+ && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
+ return false;
+ }
+
+ return true;
+}
+
/* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
mark the variable VAR for conversion into SSA. Return true when updating
stmts is required. */
@@ -1978,29 +2006,13 @@ execute_update_addresses_taken (void)
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
{
tree lhs = gimple_get_lhs (stmt);
-
- /* A plain decl does not need it set. */
- if (lhs && !DECL_P (lhs))
+ if (lhs
+ && TREE_CODE (lhs) != SSA_NAME
+ && non_rewritable_lvalue_p (lhs))
{
- tree orig_lhs = lhs;
-
- while (handled_component_p (lhs))
- lhs = TREE_OPERAND (lhs, 0);
-
- if (DECL_P (lhs))
- bitmap_set_bit (not_reg_needs, DECL_UID (lhs));
- else if (TREE_CODE (lhs) == MEM_REF
- && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
- {
- decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
- if (DECL_P (decl)
- && (!integer_zerop (TREE_OPERAND (lhs, 1))
- || (DECL_SIZE (decl)
- != TYPE_SIZE (TREE_TYPE (orig_lhs)))
- || (TREE_THIS_VOLATILE (lhs)
- != TREE_THIS_VOLATILE (decl))))
- bitmap_set_bit (not_reg_needs, DECL_UID (decl));
- }
+ decl = get_base_address (lhs);
+ if (DECL_P (decl))
+ bitmap_set_bit (not_reg_needs, DECL_UID (decl));
}
}
@@ -2027,29 +2039,12 @@ execute_update_addresses_taken (void)
{
tree link = gimple_asm_output_op (stmt, i);
tree lhs = TREE_VALUE (link);
-
- /* A plain decl does not need it set. */
- if (!DECL_P (lhs))
+ if (TREE_CODE (lhs) != SSA_NAME
+ && non_rewritable_lvalue_p (lhs))
{
- tree orig_lhs = lhs;
-
- while (handled_component_p (lhs))
- lhs = TREE_OPERAND (lhs, 0);
-
- if (DECL_P (lhs))
- bitmap_set_bit (not_reg_needs, DECL_UID (lhs));
- else if (TREE_CODE (lhs) == MEM_REF
- && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
- {
- decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
- if (DECL_P (decl)
- && (!integer_zerop (TREE_OPERAND (lhs, 1))
- || (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
- != TYPE_MAIN_VARIANT (TREE_TYPE (orig_lhs)))
- || (TREE_THIS_VOLATILE (lhs)
- != TREE_THIS_VOLATILE (decl))))
- bitmap_set_bit (not_reg_needs, DECL_UID (decl));
- }
+ decl = get_base_address (lhs);
+ if (DECL_P (decl))
+ bitmap_set_bit (not_reg_needs, DECL_UID (decl));
}
}
for (i = 0; i < gimple_asm_ninputs (stmt); ++i)