IPA ICF: include hash values of references.

* ipa-icf.c (sem_item::update_hash_by_addr_refs): New function.
	(sem_item::update_hash_by_local_refs): Likewise.
	(sem_variable::get_hash): Empty line is fixed.
	(sem_item_optimizer::execute): Include adding of hash references.
	(sem_item_optimizer::update_hash_by_addr_refs): New function.
	(sem_item_optimizer::build_hash_based_classes): Use local hash.
	* ipa-icf.h (sem_item::update_hash_by_addr_refs): New function.
	(sem_item::update_hash_by_local_refs): Likewise.

From-SVN: r221576
This commit is contained in:
Martin Liska 2015-03-22 23:47:06 +01:00 committed by Martin Liska
parent 34d417be31
commit 3ab9335949
3 changed files with 119 additions and 5 deletions

View File

@ -1,3 +1,14 @@
2015-03-22 Martin Liska <mliska@suse.cz>
* ipa-icf.c (sem_item::update_hash_by_addr_refs): New function.
(sem_item::update_hash_by_local_refs): Likewise.
(sem_variable::get_hash): Empty line is fixed.
(sem_item_optimizer::execute): Include adding of hash references.
(sem_item_optimizer::update_hash_by_addr_refs): New function.
(sem_item_optimizer::build_hash_based_classes): Use local hash.
* ipa-icf.h (sem_item::update_hash_by_addr_refs): New function.
(sem_item::update_hash_by_local_refs): Likewise.
2015-03-20 Jan Hubicka <hubicka@ucw.cz> 2015-03-20 Jan Hubicka <hubicka@ucw.cz>
PR ipa/65502 PR ipa/65502

View File

@ -557,6 +557,72 @@ sem_function::equals_wpa (sem_item *item,
return true; return true;
} }
/* Update hash by address sensitive references. We iterate over all
sensitive references (address_matters_p) and we hash ultime alias
target of these nodes, which can improve a semantic item hash.
TODO: stronger SCC based hashing would be desirable here. */
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))
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 () || !m_symtab_node_map.get (ref->referred))
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. */
void
sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
sem_item *> &m_symtab_node_map)
{
inchash::hash state (hash);
for (unsigned j = 0; j < node->num_references (); j++)
{
ipa_ref *ref;
ref = node->iterate_reference (j, ref);
sem_item **result = m_symtab_node_map.get (ref->referring);
if (result)
state.merge_hash ((*result)->hash);
}
if (type == FUNC)
{
for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
e = e->next_callee)
{
sem_item **result = m_symtab_node_map.get (e->caller);
if (result)
state.merge_hash ((*result)->hash);
}
}
global_hash = state.end ();
}
/* Returns true if the item equals to ITEM given as argument. */ /* Returns true if the item equals to ITEM given as argument. */
bool bool
@ -1749,8 +1815,8 @@ hashval_t
sem_variable::get_hash (void) sem_variable::get_hash (void)
{ {
if (hash) if (hash)
return hash; return hash;
/* All WPA streamed in symbols should have their hashes computed at compile /* 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. time. At this point, the constructor may not be in memory at all.
DECL_INITIAL (decl) would be error_mark_node in that case. */ DECL_INITIAL (decl) would be error_mark_node in that case. */
@ -2216,6 +2282,8 @@ sem_item_optimizer::execute (void)
filter_removed_items (); filter_removed_items ();
unregister_hooks (); unregister_hooks ();
build_graph ();
update_hash_by_addr_refs ();
build_hash_based_classes (); build_hash_based_classes ();
if (dump_file) if (dump_file)
@ -2225,8 +2293,6 @@ sem_item_optimizer::execute (void)
for (unsigned int i = 0; i < m_items.length(); i++) for (unsigned int i = 0; i < m_items.length(); i++)
m_items[i]->init_wpa (); m_items[i]->init_wpa ();
build_graph ();
subdivide_classes_by_equality (true); subdivide_classes_by_equality (true);
if (dump_file) if (dump_file)
@ -2315,6 +2381,27 @@ sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
item->cls = cls; item->cls = cls;
} }
/* For each semantic item, append hash values of references. */
void
sem_item_optimizer::update_hash_by_addr_refs ()
{
/* First, append to hash sensitive references. */
for (unsigned i = 0; i < m_items.length (); i++)
m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
/* Once all symbols have enhanced hash value, we can append
hash values of symbols that are seen by IPA ICF and are
references by a semantic item. Newly computed values
are saved to global_hash member variable. */
for (unsigned i = 0; i < m_items.length (); i++)
m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
/* Global hash value replace current hash values. */
for (unsigned i = 0; i < m_items.length (); i++)
m_items[i]->hash = m_items[i]->global_hash;
}
/* Congruence classes are built by hash value. */ /* Congruence classes are built by hash value. */
void void
@ -2324,7 +2411,7 @@ sem_item_optimizer::build_hash_based_classes (void)
{ {
sem_item *item = m_items[i]; sem_item *item = m_items[i];
congruence_class_group *group = get_group_by_hash (item->get_hash (), congruence_class_group *group = get_group_by_hash (item->hash,
item->type); item->type);
if (!group->classes.length ()) if (!group->classes.length ())

View File

@ -189,6 +189,15 @@ public:
/* Dump symbol to FILE. */ /* Dump symbol to FILE. */
virtual void dump_to_file (FILE *file) = 0; virtual void dump_to_file (FILE *file) = 0;
/* Update hash by address sensitive references. */
void update_hash_by_addr_refs (hash_map <symtab_node *,
sem_item *> &m_symtab_node_map);
/* Update hash by computed local hash values taken from different
semantic items. */
void update_hash_by_local_refs (hash_map <symtab_node *,
sem_item *> &m_symtab_node_map);
/* Return base tree that can be used for compatible_types_p and /* Return base tree that can be used for compatible_types_p and
contains_polymorphic_type_p comparison. */ contains_polymorphic_type_p comparison. */
static bool get_base_types (tree *t1, tree *t2); static bool get_base_types (tree *t1, tree *t2);
@ -226,9 +235,13 @@ public:
/* A set with symbol table references. */ /* A set with symbol table references. */
hash_set <symtab_node *> refs_set; hash_set <symtab_node *> refs_set;
/* Hash of item. */
hashval_t hash;
/* Temporary hash used where hash values of references are added. */
hashval_t global_hash;
protected: protected:
/* Cached, once calculated hash for the item. */ /* Cached, once calculated hash for the item. */
hashval_t hash;
/* Accumulate to HSTATE a hash of constructor expression EXP. */ /* Accumulate to HSTATE a hash of constructor expression EXP. */
static void add_expr (const_tree exp, inchash::hash &hstate); static void add_expr (const_tree exp, inchash::hash &hstate);
@ -494,6 +507,9 @@ public:
private: private:
/* For each semantic item, append hash values of references. */
void update_hash_by_addr_refs ();
/* Congruence classes are built by hash value. */ /* Congruence classes are built by hash value. */
void build_hash_based_classes (void); void build_hash_based_classes (void);