fix LTO streaming order dependence on randomness
authorRichard Biener <rguenther@suse.de>
Mon, 6 Jul 2020 09:30:53 +0000 (11:30 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 7 Jul 2020 06:43:23 +0000 (08:43 +0200)
This fixes the sorting of to copy symbols in lto_output introduced
with GCC 10 to not depend on the actual values of the randomness
we append to LTO section names but instead on the order they appear
in the unsorted array.

This fixed observed debug info differences due to tree merging
prevailing different early debug pointers.

2020-07-06  Richard Biener  <rguenther@suse.de>

* lto-streamer-out.c (cmp_symbol_files): Use the computed
order map to sort symbols from the same sub-file together.
(lto_output): Compute a map of sub-file to an order number
it appears in the symbol output array.

gcc/lto-streamer-out.c

index 059688821ccc04b35f95699f3040a830c7fcdbbf..ec28928b56abc9e452bbe0e726201509a849e5cc 100644 (file)
@@ -2614,10 +2614,12 @@ produce_lto_section ()
 /* Compare symbols to get them sorted by filename (to optimize streaming)  */
 
 static int
-cmp_symbol_files (const void *pn1, const void *pn2)
+cmp_symbol_files (const void *pn1, const void *pn2, void *id_map_)
 {
   const symtab_node *n1 = *(const symtab_node * const *)pn1;
   const symtab_node *n2 = *(const symtab_node * const *)pn2;
+  hash_map<lto_file_decl_data *, int> *id_map
+    = (hash_map<lto_file_decl_data *, int> *)id_map_;
 
   int file_order1 = n1->lto_file_data ? n1->lto_file_data->order : -1;
   int file_order2 = n2->lto_file_data ? n2->lto_file_data->order : -1;
@@ -2629,12 +2631,7 @@ cmp_symbol_files (const void *pn1, const void *pn2)
 
   /* Order within static library.  */
   if (n1->lto_file_data && n1->lto_file_data->id != n2->lto_file_data->id)
-    {
-      if (n1->lto_file_data->id > n2->lto_file_data->id)
-       return 1;
-      if (n1->lto_file_data->id < n2->lto_file_data->id)
-       return -1;
-    }
+    return *id_map->get (n1->lto_file_data) - *id_map->get (n2->lto_file_data);
 
   /* And finaly order by the definition order.  */
   return n1->order - n2->order;
@@ -2690,7 +2687,23 @@ lto_output (void)
            symbols_to_copy.safe_push (node);
        }
     }
-  symbols_to_copy.qsort (cmp_symbol_files);
+  /* Map the section hash to an order it appears in symbols_to_copy
+     since we want to sort same ID symbols next to each other but need
+     to avoid making overall order depend on the actual hash value.  */
+  int order = 0;
+  hash_map<lto_file_decl_data *, int> id_map;
+  for (i = 0; i < symbols_to_copy.length (); ++i)
+    {
+      symtab_node *snode = symbols_to_copy[i];
+      if (snode->lto_file_data)
+       {
+         bool existed_p = false;
+         int &ord = id_map.get_or_insert (snode->lto_file_data, &existed_p);
+         if (!existed_p)
+           ord = order++;
+       }
+    }
+  symbols_to_copy.sort (cmp_symbol_files, (void *)&id_map);
   for (i = 0; i < symbols_to_copy.length (); i++)
     {
       symtab_node *snode = symbols_to_copy[i];