[PATCH] Speed-up IPA ICF by enhanced hash values

Jan Hubicka hubicka@ucw.cz
Thu Mar 19 20:42:00 GMT 2015


> diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
> index f68d23c..b8e3aa4 100644
> --- a/gcc/ipa-icf.c
> +++ b/gcc/ipa-icf.c
> @@ -557,6 +557,69 @@ sem_function::equals_wpa (sem_item *item,
>    return true;
>  }
>  
> +/* Update hash by address sensitive references.  */
> +
> +void
> +sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
> +				    sem_item *> &m_symtab_node_map)
> +{
> +  if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))

Do not return early here, if reference goes to external symbol, we still want
to record it as sensitive. ref->address_matters_p () should behave well here.
> +    return;
> +
> +  ipa_ref* ref;
> +  inchash::hash hstate (hash);
> +  for (unsigned i = 0; i < node->num_references (); i++)
> +    {
> +      ref = node->iterate_reference (i, ref);
> +      if (ref->address_matters_p ())

ref->address_matters_p () || !m_symtab_node_map.get (ref->referred)

if refernce goes to external symbol, it behaves like sensitive.

You probably want to update topleve comment explaining what is sensitive and local
reference and how the hashing is handled.
> +	hstate.add_ptr (ref->referred->ultimate_alias_target ());
> +    }
> +
> +  if (is_a <cgraph_node *> (node))
> +    {
> +      for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
> +	   e = e->next_caller)
> +	{
> +	  sem_item **result = m_symtab_node_map.get (e->callee);
> +	  if (!result)
> +	    hstate.add_ptr (e->callee->ultimate_alias_target ());
> +	}
> +    }
> +
> +  hash = hstate.end ();
> +}
> +
> +/* Update hash by computed local hash values taken from different
> +   semantic items.  */

Please add TODO that stronger SCC based hashing would be desirable here.
> @@ -2301,6 +2364,19 @@ sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
>    item->cls = cls;
>  }
>  
> +void
> +sem_item_optimizer::update_hash_by_addr_refs ()

Add block comment ande xplain why the addr and local updates can not be performed at once
or someone gets an idea to merge the loops.
> +{
> +  for (unsigned i = 0; i < m_items.length (); i++)
> +    m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
> +
> +  for (unsigned i = 0; i < m_items.length (); i++)
> +    m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
> +
> +  for (unsigned i = 0; i < m_items.length (); i++)
> +    m_items[i]->hash = m_items[i]->global_hash;
> +}
> +

OK with these changes.
Honza



More information about the Gcc-patches mailing list