Commit 53aedcce by Michael Ploujnikov Committed by Michael Ploujnikov

Minimize clone counter memory usage in create_virtual_clone.

Based on Martin Jambour's suggestion:
https://gcc.gnu.org/ml/gcc-patches/2018-09/msg00111.html

gcc:

	* cgraph.h (clone_function_name): Add a variant that takes a
	tree decl.
	* cgraph.h (cgraph_node::create_virtual_clone): Add a new
	argument: num_suffix.
	* cgraphclones.c (cgraph_node::create_virtual_clone): Pass
	num_suffix to clone_function_name.
	(clone_function_name): Add a variant that takes a tree decl.
	* ipa-cp.c (create_specialized_node): Keep track of clone
	counters in clone_num_suffixes hash map.
	(ipcp_driver): Free the counter hash map.
	* ipa-hsa.c (process_hsa_functions): Creates at most one hsa
	clone per function.

From-SVN: r266692
parent b75255a9
2018-11-30 Michael Ploujnikov <michael.ploujnikov@oracle.com> 2018-11-30 Michael Ploujnikov <michael.ploujnikov@oracle.com>
Minimize clone counter memory usage in create_virtual_clone.
* cgraph.h (clone_function_name): Add a variant that takes a
tree decl.
* cgraph.h (cgraph_node::create_virtual_clone): Add a new
argument: num_suffix.
* cgraphclones.c (cgraph_node::create_virtual_clone): Pass
num_suffix to clone_function_name.
(clone_function_name): Add a variant that takes a tree decl.
* ipa-cp.c (create_specialized_node): Keep track of clone
counters in clone_num_suffixes hash map.
(ipcp_driver): Free the counter hash map.
* ipa-hsa.c (process_hsa_functions): Creates at most one hsa
clone per function.
2018-11-30 Michael Ploujnikov <michael.ploujnikov@oracle.com>
Make function assembly more independent. Make function assembly more independent.
This is achieved by having clone_function_name assign unique clone This is achieved by having clone_function_name assign unique clone
...@@ -968,11 +968,13 @@ public: ...@@ -968,11 +968,13 @@ public:
cgraph_node *new_inlined_to, cgraph_node *new_inlined_to,
bitmap args_to_skip, const char *suffix = NULL); bitmap args_to_skip, const char *suffix = NULL);
/* Create callgraph node clone with new declaration. The actual body will /* Create callgraph node clone with new declaration. The actual body will be
be copied later at compilation stage. */ copied later at compilation stage. The name of the new clone will be
constructed from the name of the original node, SUFFIX and NUM_SUFFIX. */
cgraph_node *create_virtual_clone (vec<cgraph_edge *> redirect_callers, cgraph_node *create_virtual_clone (vec<cgraph_edge *> redirect_callers,
vec<ipa_replace_map *, va_gc> *tree_map, vec<ipa_replace_map *, va_gc> *tree_map,
bitmap args_to_skip, const char * suffix); bitmap args_to_skip, const char * suffix,
unsigned num_suffix);
/* cgraph node being removed from symbol table; see if its entry can be /* cgraph node being removed from symbol table; see if its entry can be
replaced by other inline clone. */ replaced by other inline clone. */
...@@ -2386,6 +2388,8 @@ tree clone_function_name_numbered (const char *name, const char *suffix); ...@@ -2386,6 +2388,8 @@ tree clone_function_name_numbered (const char *name, const char *suffix);
tree clone_function_name_numbered (tree decl, const char *suffix); tree clone_function_name_numbered (tree decl, const char *suffix);
tree clone_function_name (const char *name, const char *suffix, tree clone_function_name (const char *name, const char *suffix,
unsigned long number); unsigned long number);
tree clone_function_name (tree decl, const char *suffix,
unsigned long number);
tree clone_function_name (tree decl, const char *suffix); tree clone_function_name (tree decl, const char *suffix);
void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
......
...@@ -572,6 +572,19 @@ clone_function_name (const char *name, const char *suffix, ...@@ -572,6 +572,19 @@ clone_function_name (const char *name, const char *suffix,
return get_identifier (tmp_name); return get_identifier (tmp_name);
} }
/* Return a new assembler name for a clone of DECL. Apart from the
string SUFFIX, the new name will end with the specified NUMBER. If
clone numbering is not needed then the two argument
clone_function_name should be used instead. */
tree
clone_function_name (tree decl, const char *suffix,
unsigned long number)
{
return clone_function_name (
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), suffix, number);
}
/* Return a new assembler name ending with the string SUFFIX for a /* Return a new assembler name ending with the string SUFFIX for a
clone of DECL. */ clone of DECL. */
...@@ -599,8 +612,9 @@ clone_function_name (tree decl, const char *suffix) ...@@ -599,8 +612,9 @@ clone_function_name (tree decl, const char *suffix)
} }
/* Create callgraph node clone with new declaration. The actual body will /* Create callgraph node clone with new declaration. The actual body will be
be copied later at compilation stage. copied later at compilation stage. The name of the new clone will be
constructed from the name of the original node, SUFFIX and NUM_SUFFIX.
TODO: after merging in ipa-sra use function call notes instead of args_to_skip TODO: after merging in ipa-sra use function call notes instead of args_to_skip
bitmap interface. bitmap interface.
...@@ -608,7 +622,8 @@ clone_function_name (tree decl, const char *suffix) ...@@ -608,7 +622,8 @@ clone_function_name (tree decl, const char *suffix)
cgraph_node * cgraph_node *
cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
vec<ipa_replace_map *, va_gc> *tree_map, vec<ipa_replace_map *, va_gc> *tree_map,
bitmap args_to_skip, const char * suffix) bitmap args_to_skip, const char * suffix,
unsigned num_suffix)
{ {
tree old_decl = decl; tree old_decl = decl;
cgraph_node *new_node = NULL; cgraph_node *new_node = NULL;
...@@ -643,8 +658,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, ...@@ -643,8 +658,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
strcpy (name + len + 1, suffix); strcpy (name + len + 1, suffix);
name[len] = '.'; name[len] = '.';
DECL_NAME (new_decl) = get_identifier (name); DECL_NAME (new_decl) = get_identifier (name);
SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name_numbered (old_decl, SET_DECL_ASSEMBLER_NAME (new_decl,
suffix)); clone_function_name (old_decl, suffix, num_suffix));
SET_DECL_RTL (new_decl, NULL); SET_DECL_RTL (new_decl, NULL);
new_node = create_clone (new_decl, count, false, new_node = create_clone (new_decl, count, false,
......
...@@ -376,6 +376,9 @@ static profile_count max_count; ...@@ -376,6 +376,9 @@ static profile_count max_count;
static long overall_size, max_new_size; static long overall_size, max_new_size;
/* Node to unique clone suffix number map. */
static hash_map<cgraph_node *, unsigned> *clone_num_suffixes;
/* Return the param lattices structure corresponding to the Ith formal /* Return the param lattices structure corresponding to the Ith formal
parameter of the function described by INFO. */ parameter of the function described by INFO. */
static inline struct ipcp_param_lattices * static inline struct ipcp_param_lattices *
...@@ -3829,8 +3832,11 @@ create_specialized_node (struct cgraph_node *node, ...@@ -3829,8 +3832,11 @@ create_specialized_node (struct cgraph_node *node,
} }
} }
unsigned &suffix_counter = clone_num_suffixes->get_or_insert (node);
new_node = node->create_virtual_clone (callers, replace_trees, new_node = node->create_virtual_clone (callers, replace_trees,
args_to_skip, "constprop"); args_to_skip, "constprop",
suffix_counter);
suffix_counter++;
bool have_self_recursive_calls = !self_recursive_calls.is_empty (); bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
for (unsigned j = 0; j < self_recursive_calls.length (); j++) for (unsigned j = 0; j < self_recursive_calls.length (); j++)
...@@ -5044,6 +5050,7 @@ ipcp_driver (void) ...@@ -5044,6 +5050,7 @@ ipcp_driver (void)
ipa_check_create_node_params (); ipa_check_create_node_params ();
ipa_check_create_edge_args (); ipa_check_create_edge_args ();
clone_num_suffixes = new hash_map<cgraph_node *, unsigned>;
if (dump_file) if (dump_file)
{ {
...@@ -5065,6 +5072,7 @@ ipcp_driver (void) ...@@ -5065,6 +5072,7 @@ ipcp_driver (void)
ipcp_store_vr_results (); ipcp_store_vr_results ();
/* Free all IPCP structures. */ /* Free all IPCP structures. */
delete clone_num_suffixes;
free_toporder_info (&topo); free_toporder_info (&topo);
delete edge_clone_summaries; delete edge_clone_summaries;
edge_clone_summaries = NULL; edge_clone_summaries = NULL;
......
...@@ -88,7 +88,7 @@ process_hsa_functions (void) ...@@ -88,7 +88,7 @@ process_hsa_functions (void)
continue; continue;
cgraph_node *clone cgraph_node *clone
= node->create_virtual_clone (vec <cgraph_edge *> (), = node->create_virtual_clone (vec <cgraph_edge *> (),
NULL, NULL, "hsa"); NULL, NULL, "hsa", 0);
TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl); TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl);
clone->externally_visible = node->externally_visible; clone->externally_visible = node->externally_visible;
...@@ -109,7 +109,7 @@ process_hsa_functions (void) ...@@ -109,7 +109,7 @@ process_hsa_functions (void)
continue; continue;
cgraph_node *clone cgraph_node *clone
= node->create_virtual_clone (vec <cgraph_edge *> (), = node->create_virtual_clone (vec <cgraph_edge *> (),
NULL, NULL, "hsa"); NULL, NULL, "hsa", 0);
TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl); TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl);
clone->externally_visible = node->externally_visible; clone->externally_visible = node->externally_visible;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment