diff options
author | Richard Guenther <rguenther@suse.de> | 2011-02-07 12:09:31 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-02-07 12:09:31 +0000 |
commit | c0aae19ce3ebff871fa2e611135353071aff4fca (patch) | |
tree | 7df86d53ae12dd81938cfb2a94969c03feab1395 /gcc | |
parent | e6d926d7d35a8675134b34e02a2932451d81bf1d (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr47621.c | 14 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 83 |
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) |