]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/lto/lto-partition.c
Update copyright years.
[thirdparty/gcc.git] / gcc / lto / lto-partition.c
index e8207fb7230dbe577e91869f199199e7b232f279..86b2eabe37454c35fabff41e74873419d3c680e6 100644 (file)
@@ -1,5 +1,5 @@
 /* LTO partitioning logic routines.
-   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   Copyright (C) 2009-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -29,7 +29,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "cgraph.h"
 #include "lto-streamer.h"
-#include "params.h"
 #include "symbol-summary.h"
 #include "tree-vrp.h"
 #include "ipa-prop.h"
@@ -160,8 +159,8 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
   if (symbol_partitioned_p (node))
     {
       node->in_other_partition = 1;
-      if (symtab->dump_file)
-       fprintf (symtab->dump_file,
+      if (dump_file)
+       fprintf (dump_file,
                 "Symbol node %s now used in multiple partitions\n",
                 node->name ());
     }
@@ -171,7 +170,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
     {
       struct cgraph_edge *e;
       if (!node->alias && c == SYMBOL_PARTITION)
-        part->insns += ipa_fn_summaries->get (cnode)->size;
+       part->insns += ipa_size_summaries->get (cnode)->size;
 
       /* Add all inline clones and callees that are duplicated.  */
       for (e = cnode->callees; e; e = e->next_callee)
@@ -182,7 +181,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
 
       /* Add all thunks associated with the function.  */
       for (e = cnode->callers; e; e = e->next_caller)
-       if (e->caller->thunk.thunk_p && !e->caller->global.inlined_to)
+       if (e->caller->thunk.thunk_p && !e->caller->inlined_to)
          add_symbol_to_partition_1 (part, e->caller);
     }
 
@@ -233,8 +232,8 @@ contained_in_symbol (symtab_node *node)
   if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
     {
       cnode = cnode->function_symbol ();
-      if (cnode->global.inlined_to)
-       cnode = cnode->global.inlined_to;
+      if (cnode->inlined_to)
+       cnode = cnode->inlined_to;
       return cnode;
     }
   else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
@@ -250,14 +249,14 @@ add_symbol_to_partition (ltrans_partition part, symtab_node *node)
 {
   symtab_node *node1;
 
-  /* Verify that we do not try to duplicate something that can not be.  */
+  /* Verify that we do not try to duplicate something that cannot be.  */
   gcc_checking_assert (node->get_partitioning_class () == SYMBOL_DUPLICATE
                       || !symbol_partitioned_p (node));
 
   while ((node1 = contained_in_symbol (node)) != node)
     node = node1;
 
-  /* If we have duplicated symbol contained in something we can not duplicate,
+  /* If we have duplicated symbol contained in something we cannot duplicate,
      we are very badly screwed.  The other way is possible, so we do not
      assert this in add_symbol_to_partition_1. 
 
@@ -291,7 +290,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
 
       if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node))
           && node->get_partitioning_class () == SYMBOL_PARTITION)
-        partition->insns -= ipa_fn_summaries->get (cnode)->size;
+       partition->insns -= ipa_size_summaries->get (cnode)->size;
       lto_symtab_encoder_delete_node (partition->encoder, node);
       node->aux = (void *)((size_t)node->aux - 1);
     }
@@ -373,38 +372,9 @@ lto_max_map (void)
     new_partition ("empty");
 }
 
-/* Helper function for qsort; sort nodes by order. noreorder functions must have
-   been removed earlier.  */
-static int
-node_cmp (const void *pa, const void *pb)
-{
-  const struct cgraph_node *a = *(const struct cgraph_node * const *) pa;
-  const struct cgraph_node *b = *(const struct cgraph_node * const *) pb;
-
-  /* Profile reorder flag enables function reordering based on first execution
-     of a function. All functions with profile are placed in ascending
-     order at the beginning.  */
-
-  if (flag_profile_reorder_functions)
-  {
-    /* Functions with time profile are sorted in ascending order.  */
-    if (a->tp_first_run && b->tp_first_run)
-      return a->tp_first_run != b->tp_first_run
-       ? a->tp_first_run - b->tp_first_run
-        : a->order - b->order;
-
-    /* Functions with time profile are sorted before the functions
-       that do not have the profile.  */
-    if (a->tp_first_run || b->tp_first_run)
-      return b->tp_first_run - a->tp_first_run;
-  }
-
-  return b->order - a->order;
-}
-
 /* Helper function for qsort; sort nodes by order.  */
 static int
-varpool_node_cmp (const void *pa, const void *pb)
+node_cmp (const void *pa, const void *pb)
 {
   const symtab_node *a = *static_cast<const symtab_node * const *> (pa);
   const symtab_node *b = *static_cast<const symtab_node * const *> (pb);
@@ -419,7 +389,7 @@ add_sorted_nodes (vec<symtab_node *> &next_nodes, ltrans_partition partition)
   unsigned i;
   symtab_node *node;
 
-  next_nodes.qsort (varpool_node_cmp);
+  next_nodes.qsort (node_cmp);
   FOR_EACH_VEC_ELT (next_nodes, i, node)
     if (!symbol_partitioned_p (node))
       add_symbol_to_partition (partition, node);
@@ -500,12 +470,10 @@ account_reference_p (symtab_node *n1, symtab_node *n2)
 void
 lto_balanced_map (int n_lto_partitions, int max_partition_size)
 {
-  int n_nodes = 0;
   int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
-  struct cgraph_node **order = XNEWVEC (cgraph_node *, symtab->cgraph_max_uid);
+  auto_vec <cgraph_node *> order (symtab->cgraph_count);
   auto_vec<cgraph_node *> noreorder;
   auto_vec<varpool_node *> varpool_order;
-  int i;
   struct cgraph_node *node;
   int64_t original_total_size, total_size = 0;
   int64_t partition_size;
@@ -513,7 +481,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
   int last_visited_node = 0;
   varpool_node *vnode;
   int64_t cost = 0, internal = 0;
-  int best_n_nodes = 0, best_i = 0;
+  unsigned int best_n_nodes = 0, best_i = 0;
   int64_t best_cost = -1, best_internal = 0, best_size = 0;
   int npartitions;
   int current_order = -1;
@@ -521,16 +489,16 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
 
   FOR_EACH_VARIABLE (vnode)
     gcc_assert (!vnode->aux);
-    
+
   FOR_EACH_DEFINED_FUNCTION (node)
     if (node->get_partitioning_class () == SYMBOL_PARTITION)
       {
        if (node->no_reorder)
          noreorder.safe_push (node);
        else
-         order[n_nodes++] = node;
+         order.safe_push (node);
        if (!node->alias)
-         total_size += ipa_fn_summaries->get (node)->size;
+         total_size += ipa_size_summaries->get (node)->size;
       }
 
   original_total_size = total_size;
@@ -540,16 +508,16 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
      unit tends to import a lot of global trees defined there.  We should
      get better about minimizing the function bounday, but until that
      things works smoother if we order in source order.  */
-  qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
+  order.qsort (tp_first_run_node_cmp);
   noreorder.qsort (node_cmp);
 
-  if (symtab->dump_file)
+  if (dump_file)
     {
-      for(i = 0; i < n_nodes; i++)
-       fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n",
+      for (unsigned i = 0; i < order.length (); i++)
+       fprintf (dump_file, "Balanced map symbol order:%s:%u\n",
                 order[i]->name (), order[i]->tp_first_run);
-      for(i = 0; i < (int)noreorder.length(); i++)
-       fprintf (symtab->dump_file, "Balanced map symbol no_reorder:%s:%u\n",
+      for (unsigned i = 0; i < noreorder.length (); i++)
+       fprintf (dump_file, "Balanced map symbol no_reorder:%s:%u\n",
                 noreorder[i]->name (), noreorder[i]->tp_first_run);
     }
 
@@ -559,25 +527,25 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
        && vnode->no_reorder)
       varpool_order.safe_push (vnode);
   n_varpool_nodes = varpool_order.length ();
-  varpool_order.qsort (varpool_node_cmp);
+  varpool_order.qsort (node_cmp);
 
   /* Compute partition size and create the first partition.  */
-  if (PARAM_VALUE (MIN_PARTITION_SIZE) > max_partition_size)
+  if (param_min_partition_size > max_partition_size)
     fatal_error (input_location, "min partition size cannot be greater "
                 "than max partition size");
 
   partition_size = total_size / n_lto_partitions;
-  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
-    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
+  if (partition_size < param_min_partition_size)
+    partition_size = param_min_partition_size;
   npartitions = 1;
   partition = new_partition ("");
-  if (symtab->dump_file)
-    fprintf (symtab->dump_file, "Total unit size: %" PRId64 ", partition size: %" PRId64 "\n",
+  if (dump_file)
+    fprintf (dump_file, "Total unit size: %" PRId64 ", partition size: %" PRId64 "\n",
             total_size, partition_size);
 
   auto_vec<symtab_node *> next_nodes;
 
-  for (i = 0; i < n_nodes; i++)
+  for (unsigned i = 0; i < order.length (); i++)
     {
       if (symbol_partitioned_p (order[i]))
        continue;
@@ -765,8 +733,8 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
          best_n_nodes = lto_symtab_encoder_size (partition->encoder);
          best_varpool_pos = varpool_pos;
        }
-      if (symtab->dump_file)
-       fprintf (symtab->dump_file, "Step %i: added %s/%i, size %i, "
+      if (dump_file)
+       fprintf (dump_file, "Step %i: added %s/%i, size %i, "
                 "cost %" PRId64 "/%" PRId64 " "
                 "best %" PRId64 "/%" PRId64", step %i\n", i,
                 order[i]->name (), order[i]->order,
@@ -779,30 +747,30 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
        {
          if (best_i != i)
            {
-             if (symtab->dump_file)
-               fprintf (symtab->dump_file, "Unwinding %i insertions to step %i\n",
+             if (dump_file)
+               fprintf (dump_file, "Unwinding %i insertions to step %i\n",
                         i - best_i, best_i);
              undo_partition (partition, best_n_nodes);
              varpool_pos = best_varpool_pos;
            }
          gcc_assert (best_size == partition->insns);
          i = best_i;
-         if (symtab->dump_file)
-           fprintf (symtab->dump_file,
+         if (dump_file)
+           fprintf (dump_file,
                     "Partition insns: %i (want %" PRId64 ")\n",
                     partition->insns, partition_size);
          /* When we are finished, avoid creating empty partition.  */
-         while (i < n_nodes - 1 && symbol_partitioned_p (order[i + 1]))
+         while (i < order.length () - 1 && symbol_partitioned_p (order[i + 1]))
            i++;
-         if (i == n_nodes - 1)
+         if (i == order.length () - 1)
            break;
          total_size -= partition->insns;
          partition = new_partition ("");
          last_visited_node = 0;
          cost = 0;
 
-         if (symtab->dump_file)
-           fprintf (symtab->dump_file, "New partition\n");
+         if (dump_file)
+           fprintf (dump_file, "New partition\n");
          best_n_nodes = 0;
          best_cost = -1;
 
@@ -814,12 +782,12 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
            /* Watch for overflow.  */
            partition_size = INT_MAX / 16;
 
-         if (symtab->dump_file)
-           fprintf (symtab->dump_file,
+         if (dump_file)
+           fprintf (dump_file,
                     "Total size: %" PRId64 " partition_size: %" PRId64 "\n",
                     total_size, partition_size);
-         if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
-           partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
+         if (partition_size < param_min_partition_size)
+           partition_size = param_min_partition_size;
          npartitions ++;
        }
     }
@@ -842,23 +810,21 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
   gcc_assert (next_nodes.length () || npartitions != 1 || !best_cost || best_cost == -1);
   add_sorted_nodes (next_nodes, partition);
 
-  free (order);
-
-  if (symtab->dump_file)
+  if (dump_file)
     {
-      fprintf (symtab->dump_file, "\nPartition sizes:\n");
+      fprintf (dump_file, "\nPartition sizes:\n");
       unsigned partitions = ltrans_partitions.length ();
 
       for (unsigned i = 0; i < partitions ; i++)
        {
          ltrans_partition p = ltrans_partitions[i];
-         fprintf (symtab->dump_file, "partition %d contains %d (%2.2f%%)"
+         fprintf (dump_file, "partition %d contains %d (%2.2f%%)"
                   " symbols and %d (%2.2f%%) insns\n", i, p->symbols,
-                  100.0 * p->symbols / n_nodes, p->insns,
+                  100.0 * p->symbols / order.length (), p->insns,
                   100.0 * p->insns / original_total_size);
        }
 
-      fprintf (symtab->dump_file, "\n");
+      fprintf (dump_file, "\n");
     }
 }
 
@@ -873,8 +839,8 @@ must_not_rename (symtab_node *node, const char *name)
   if (node->lto_file_data
       && lto_get_decl_name_mapping (node->lto_file_data, name) != name)
     {
-      if (symtab->dump_file)
-       fprintf (symtab->dump_file,
+      if (dump_file)
+       fprintf (dump_file,
                 "Not privatizing symbol name: %s. It privatized already.\n",
                 name);
       return true;
@@ -885,8 +851,8 @@ must_not_rename (symtab_node *node, const char *name)
      that are not really clones.  */
   if (node->unique_name)
     {
-      if (symtab->dump_file)
-       fprintf (symtab->dump_file,
+      if (dump_file)
+       fprintf (dump_file,
                 "Not privatizing symbol name: %s. Has unique name.\n",
                 name);
       return true;
@@ -955,6 +921,9 @@ validize_symbol_for_target (symtab_node *node)
     }
 }
 
+/* Maps symbol names to unique lto clone counters.  */
+static hash_map<const char *, unsigned> *lto_clone_numbers;
+
 /* Helper for privatize_symbol_name.  Mangle NODE symbol name
    represented by DECL.  */
 
@@ -967,17 +936,19 @@ privatize_symbol_name_1 (symtab_node *node, tree decl)
     return false;
 
   name = maybe_rewrite_identifier (name);
+  unsigned &clone_number = lto_clone_numbers->get_or_insert (name);
   symtab->change_decl_assembler_name (decl,
-                                     clone_function_name_1 (name,
-                                                            "lto_priv"));
+                                     clone_function_name (
+                                         name, "lto_priv", clone_number));
+  clone_number++;
 
   if (node->lto_file_data)
     lto_record_renamed_decl (node->lto_file_data, name,
                             IDENTIFIER_POINTER
                             (DECL_ASSEMBLER_NAME (decl)));
 
-  if (symtab->dump_file)
-    fprintf (symtab->dump_file,
+  if (dump_file)
+    fprintf (dump_file,
             "Privatizing symbol name: %s -> %s\n",
             name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
 
@@ -1022,8 +993,8 @@ promote_symbol (symtab_node *node)
   TREE_PUBLIC (node->decl) = 1;
   DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN;
   DECL_VISIBILITY_SPECIFIED (node->decl) = true;
-  if (symtab->dump_file)
-    fprintf (symtab->dump_file,
+  if (dump_file)
+    fprintf (dump_file,
             "Promoting as hidden: %s (%s)\n", node->name (),
             IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
 
@@ -1039,8 +1010,8 @@ promote_symbol (symtab_node *node)
          TREE_PUBLIC (alias->decl) = 1;
          DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN;
          DECL_VISIBILITY_SPECIFIED (alias->decl) = true;
-         if (symtab->dump_file)
-           fprintf (symtab->dump_file,
+         if (dump_file)
+           fprintf (dump_file,
                     "Promoting alias as hidden: %s\n",
                     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
        }
@@ -1092,7 +1063,7 @@ rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
     return;
 
   /* Now walk symbols sharing the same name and see if there are any conflicts.
-     (all types of symbols counts here, since we can not have static of the
+     (all types of symbols counts here, since we cannot have static of the
      same name as external or public symbol.)  */
   for (s = symtab_node::get_for_asmname (name);
        s; s = s->next_sharing_asm_name)
@@ -1106,8 +1077,8 @@ rename_statics (lto_symtab_encoder_t encoder, symtab_node *node)
   if (!s)
     return;
 
-  if (symtab->dump_file)
-    fprintf (symtab->dump_file,
+  if (dump_file)
+    fprintf (dump_file,
            "Renaming statics with asm name: %s\n", node->name ());
 
   /* Assign every symbol in the set that shares the same ASM name an unique
@@ -1161,6 +1132,8 @@ lto_promote_cross_file_statics (void)
       part->encoder = compute_ltrans_boundary (part->encoder);
     }
 
+  lto_clone_numbers = new hash_map<const char *, unsigned>;
+
   /* Look at boundaries and promote symbols as needed.  */
   for (i = 0; i < n_sets; i++)
     {
@@ -1191,6 +1164,7 @@ lto_promote_cross_file_statics (void)
           promote_symbol (node);
         }
     }
+  delete lto_clone_numbers;
 }
 
 /* Rename statics in the whole unit in the case that 
@@ -1200,9 +1174,12 @@ void
 lto_promote_statics_nonwpa (void)
 {
   symtab_node *node;
+
+  lto_clone_numbers = new hash_map<const char *, unsigned>;
   FOR_EACH_SYMBOL (node)
     {
       rename_statics (NULL, node);
       validize_symbol_for_target (node);
     }
+  delete lto_clone_numbers;
 }