Minimize clone counter memory usage in create_virtual_clone.
authorMichael Ploujnikov <michael.ploujnikov@oracle.com>
Fri, 30 Nov 2018 22:27:11 +0000 (22:27 +0000)
committerMichael Ploujnikov <plouj@gcc.gnu.org>
Fri, 30 Nov 2018 22:27:11 +0000 (22:27 +0000)
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

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa-cp.c
gcc/ipa-hsa.c

index e47e2b1..873d1c8 100644 (file)
@@ -1,4 +1,20 @@
 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.
 
        This is achieved by having clone_function_name assign unique clone
index dd1e8fd..b8e23cc 100644 (file)
@@ -968,11 +968,13 @@ public:
                             cgraph_node *new_inlined_to,
                             bitmap args_to_skip, const char *suffix = NULL);
 
-  /* Create callgraph node clone with new declaration.  The actual body will
-     be copied later at compilation stage.  */
+  /* Create callgraph node clone with new declaration.  The actual body will be
+     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,
                                     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
    replaced by other inline clone.  */
@@ -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 (const char *name, const char *suffix,
                          unsigned long number);
+tree clone_function_name (tree decl, const char *suffix,
+                         unsigned long number);
 tree clone_function_name (tree decl, const char *suffix);
 
 void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
index a45722f..f807692 100644 (file)
@@ -572,6 +572,19 @@ clone_function_name (const char *name, const char *suffix,
   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
    clone of DECL.  */
 
@@ -599,8 +612,9 @@ clone_function_name (tree decl, const char *suffix)
 }
 
 
-/* Create callgraph node clone with new declaration.  The actual body will
-   be copied later at compilation stage.
+/* Create callgraph node clone with new declaration.  The actual body will be
+   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
    bitmap interface.
@@ -608,7 +622,8 @@ clone_function_name (tree decl, const char *suffix)
 cgraph_node *
 cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
                                   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;
   cgraph_node *new_node = NULL;
@@ -643,8 +658,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
   strcpy (name + len + 1, suffix);
   name[len] = '.';
   DECL_NAME (new_decl) = get_identifier (name);
-  SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name_numbered (old_decl,
-                                                                  suffix));
+  SET_DECL_ASSEMBLER_NAME (new_decl,
+                          clone_function_name (old_decl, suffix, num_suffix));
   SET_DECL_RTL (new_decl, NULL);
 
   new_node = create_clone (new_decl, count, false,
index 6b9dc8c..84ca688 100644 (file)
@@ -376,6 +376,9 @@ static profile_count max_count;
 
 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
    parameter of the function described by INFO.  */
 static inline struct ipcp_param_lattices *
@@ -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,
-                                        args_to_skip, "constprop");
+                                        args_to_skip, "constprop",
+                                        suffix_counter);
+  suffix_counter++;
 
   bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
   for (unsigned j = 0; j < self_recursive_calls.length (); j++)
@@ -5044,6 +5050,7 @@ ipcp_driver (void)
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
+  clone_num_suffixes = new hash_map<cgraph_node *, unsigned>;
 
   if (dump_file)
     {
@@ -5065,6 +5072,7 @@ ipcp_driver (void)
   ipcp_store_vr_results ();
 
   /* Free all IPCP structures.  */
+  delete clone_num_suffixes;
   free_toporder_info (&topo);
   delete edge_clone_summaries;
   edge_clone_summaries = NULL;
index 7c6ceaa..63b41ea 100644 (file)
@@ -88,7 +88,7 @@ process_hsa_functions (void)
            continue;
          cgraph_node *clone
            = node->create_virtual_clone (vec <cgraph_edge *> (),
-                                         NULL, NULL, "hsa");
+                                         NULL, NULL, "hsa", 0);
          TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl);
          clone->externally_visible = node->externally_visible;
 
@@ -109,7 +109,7 @@ process_hsa_functions (void)
            continue;
          cgraph_node *clone
            = node->create_virtual_clone (vec <cgraph_edge *> (),
-                                         NULL, NULL, "hsa");
+                                         NULL, NULL, "hsa", 0);
          TREE_PUBLIC (clone->decl) = TREE_PUBLIC (node->decl);
          clone->externally_visible = node->externally_visible;