diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr41750.c | 68 | ||||
-rw-r--r-- | gcc/tree-sra.c | 56 |
4 files changed, 110 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ecad8bb37c..df8f0ed9082 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-11-02 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/41750 + * tree-sra.c (analyze_modified_params): Loop over all + representatives of components of a parameter. + 2009-11-02 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/41841 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6ee45e20d8..4fe2079320b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-11-02 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/41750 + * gcc.c-torture/execute/pr41750.c: New test. + 2009-11-02 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/41841 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41750.c b/gcc/testsuite/gcc.c-torture/execute/pr41750.c new file mode 100644 index 00000000000..3f5cb635d16 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr41750.c @@ -0,0 +1,68 @@ +/* PR 41750 - IPA-SRA used to pass hash->sgot by value rather than by + reference. */ + +struct bfd_link_hash_table +{ + int hash; +}; + +struct foo_link_hash_table +{ + struct bfd_link_hash_table root; + int *dynobj; + int *sgot; +}; + +struct foo_link_info +{ + struct foo_link_hash_table *hash; +}; + +extern void abort (void); + +int __attribute__((noinline)) +foo_create_got_section (int *abfd, struct foo_link_info *info) +{ + info->hash->sgot = abfd; + return 1; +} + +static int * +get_got (int *abfd, struct foo_link_info *info, + struct foo_link_hash_table *hash) +{ + int *got; + int *dynobj; + + got = hash->sgot; + if (!got) + { + dynobj = hash->dynobj; + if (!dynobj) + hash->dynobj = dynobj = abfd; + if (!foo_create_got_section (dynobj, info)) + return 0; + got = hash->sgot; + } + return got; +} + +int * __attribute__((noinline,noclone)) +elf64_ia64_check_relocs (int *abfd, struct foo_link_info *info) +{ + return get_got (abfd, info, info->hash); +} + +struct foo_link_info link_info; +struct foo_link_hash_table hash; +int abfd; + +int +main () +{ + link_info.hash = &hash; + if (elf64_ia64_check_relocs (&abfd, &link_info) != &abfd) + abort (); + return 0; +} + diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 8db84ea2971..12b19909db9 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2818,33 +2818,39 @@ analyze_modified_params (VEC (access_p, heap) *representatives) for (i = 0; i < func_param_count; i++) { - struct access *repr = VEC_index (access_p, representatives, i); - VEC (access_p, heap) *access_vec; - int j, access_count; - tree parm; - - if (!repr || no_accesses_p (repr)) - continue; - parm = repr->base; - if (!POINTER_TYPE_P (TREE_TYPE (parm)) - || repr->grp_maybe_modified) - continue; + struct access *repr; - access_vec = get_base_access_vector (parm); - access_count = VEC_length (access_p, access_vec); - for (j = 0; j < access_count; j++) + for (repr = VEC_index (access_p, representatives, i); + repr; + repr = repr->next_grp) { - struct access *access; - ao_ref ar; - - /* All accesses are read ones, otherwise grp_maybe_modified would be - trivially set. */ - access = VEC_index (access_p, access_vec, j); - ao_ref_init (&ar, access->expr); - walk_aliased_vdefs (&ar, gimple_vuse (access->stmt), - mark_maybe_modified, repr, NULL); - if (repr->grp_maybe_modified) - break; + VEC (access_p, heap) *access_vec; + int j, access_count; + tree parm; + + if (no_accesses_p (repr)) + continue; + parm = repr->base; + if (!POINTER_TYPE_P (TREE_TYPE (parm)) + || repr->grp_maybe_modified) + continue; + + access_vec = get_base_access_vector (parm); + access_count = VEC_length (access_p, access_vec); + for (j = 0; j < access_count; j++) + { + struct access *access; + ao_ref ar; + + /* All accesses are read ones, otherwise grp_maybe_modified would + be trivially set. */ + access = VEC_index (access_p, access_vec, j); + ao_ref_init (&ar, access->expr); + walk_aliased_vdefs (&ar, gimple_vuse (access->stmt), + mark_maybe_modified, repr, NULL); + if (repr->grp_maybe_modified) + break; + } } } } |