aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOlga Golovanevsky <olga@il.ibm.com>2009-12-08 09:41:13 +0000
committerOlga Golovanevsky <olga@gcc.gnu.org>2009-12-08 09:41:13 +0000
commit72d099cb27a5fedea22e2d69ce8d03e71120fddc (patch)
treea7fff87194d60ae9fc724724cf946d6b83ad9d24 /gcc
parent96c493240211f9103b0a19d0411b2e8e4d0da11c (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/ipa-struct-reorg.c65
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/struct/wo_prof_empty_str.c47
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 "*" } } */