diff options
author | Olga Golovanevsky <olga@il.ibm.com> | 2009-12-08 09:41:13 +0000 |
---|---|---|
committer | Olga Golovanevsky <olga@gcc.gnu.org> | 2009-12-08 09:41:13 +0000 |
commit | 72d099cb27a5fedea22e2d69ce8d03e71120fddc (patch) | |
tree | a7fff87194d60ae9fc724724cf946d6b83ad9d24 /gcc | |
parent | 96c493240211f9103b0a19d0411b2e8e4d0da11c (diff) | |
download | gcc-72d099cb27a5fedea22e2d69ce8d03e71120fddc.zip gcc-72d099cb27a5fedea22e2d69ce8d03e71120fddc.tar.gz gcc-72d099cb27a5fedea22e2d69ce8d03e71120fddc.tar.bz2 |
[multiple changes]
2009-12-07 Olga Golovanevsky <olga@il.ibm.com>
PR middle-end/41843
* ipa-struct-reorg.c (compare_fields): New function.
(find_field_in_struct_1): Use compare_fields function.
(is_equal_types): Likewise.
2009-12-04 Olga Golovanevsky <olga@il.ibm.com>
Jakub Jelinek <jakub@redhat.com>
PR midle-end/41843
* gcc.dg/struct/wo_prof_empty_str.c: New testcase.
Co-Authored-By: Jakub Jelinek <jakub@redhat.com>
From-SVN: r155084
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-struct-reorg.c | 65 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/struct/wo_prof_empty_str.c | 47 |
4 files changed, 100 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4d7594..22fd5cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-12-08 Olga Golovanevsky <olga@il.ibm.com> + + PR middle-end/41843 + * ipa-struct-reorg.c (compare_fields): New function. + (find_field_in_struct_1): Use compare_fields function. + (is_equal_types): Likewise. + 2009-12-07 DJ Delorie <dj@redhat.com> PR c/42312 diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c index e1dddae..bef303e 100644 --- a/gcc/ipa-struct-reorg.c +++ b/gcc/ipa-struct-reorg.c @@ -248,6 +248,32 @@ finalize_stmt_and_append (gimple_seq *stmts, gimple stmt) finalize_stmt (stmt); } +/* This function returns true if two fields FIELD1 and FIELD2 are + semantically equal, and false otherwise. */ + +static bool +compare_fields (tree field1, tree field2) +{ + if (DECL_NAME (field1) && DECL_NAME (field2)) + { + const char *name1 = IDENTIFIER_POINTER (DECL_NAME (field1)); + const char *name2 = IDENTIFIER_POINTER (DECL_NAME (field2)); + + gcc_assert (name1 && name2); + + if (strcmp (name1, name2)) + return false; + + } + else if (DECL_NAME (field1) || DECL_NAME (field2)) + return false; + + if (!is_equal_types (TREE_TYPE (field1), TREE_TYPE (field2))) + return false; + + return true; +} + /* Given structure type SRT_TYPE and field FIELD, this function is looking for a field with the same name and type as FIELD in STR_TYPE. It returns it if found, @@ -264,24 +290,12 @@ find_field_in_struct_1 (tree str_type, tree field) for (str_field = TYPE_FIELDS (str_type); str_field; str_field = TREE_CHAIN (str_field)) { - const char *str_field_name; - const char *field_name; if (!DECL_NAME (str_field)) continue; - str_field_name = IDENTIFIER_POINTER (DECL_NAME (str_field)); - field_name = IDENTIFIER_POINTER (DECL_NAME (field)); - - gcc_assert (str_field_name); - gcc_assert (field_name); - - if (!strcmp (str_field_name, field_name)) - { - /* Check field types. */ - if (is_equal_types (TREE_TYPE (str_field), TREE_TYPE (field))) - return str_field; - } + if (compare_fields (field, str_field)) + return str_field; } return NULL_TREE; @@ -1596,11 +1610,8 @@ is_equal_types (tree type1, tree type2) name1 = get_type_name (type1); name2 = get_type_name (type2); - if (name1 && name2 && !strcmp (name1, name2)) - return true; - - if (name1 && name2 && strcmp (name1, name2)) - return false; + if (name1 && name2) + return strcmp (name1, name2) == 0; switch (TREE_CODE (type1)) { @@ -1616,16 +1627,20 @@ is_equal_types (tree type1, tree type2) case QUAL_UNION_TYPE: case ENUMERAL_TYPE: { - tree field1; + tree field1, field2; + /* Compare fields of structure. */ - for (field1 = TYPE_FIELDS (type1); field1; - field1 = TREE_CHAIN (field1)) + for (field1 = TYPE_FIELDS (type1), field2 = TYPE_FIELDS (type2); + field1 && field2; + field1 = TREE_CHAIN (field1), field2 = TREE_CHAIN (field2)) { - tree field2 = find_field_in_struct_1 (type2, field1); - if (!field2) + if (!compare_fields (field1, field2)) return false; } - return true; + if (field1 || field2) + return false; + else + return true; } break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d245b7..3dce570 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-12-08 Olga Golovanevsky <olga@il.ibm.com> + Jakub Jelinek <jakub@redhat.com> + + PR midle-end/41843 + * gcc.dg/struct/wo_prof_empty_str.c: New testcase. + 2009-12-07 Jakub Jelinek <jakub@redhat.com> PR debug/42244 diff --git a/gcc/testsuite/gcc.dg/struct/wo_prof_empty_str.c b/gcc/testsuite/gcc.dg/struct/wo_prof_empty_str.c new file mode 100644 index 0000000..8f9751d --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/wo_prof_empty_str.c @@ -0,0 +1,47 @@ +/* { dg-options "-O3 -fno-inline -fipa-type-escape -fdump-ipa-all -fipa-struct-reorg -fwhole-program -combine" } */ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include <stdlib.h> + +struct S { int a; struct V *b; }; +typedef struct { int c; } T; +typedef struct { int d; int e; } U; + +void * +fn (void *x) +{ + return x; +} + +int +foo (struct S *s) +{ + T x; + + T y = *(T *)fn (&x); + return y.c; +} + +int +bar (struct S *s) +{ + U x; + + U y = *(U *)fn (&x); + return y.d + s->a; +} + +int +main () +{ + struct S s; + + foo(&s) + bar (&s); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform" "ipa_struct_reorg" { xfail { "avr-*-*" } } } } */ +/* { dg-final { cleanup-ipa-dump "*" } } */ |