re PR ipa/68035 (ipa performance issue when no procedures are present)

Fix PR ipa/68035

	PR ipa/68035
	* ipa-icf.c (void sem_item::set_hash): New function.
	(sem_function::get_hash): Use renamed m_hash member variable.
	(sem_item::update_hash_by_addr_refs): Utilize get_hash.
	(sem_item::update_hash_by_local_refs): Likewise.
	(sem_variable::get_hash): Use renamed m_hash member variable.
	(sem_item_optimizer::update_hash_by_addr_refs): Utilize get_hash.
	(sem_item_optimizer::build_hash_based_classes): Utilize set_hash.
	(sem_item_optimizer::build_graph): As the hash value of an item
	is lazy initialized, force the calculation.
	* ipa-icf.h (set_hash): Declare new function and rename hash member
	variable to m_hash.
	* gcc.dg/ipa/pr68035.c: New test.

From-SVN: r230263
This commit is contained in:
Martin Liska 2015-11-12 16:16:00 +01:00 committed by Martin Liska
parent c2a12ca06d
commit 808b6bb7a8
4 changed files with 52 additions and 22 deletions

View File

@ -1,3 +1,18 @@
2015-11-12 Martin Liska <mliska@suse.cz>
PR ipa/68035
* ipa-icf.c (void sem_item::set_hash): New function.
(sem_function::get_hash): Use renamed m_hash member variable.
(sem_item::update_hash_by_addr_refs): Utilize get_hash.
(sem_item::update_hash_by_local_refs): Likewise.
(sem_variable::get_hash): Use renamed m_hash member variable.
(sem_item_optimizer::update_hash_by_addr_refs): Utilize get_hash.
(sem_item_optimizer::build_hash_based_classes): Utilize set_hash.
(sem_item_optimizer::build_graph): As the hash value of an item
is lazy initialized, force the calculation.
* ipa-icf.h (set_hash): Declare new function and rename hash member
variable to m_hash.
2015-11-12 Richard Biener <rguenther@suse.de> 2015-11-12 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (vect_slp_analyze_data_ref_dependences): * tree-vectorizer.h (vect_slp_analyze_data_ref_dependences):

View File

@ -140,7 +140,7 @@ sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
for bitmap memory allocation. */ for bitmap memory allocation. */
sem_item::sem_item (sem_item_type _type, sem_item::sem_item (sem_item_type _type,
bitmap_obstack *stack): type(_type), hash(0) bitmap_obstack *stack): type (_type), m_hash (0)
{ {
setup (stack); setup (stack);
} }
@ -151,7 +151,7 @@ sem_item::sem_item (sem_item_type _type,
sem_item::sem_item (sem_item_type _type, symtab_node *_node, sem_item::sem_item (sem_item_type _type, symtab_node *_node,
hashval_t _hash, bitmap_obstack *stack): type(_type), hashval_t _hash, bitmap_obstack *stack): type(_type),
node (_node), hash (_hash) node (_node), m_hash (_hash)
{ {
decl = node->decl; decl = node->decl;
setup (stack); setup (stack);
@ -227,6 +227,11 @@ sem_item::target_supports_symbol_aliases_p (void)
#endif #endif
} }
void sem_item::set_hash (hashval_t hash)
{
m_hash = hash;
}
/* Semantic function constructor that uses STACK as bitmap memory stack. */ /* Semantic function constructor that uses STACK as bitmap memory stack. */
sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack), sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
@ -274,7 +279,7 @@ sem_function::get_bb_hash (const sem_bb *basic_block)
hashval_t hashval_t
sem_function::get_hash (void) sem_function::get_hash (void)
{ {
if(!hash) if (!m_hash)
{ {
inchash::hash hstate; inchash::hash hstate;
hstate.add_int (177454); /* Random number for function type. */ hstate.add_int (177454); /* Random number for function type. */
@ -289,7 +294,6 @@ sem_function::get_hash (void)
for (unsigned i = 0; i < bb_sizes.length (); i++) for (unsigned i = 0; i < bb_sizes.length (); i++)
hstate.add_int (bb_sizes[i]); hstate.add_int (bb_sizes[i]);
/* Add common features of declaration itself. */ /* Add common features of declaration itself. */
if (DECL_FUNCTION_SPECIFIC_TARGET (decl)) if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
hstate.add_wide_int hstate.add_wide_int
@ -301,10 +305,10 @@ sem_function::get_hash (void)
hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl)); hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl)); hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
hash = hstate.end (); set_hash (hstate.end ());
} }
return hash; return m_hash;
} }
/* Return ture if A1 and A2 represent equivalent function attribute lists. /* Return ture if A1 and A2 represent equivalent function attribute lists.
@ -800,7 +804,7 @@ sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
sem_item *> &m_symtab_node_map) sem_item *> &m_symtab_node_map)
{ {
ipa_ref* ref; ipa_ref* ref;
inchash::hash hstate (hash); inchash::hash hstate (get_hash ());
for (unsigned i = 0; node->iterate_reference (i, ref); i++) for (unsigned i = 0; node->iterate_reference (i, ref); i++)
{ {
@ -823,7 +827,7 @@ sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
} }
} }
hash = hstate.end (); set_hash (hstate.end ());
} }
/* Update hash by computed local hash values taken from different /* Update hash by computed local hash values taken from different
@ -835,13 +839,13 @@ sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
sem_item *> &m_symtab_node_map) sem_item *> &m_symtab_node_map)
{ {
ipa_ref* ref; ipa_ref* ref;
inchash::hash state (hash); inchash::hash state (get_hash ());
for (unsigned j = 0; node->iterate_reference (j, ref); j++) for (unsigned j = 0; node->iterate_reference (j, ref); j++)
{ {
sem_item **result = m_symtab_node_map.get (ref->referring); sem_item **result = m_symtab_node_map.get (ref->referring);
if (result) if (result)
state.merge_hash ((*result)->hash); state.merge_hash ((*result)->get_hash ());
} }
if (type == FUNC) if (type == FUNC)
@ -851,7 +855,7 @@ sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
{ {
sem_item **result = m_symtab_node_map.get (e->caller); sem_item **result = m_symtab_node_map.get (e->caller);
if (result) if (result)
state.merge_hash ((*result)->hash); state.merge_hash ((*result)->get_hash ());
} }
} }
@ -2099,8 +2103,8 @@ sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
hashval_t hashval_t
sem_variable::get_hash (void) sem_variable::get_hash (void)
{ {
if (hash) if (m_hash)
return hash; return m_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.
@ -2113,9 +2117,9 @@ sem_variable::get_hash (void)
if (DECL_SIZE (decl) && tree_fits_shwi_p (DECL_SIZE (decl))) if (DECL_SIZE (decl) && tree_fits_shwi_p (DECL_SIZE (decl)))
hstate.add_wide_int (tree_to_shwi (DECL_SIZE (decl))); hstate.add_wide_int (tree_to_shwi (DECL_SIZE (decl)));
add_expr (ctor, hstate); add_expr (ctor, hstate);
hash = hstate.end (); set_hash (hstate.end ());
return hash; return m_hash;
} }
/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
@ -2688,7 +2692,7 @@ sem_item_optimizer::update_hash_by_addr_refs ()
{ {
tree class_type tree class_type
= TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)); = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
inchash::hash hstate (m_items[i]->hash); inchash::hash hstate (m_items[i]->get_hash ());
if (TYPE_NAME (class_type) if (TYPE_NAME (class_type)
&& DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))) && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
@ -2696,7 +2700,7 @@ sem_item_optimizer::update_hash_by_addr_refs ()
(IDENTIFIER_HASH_VALUE (IDENTIFIER_HASH_VALUE
(DECL_ASSEMBLER_NAME (TYPE_NAME (class_type)))); (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
m_items[i]->hash = hstate.end (); m_items[i]->set_hash (hstate.end ());
} }
} }
} }
@ -2710,7 +2714,7 @@ sem_item_optimizer::update_hash_by_addr_refs ()
/* Global hash value replace current hash values. */ /* Global hash value replace current hash values. */
for (unsigned i = 0; i < m_items.length (); i++) for (unsigned i = 0; i < m_items.length (); i++)
m_items[i]->hash = m_items[i]->global_hash; m_items[i]->set_hash (m_items[i]->global_hash);
} }
/* Congruence classes are built by hash value. */ /* Congruence classes are built by hash value. */
@ -2722,7 +2726,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->hash, congruence_class_group *group = get_group_by_hash (item->get_hash (),
item->type); item->type);
if (!group->classes.length ()) if (!group->classes.length ())
@ -2744,6 +2748,10 @@ sem_item_optimizer::build_graph (void)
{ {
sem_item *item = m_items[i]; sem_item *item = m_items[i];
m_symtab_node_map.put (item->node, item); m_symtab_node_map.put (item->node, item);
/* Initialize hash values if we are not in LTO mode. */
if (!in_lto_p)
item->get_hash ();
} }
for (unsigned i = 0; i < m_items.length (); i++) for (unsigned i = 0; i < m_items.length (); i++)

View File

@ -181,6 +181,9 @@ public:
/* References independent hash function. */ /* References independent hash function. */
virtual hashval_t get_hash (void) = 0; virtual hashval_t get_hash (void) = 0;
/* Set new hash value of the item. */
void set_hash (hashval_t hash);
/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
be applied. */ be applied. */
virtual bool merge (sem_item *alias_item) = 0; virtual bool merge (sem_item *alias_item) = 0;
@ -234,9 +237,6 @@ 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. */ /* Temporary hash used where hash values of references are added. */
hashval_t global_hash; hashval_t global_hash;
protected: protected:
@ -270,6 +270,9 @@ protected:
&ignored_nodes, &ignored_nodes,
symtab_node *n1, symtab_node *n2, symtab_node *n1, symtab_node *n2,
bool address); bool address);
protected:
/* Hash of item. */
hashval_t m_hash;
private: private:
/* Initialize internal data structures. Bitmap STACK is used for /* Initialize internal data structures. Bitmap STACK is used for

View File

@ -1,3 +1,7 @@
2015-11-12 Martin Liska <mliska@suse.cz>
* gcc.dg/ipa/pr68035.c: New test.
2015-11-12 Richard Biener <rguenther@suse.de> 2015-11-12 Richard Biener <rguenther@suse.de>
PR tree-optimization/68306 PR tree-optimization/68306