[PATCH] Fix for PR ipa/64693

Jan Hubicka hubicka@ucw.cz
Wed Feb 25 19:18:00 GMT 2015


> 

> >From dd240028726cb7fdc777acd0b6d14c4f89aed714 Mon Sep 17 00:00:00 2001
> From: mliska <mliska@suse.cz>
> Date: Thu, 19 Feb 2015 16:08:09 +0100
> Subject: [PATCH 1/3] Fix PR ipa/64693
> 
> 2015-02-25  Martin Liska  <mliska@suse.cz>
> 	    Jan Hubicka  <hubicka@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  <mliska@suse.cz>
> 	    Jan Hubicka  <hubicka@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



More information about the Gcc-patches mailing list