This patch adds create_asm_partitions to cache partitioning
to prevent issues with non-renameable symbols (while partition
joining and splitting).

All other relevant partitionings use create_asm_partitions.
It was not used in cache partitioning, because toplevel asm
could be in principle special handled in cache partitioning
with marginally better results, but I never implemented it.


map_1_to_1 has to be used twice, second time without toplevel
asm, so I modified it to better express what should be included.

        lto/124289

gcc/lto/ChangeLog:

        * lto-partition.cc (enum map1to1_content): New.
        (map_1_to_1): Use map1to1_content.
        (lto_1_to_1_map): Likewise.
        (create_asm_partitions): Likewise.
        (lto_max_map): Likewise.
        (lto_cache_map): Use create_asm_partitions.

gcc/testsuite/ChangeLog:

        * gcc.dg/lto/toplevel-extended-asm-2_0.c: Add padding to asm label.
        * gcc.dg/lto/toplevel-extended-asm-2_1.c: Add padding to asm label.
---
 gcc/lto/lto-partition.cc                      | 47 +++++++++++++++----
 .../gcc.dg/lto/toplevel-extended-asm-2_0.c    |  2 +-
 .../gcc.dg/lto/toplevel-extended-asm-2_1.c    |  2 +-
 3 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
index 3eef5d9ddf2..1276e7793d4 100644
--- a/gcc/lto/lto-partition.cc
+++ b/gcc/lto/lto-partition.cc
@@ -366,10 +366,21 @@ node_into_file_partition (toplevel_node* node,
   add_symbol_to_partition (partition, node);
 }
 
+enum map1to1_content {
+    /* Forced symbols are always attempted.  */
+    map1to1_forced_symbols = 0,
+
+    map1to1_asm = 1,
+    map1to1_other_symbols = 2,
+    map1to1_symbols = map1to1_forced_symbols | map1to1_other_symbols,
+    map1to1_forced = map1to1_asm | map1to1_forced_symbols,
+    map1to1_all = map1to1_symbols | map1to1_asm,
+};
+
 /* Group cgraph nodes by input files.  Used for symbols that must remain
    together.  */
 static void
-map_1_to_1 (bool forced_symbols_only)
+map_1_to_1 (map1to1_content content)
 {
   symtab_node *node;
   hash_map<lto_file_decl_data *, ltrans_partition> pmap;
@@ -380,7 +391,7 @@ map_1_to_1 (bool forced_symbols_only)
          || symbol_partitioned_p (node))
        continue;
 
-      if (forced_symbols_only && !node->must_remain_in_tu_name
+      if (!(content & map1to1_other_symbols) && !node->must_remain_in_tu_name
          && !node->must_remain_in_tu_body && !node->no_reorder)
        continue;
 
@@ -388,8 +399,10 @@ map_1_to_1 (bool forced_symbols_only)
     }
 
   struct asm_node *anode;
-  for (anode = symtab->first_asm_symbol (); anode; anode = 
safe_as_a<asm_node*>(anode->next))
-    node_into_file_partition (anode, pmap);
+  if (content & map1to1_asm)
+    for (anode = symtab->first_asm_symbol (); anode;
+        anode = safe_as_a<asm_node*>(anode->next))
+      node_into_file_partition (anode, pmap);
 
   /* Order partitions by order of symbols because they are linked into binary
      that way.  */
@@ -402,7 +415,7 @@ map_1_to_1 (bool forced_symbols_only)
 void
 lto_1_to_1_map (void)
 {
-  map_1_to_1 (false);
+  map_1_to_1 (map1to1_all);
   create_partition_if_empty ();
 }
 
@@ -420,7 +433,7 @@ create_asm_partitions (int64_t target_size)
 {
   if (!symtab->first_asm_symbol ())
     return;
-  map_1_to_1 (true);
+  map_1_to_1 (map1to1_forced);
 
   size_t join_into = 0;
   size_t join_from = 0;
@@ -486,7 +499,7 @@ lto_max_map (void)
   ltrans_partition partition;
 
   /* Needed for toplevel assembly.  */
-  map_1_to_1 (true);
+  map_1_to_1 (map1to1_forced);
 
   FOR_EACH_SYMBOL (node)
     {
@@ -1111,15 +1124,29 @@ private:
 void
 lto_cache_map (int n_lto_partitions, int max_partition_size)
 {
-  lto_1_to_1_map ();
+  cgraph_node *node;
+  int64_t total_size = 0;
+  FOR_EACH_DEFINED_FUNCTION (node)
+    if (node->get_partitioning_class () == SYMBOL_PARTITION && !node->alias)
+      total_size += ipa_size_summaries->get (node)->size;
+
+  /* Separates toplevel asm into its own partitions and handles name conflicts.
+
+     We could do this directly in cache partitioning without separating asm
+     into its own partitions in most cases.  */
+  create_asm_partitions (total_size / n_lto_partitions);
+  unsigned asm_n = ltrans_partitions.length ();
+
+  map_1_to_1 (map1to1_symbols);
+  create_partition_if_empty ();
 
   std::vector<ltrans_partition> partitions;
-  for (unsigned i = 0; i < ltrans_partitions.length (); ++i)
+  for (unsigned i = asm_n; i < ltrans_partitions.length (); ++i)
     {
       ltrans_partition part = ltrans_partitions[i];
       partitions.push_back (part);
     }
-  ltrans_partitions.truncate (0);
+  ltrans_partitions.truncate (asm_n);
 
   partitioner_default partitioner = partitioner_default
     (param_min_partition_size, max_partition_size);
diff --git a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c 
b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c
index 84a7284d669..089ce2e0460 100644
--- a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c
+++ b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c
@@ -6,7 +6,7 @@ extern int use_statics ();
 extern int asm_var;
 
 static int a;
-asm (".local %cc0\n %cc0:" :: ":"(&a));
+asm (".local %cc0\n %cc0: .long 0" :: ":"(&a));
 
 int main() {
   return a + use_statics ();
diff --git a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c 
b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c
index 2b6c5539177..f0a6ec3fdf5 100644
--- a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c
+++ b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c
@@ -7,7 +7,7 @@ extern int asm_var;
 asm("%cc0:" :: ":" (&asm_var));
 
 static int a;
-asm (".local %cc0\n %cc0:" :: ":"(&a));
+asm (".local %cc0\n %cc0: .long 0" :: ":"(&a));
 
 int use_statics () {
   static_asm_fn ();
-- 
2.52.0

Reply via email to