1to1 partitioning now also partitions toplevel assembly.
Other partitionings keep the old behavior of putting all
toplevel assembly into single partition.

gcc/ChangeLog:

        * lto-cgraph.cc (compute_ltrans_boundary): Add asm_node.

gcc/lto/ChangeLog:

        * lto-partition.cc (create_partition_if_empty): New.
        (node_into_file_partition): New.
        (lto_1_to_1_map): Partition toplevel assembly.
        (create_asm_partition): New.
        (lto_max_map): Use create_asm_partition.
        (lto_balanced_map): Likewise.
---
 gcc/lto-cgraph.cc        |   7 +++
 gcc/lto/lto-partition.cc | 101 ++++++++++++++++++++++++++-------------
 2 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index d6e58351ce4..017686ed9b2 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -989,6 +989,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
            lto_symtab_encoder_encode (encoder, node);
        }
     }
+
+  for (lsei = lsei_start (in_encoder); !lsei_end_p (lsei); lsei_next (&lsei))
+    {
+      toplevel_node *tnode = lsei_node (lsei);
+      if (asm_node* node = dyn_cast <asm_node*> (tnode))
+       lto_set_symtab_encoder_in_partition (encoder, node);
+    }
   lto_symtab_encoder_delete (in_encoder);
   return encoder;
 }
diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
index a9d7dbb48e9..b87ca440bc9 100644
--- a/gcc/lto/lto-partition.cc
+++ b/gcc/lto/lto-partition.cc
@@ -88,6 +88,15 @@ new_partition (const char *name)
   return part;
 }
 
+/* If the cgraph is empty, create one cgraph node set so that there is still
+   an output file for any variables that need to be exported in a DSO.  */
+static void
+create_partition_if_empty ()
+{
+  if (!ltrans_partitions.length ())
+    new_partition ("empty");
+}
+
 /* Free memory used by ltrans partition.
    Encoder can be kept to be freed after streaming.  */
 static void
@@ -328,6 +337,35 @@ undo_partition (ltrans_partition partition, unsigned int 
n_nodes)
     }
 }
 
+/* Insert node into its file partition.  */
+static void
+node_into_file_partition (toplevel_node* node,
+                         hash_map<lto_file_decl_data *,
+                                  ltrans_partition>& pmap)
+{
+  ltrans_partition partition;
+
+  struct lto_file_decl_data *file_data = node->lto_file_data;
+
+  if (file_data)
+    {
+      ltrans_partition *slot = &pmap.get_or_insert (file_data);
+      if (*slot)
+       partition = *slot;
+      else
+       {
+         partition = new_partition (file_data->file_name);
+         *slot = partition;
+       }
+    }
+  else if (!file_data && ltrans_partitions.length ())
+    partition = ltrans_partitions[0];
+  else
+    partition = new_partition ("");
+
+  add_symbol_to_partition (partition, node);
+}
+
 /* Group cgrah nodes by input files.  This is used mainly for testing
    right now.  */
 
@@ -335,10 +373,7 @@ void
 lto_1_to_1_map (void)
 {
   symtab_node *node;
-  struct lto_file_decl_data *file_data;
   hash_map<lto_file_decl_data *, ltrans_partition> pmap;
-  ltrans_partition partition;
-  int npartitions = 0;
 
   FOR_EACH_SYMBOL (node)
     {
@@ -346,41 +381,38 @@ lto_1_to_1_map (void)
          || symbol_partitioned_p (node))
        continue;
 
-      file_data = node->lto_file_data;
-
-      if (file_data)
-       {
-          ltrans_partition *slot = &pmap.get_or_insert (file_data);
-          if (*slot)
-           partition = *slot;
-         else
-           {
-             partition = new_partition (file_data->file_name);
-             *slot = partition;
-             npartitions++;
-           }
-       }
-      else if (!file_data && ltrans_partitions.length ())
-       partition = ltrans_partitions[0];
-      else
-       {
-         partition = new_partition ("");
-         npartitions++;
-       }
-
-      add_symbol_to_partition (partition, node);
+      node_into_file_partition (node, pmap);
     }
 
-  /* If the cgraph is empty, create one cgraph node set so that there is still
-     an output file for any variables that need to be exported in a DSO.  */
-  if (!npartitions)
-    new_partition ("empty");
+  struct asm_node *anode;
+  for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
+    node_into_file_partition (anode, pmap);
+
+  create_partition_if_empty ();
 
   /* Order partitions by order of symbols because they are linked into binary
      that way.  */
   ltrans_partitions.qsort (cmp_partitions_order);
 }
 
+/* Creates partition with all toplevel assembly.
+
+   Before toplevel asm could be partitioned, all toplevel asm was inserted
+   into first partition.
+   This function achieves similar behavior for partitionings that cannot
+   easily satisfy requirements of toplevel asm.  */
+static void
+create_asm_partition (void)
+{
+  struct asm_node *anode = symtab->first_asm_symbol ();
+  if (anode)
+    {
+      ltrans_partition partition = new_partition ("asm_nodes");
+      for (; anode; anode = anode->next)
+       add_symbol_to_partition (partition, anode);
+    }
+}
+
 /* Maximal partitioning.  Put every new symbol into new partition if possible. 
 */
 
 void
@@ -388,7 +420,6 @@ lto_max_map (void)
 {
   symtab_node *node;
   ltrans_partition partition;
-  int npartitions = 0;
 
   FOR_EACH_SYMBOL (node)
     {
@@ -397,10 +428,10 @@ lto_max_map (void)
        continue;
       partition = new_partition (node->asm_name ());
       add_symbol_to_partition (partition, node);
-      npartitions++;
     }
-  if (!npartitions)
-    new_partition ("empty");
+
+  create_asm_partition ();
+  create_partition_if_empty ();
 }
 
 /* Helper function for qsort; sort nodes by order.  */
@@ -1408,6 +1439,8 @@ 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);
 
+  create_asm_partition ();
+
   if (dump_file)
     {
       fprintf (dump_file, "\nPartition sizes:\n");
-- 
2.50.0

Reply via email to