> > >From dd240028726cb7fdc777acd0b6d14c4f89aed714 Mon Sep 17 00:00:00 2001 > From: mliska <mli...@suse.cz> > Date: Thu, 19 Feb 2015 16:08:09 +0100 > Subject: [PATCH 1/3] Fix PR ipa/64693 > > 2015-02-25 Martin Liska <mli...@suse.cz> > Jan Hubicka <hubi...@ucw.cz> > > * gcc.dg/ipa/ipa-icf-26.c: Update test. > * gcc.dg/ipa/ipa-icf-33.c: Remove redundant line. > * gcc.dg/ipa/ipa-icf-34.c: New test. > > gcc/ChangeLog: > > 2015-02-25 Martin Liska <mli...@suse.cz> > Jan Hubicka <hubi...@ucw.cz> > > * cgraph.h (address_matters_p): New function. > * ipa-icf.c (symbol_compare_collection::symbol_compare_collection): New. > (sem_item_optimizer::subdivide_classes_by_sensitive_refs): New function. > (sem_item_optimizer::process_cong_reduction): Include division by > sensitive references. > * ipa-icf.h (struct symbol_compare_hashmap_traits): New class. > * ipa-visibility.c (symtab_node::address_taken_from_non_vtable_p): > Removed. > * symtab.c (address_matters_1): New function. > (symtab_node::address_matters_p): Moved from ipa-visibility.c. > + if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl)) > + return; > + > + for (unsigned i = 0; i < node->num_references (); i++) > + { > + ref = node->iterate_reference (i, ref); > + if (ref->use == IPA_REF_ADDR && ref->referred->address_matters_p () > + && !DECL_VIRTUAL_P (ref->referring->decl)) !address_matters_p should be implied by !DECL_VIRTUAL_P (ref->referring->decl). > + m_references.safe_push (ref->referred); > + > + if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE) > + m_interposables.safe_push (ref->referred); Push into m_references if ref->use is IPA_REF_ADDR. We care about address and not value then. > + } > + > + if (is_a <cgraph_node *> (node)) > + { > + cgraph_node *cnode = dyn_cast <cgraph_node *> (node); > + > + for (cgraph_edge *e = cnode->callees; e; e = e->next_callee) > + if (e->callee->get_availability () <= AVAIL_INTERPOSABLE) > + m_interposables.safe_push (e->callee); > + } > @@ -140,6 +204,15 @@ public: > contains_polymorphic_type_p comparison. */ > static bool get_base_types (tree *t1, tree *t2); > > + /* Return true if given DECL is neither virtual nor cdtor. */ > + static bool is_nonvirtual_or_cdtor (tree decl)
You should be able to drop this one. > +/* Return ture if address of N is possibly compared. */ > + > +static bool > +address_matters_1 (symtab_node *n, void *) > +{ > + if (DECL_VIRTUAL_P (n->decl)) > + return false; > + if (is_a <cgraph_node *> (n) > + && (DECL_CXX_CONSTRUCTOR_P (n->decl) > + || DECL_CXX_DESTRUCTOR_P (n->decl))) > + return false; > + if (n->externally_visible > + || n->symtab_node::address_taken_from_non_vtable_p ()) > + return true; > + return false; > +} Aha, I meant adding address_matters_p predicate into ipa-ref that will test whether given refernece may lead to address being used for comparsion. Something like /* Return true if refernece may be used in address compare. */ bool ipa_ref::address_matters_p () { if (use != IPA_REF_ADDR) return false; /* Addresses taken from virtual tables are never compared. */ if (is_a <varpool_node *> (referring) && DECL_VIRTUAL_P (referring->decl)) return false; /* Address of virtual tables and functions is never compared. */ if (DECL_VIRTUAL_P (referred->decl) return false; /* Address of C++ cdtors is never compared. */ if (is_a <cgraph_node *> (referred) && (DECL_CXX_CONSTRUCTOR_P (referred->decl) || DECL_CXX_DESTRUCTOR_P (referred->decl))) return false; return true; } Honza