From c4c0f336bc3bd0761ccac74d297dd45d45e299fe Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 2 Mar 2015 08:51:28 +0100 Subject: [PATCH] ipa-icf.c (sem_variable::equals): Improve debug output; get variable constructor. 2015-02-28 Martin Liska Jan Hubicka * ipa-icf.c (sem_variable::equals): Improve debug output; get variable constructor. (sem_variable::parse): Do not filter out too early; give up on volatile and register vars. (sem_item_optimizer::filter_removed_items): Filter out nonreadonly variables. * ipa-icf.h (sem_variable::init): Do not set ctor. (sem_variable::ctor): Remove. gcc/testsuite/ChangeLog: 2015-02-28 Martin Liska Jan Hubicka * gcc.dg/ipa/ipa-icf-35.c: New test. * gcc.dg/ipa/ipa-icf-36.c: New test. * gcc.dg/ipa/ipa-icf-37.c: New test. Co-Authored-By: Jan Hubicka From-SVN: r221099 --- gcc/ChangeLog | 12 +++++++ gcc/ipa-icf.c | 51 ++++++++++++++------------- gcc/ipa-icf.h | 5 --- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c | 31 ++++++++++++++++ gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c | 36 +++++++++++++++++++ gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c | 36 +++++++++++++++++++ 7 files changed, 148 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90f5e41edd1..27b3a759276 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-02-28 Martin Liska + Jan Hubicka + + * ipa-icf.c (sem_variable::equals): Improve debug output; + get variable constructor. + (sem_variable::parse): Do not filter out too early; give up on + volatile and register vars. + (sem_item_optimizer::filter_removed_items): Filter out nonreadonly + variables. + * ipa-icf.h (sem_variable::init): Do not set ctor. + (sem_variable::ctor): Remove. + 2015-03-01 Aldy Hernandez PR middle-end/65233 diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index a2d99e9a8e8..31fcbec6615 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -1448,18 +1448,29 @@ sem_variable::equals_wpa (sem_item *item, /* Returns true if the item equals to ITEM given as argument. */ +/* Returns true if the item equals to ITEM given as argument. */ + bool sem_variable::equals (sem_item *item, - hash_map & ARG_UNUSED (ignored_nodes)) + hash_map &) { gcc_assert (item->type == VAR); + bool ret; - sem_variable *v = static_cast(item); + if (DECL_INITIAL (decl) == error_mark_node && in_lto_p) + dyn_cast (node)->get_constructor (); + if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p) + dyn_cast (item->node)->get_constructor (); - if (!ctor || !v->ctor) - return return_false_with_msg ("ctor is missing for semantic variable"); + ret = sem_variable::equals (DECL_INITIAL (decl), + DECL_INITIAL (item->node->decl)); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Equals called for vars:%s:%s (%u:%u) (%s:%s) with result: %s\n\n", + name(), item->name (), node->order, item->node->order, asm_name (), + item->asm_name (), ret ? "true" : "false"); - return sem_variable::equals (ctor, v->ctor); + return ret; } /* Compares trees T1 and T2 for semantic equality. */ @@ -1653,24 +1664,7 @@ sem_variable::equals (tree t1, tree t2) sem_variable * sem_variable::parse (varpool_node *node, bitmap_obstack *stack) { - tree decl = node->decl; - - if (node->alias) - return NULL; - - bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl); - if (!readonly) - return NULL; - - bool can_handle = DECL_VIRTUAL_P (decl) - || flag_merge_constants >= 2 - || (!TREE_ADDRESSABLE (decl) && !node->externally_visible); - - if (!can_handle || DECL_EXTERNAL (decl)) - return NULL; - - tree ctor = ctor_for_folding (decl); - if (!ctor) + if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)) return NULL; sem_variable *v = new sem_variable (node, 0, stack); @@ -1686,8 +1680,8 @@ hashval_t sem_variable::get_hash (void) { if (hash) - return hash; + return hash; /* All WPA streamed in symbols should have their hashes computed at compile time. At this point, the constructor may not be in memory at all. DECL_INITIAL (decl) would be error_mark_node in that case. */ @@ -2155,7 +2149,14 @@ sem_item_optimizer::filter_removed_items (void) if (!flag_ipa_icf_variables) remove_item (item); else - filtered.safe_push (item); + { + /* Filter out non-readonly variables. */ + tree decl = item->decl; + if (TREE_READONLY (decl)) + filtered.safe_push (item); + else + remove_item (item); + } } } diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index b4862b75357..e3582db89a8 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -393,7 +393,6 @@ public: inline virtual void init (void) { decl = get_node ()->decl; - ctor = ctor_for_folding (decl); } virtual hashval_t get_hash (void); @@ -415,9 +414,6 @@ public: /* Parser function that visits a varpool NODE. */ static sem_variable *parse (varpool_node *node, bitmap_obstack *stack); - /* Variable constructor. */ - tree ctor; - private: /* Iterates though a constructor and identifies tree references we are interested in semantic function equality. */ @@ -428,7 +424,6 @@ private: /* Compare that symbol sections are either NULL or have same name. */ bool compare_sections (sem_variable *alias); - }; // class sem_variable class sem_item_optimizer; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e397689d287..c18c5e7fb75 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-02-28 Martin Liska + Jan Hubicka + + * gcc.dg/ipa/ipa-icf-35.c: New test. + * gcc.dg/ipa/ipa-icf-36.c: New test. + * gcc.dg/ipa/ipa-icf-37.c: New test. + 2015-02-28 Martin Liska Jan Hubicka diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c new file mode 100644 index 00000000000..f91cdd78483 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-icf" } */ + +void f1() +{ +} + +void f2() +{ +} + +static void (*a)(void)=&f1; +static void (*b)(void)=&f1; +static void (*c)(void)=&f2; +static void (*d)(void)=&f2; + +int main() +{ + a(); + b(); + c(); + d(); + + return 0; +} + +/* { dg-final { scan-ipa-dump "Equal symbols: 3" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:f2->f1" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:d->c" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:b->a" "icf" } } */ +/* { dg-final { cleanup-ipa-dump "icf" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c new file mode 100644 index 00000000000..d8cd5c8567e --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-icf -fmerge-all-constants" } */ +static int a; +static int b; +static const int c = 2; +static const int d = 2; +static char * e = "test"; +static char * f = "test"; +static int g[3]={1,2,3}; +static int h[3]={1,2,3}; +static const int *i=&c; +static const int *j=&c; +static const int *k=&d; +int t(int tt) +{ + switch (tt) + { + case 1: return a; + case 2: return b; + case 3: return c; + case 4: return d; + case 5: return e[1]; + case 6: return f[1]; + case 7: return g[1]; + case 8: return h[1]; + case 9: return i[0]; + case 10: return j[0]; + case 11: return k[0]; + } +} +/* { dg-final { scan-ipa-dump "Equal symbols: 6" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:b->a" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:d->c" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:f->e" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:h->g" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:k->i" "icf" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c new file mode 100644 index 00000000000..7314697e887 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-icf" } */ +static int a; +static int b; +static const int c = 2; +static const int d = 2; +static char * e = "test"; +static char * f = "test"; +static int g[3]={1,2,3}; +static int h[3]={1,2,3}; +static const int *i=&c; +static const int *j=&c; +static const int *k=&d; +int t(int tt) +{ + switch (tt) + { + case 1: return a; + case 2: return b; + case 3: return c; + case 4: return d; + case 5: return e[1]; + case 6: return f[1]; + case 7: return g[1]; + case 8: return h[1]; + case 9: return i[0]; + case 10: return j[0]; + case 11: return k[0]; + } +} +/* { dg-final { scan-ipa-dump "Equal symbols: 5" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:b->a" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:d->c" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:f->e" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:h->g" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:j->i" "icf" } } */ -- 2.30.2