Patchwork PATCH: PR lto/50568: [4.7 Regression] Massive LTO failures

login
register
mail settings
Submitter Andi Kleen
Date Sept. 30, 2011, 4:09 a.m.
Message ID <20110930040931.GA13480@alboin.amr.corp.intel.com>
Download mbox | patch
Permalink /patch/117020/
State New
Headers show

Comments

Andi Kleen - Sept. 30, 2011, 4:09 a.m.
I updated the patch according to your comments. Ok now?

-Andi

gcc/lto/:

2011-09-29  H.J. Lu  <hongjiu.lu@intel.com>
            Andi Kleen  <ak@linux.intel.com>

        PR lto/50568
        * lto.c (lto_splay_tree_delete_id): New.
        (lto_splay_tree_compare_ids): Likewise.
        (lto_splay_tree_lookup): Likewise.
        (lto_splay_tree_id_equal_p): Likewise.
        (lto_splay_tree_insert): Likewise.
        (lto_splay_tree_new): Likewise.
        (lto_resolution_read): Change id to unsigned HOST_WIDE_INT.
        Use lto_splay_tree_id_equal_p and lto_splay_tree_lookup.
        (create_subid_section_table): Use lto_splay_tree_lookup and
        lto_splay_tree_insert.
        (lto_file_read): Use lto_splay_tree_new.

lto-plugin/:

2011-09-29  H.J. Lu  <hongjiu.lu@intel.com>
            Andi Kleen  <ak@linux.intel.com>

        PR lto/50568
        * lto-plugin.c (sym_aux): Change id to unsigned long long.
        (plugin_symtab): Likewise.
        (dump_symtab): Likewise.
        (resolve_conflicts): Likewise.
        (process_symtab): Likewise.
---
 gcc/lto/lto.c           |   84 ++++++++++++++++++++++++++++++++++++++++++----
 lto-plugin/lto-plugin.c |   14 ++++---
 2 files changed, 84 insertions(+), 14 deletions(-)
Diego Novillo - Sept. 30, 2011, 11:03 a.m.
On Fri, Sep 30, 2011 at 00:09, Andi Kleen <ak@linux.intel.com> wrote:

> gcc/lto/:
>
> 2011-09-29  H.J. Lu  <hongjiu.lu@intel.com>
>            Andi Kleen  <ak@linux.intel.com>
>
>        PR lto/50568
>        * lto.c (lto_splay_tree_delete_id): New.
>        (lto_splay_tree_compare_ids): Likewise.
>        (lto_splay_tree_lookup): Likewise.
>        (lto_splay_tree_id_equal_p): Likewise.
>        (lto_splay_tree_insert): Likewise.
>        (lto_splay_tree_new): Likewise.
>        (lto_resolution_read): Change id to unsigned HOST_WIDE_INT.
>        Use lto_splay_tree_id_equal_p and lto_splay_tree_lookup.
>        (create_subid_section_table): Use lto_splay_tree_lookup and
>        lto_splay_tree_insert.
>        (lto_file_read): Use lto_splay_tree_new.
>
> lto-plugin/:
>
> 2011-09-29  H.J. Lu  <hongjiu.lu@intel.com>
>            Andi Kleen  <ak@linux.intel.com>
>
>        PR lto/50568
>        * lto-plugin.c (sym_aux): Change id to unsigned long long.
>        (plugin_symtab): Likewise.
>        (dump_symtab): Likewise.
>        (resolve_conflicts): Likewise.
>        (process_symtab): Likewise.

OK.


Diego.

Patch

diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 77eb1a1..778e33e 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -93,6 +93,71 @@  lto_obj_create_section_hash_table (void)
   return htab_create (37, hash_name, eq_name, free_with_string);
 }
 
+/* Delete an allocated integer KEY in the splay tree.  */
+
+static void
+lto_splay_tree_delete_id (splay_tree_key key)
+{
+  free ((void *) key);
+}
+
+/* Compare splay tree node ids A and B.  */
+
+static int
+lto_splay_tree_compare_ids (splay_tree_key a, splay_tree_key b)
+{
+  unsigned HOST_WIDE_INT ai;
+  unsigned HOST_WIDE_INT bi;
+
+  ai = *(unsigned HOST_WIDE_INT *) a;
+  bi = *(unsigned HOST_WIDE_INT *) b;
+
+  if (ai < bi)
+    return -1;
+  else if (ai > bi)
+    return 1;
+  return 0;
+}
+
+/* Look up splay tree node by ID in splay tree T.  */
+
+static splay_tree_node
+lto_splay_tree_lookup (splay_tree t, unsigned HOST_WIDE_INT id)
+{
+  return splay_tree_lookup (t, (splay_tree_key) &id);
+}
+
+/* Check if KEY has ID.  */
+
+static bool
+lto_splay_tree_id_equal_p (splay_tree_key key, unsigned HOST_WIDE_INT id)
+{
+  return *(unsigned HOST_WIDE_INT *) key == id;
+}
+
+/* Insert a splay tree node into tree T with ID as key and FILE_DATA as value. 
+   The ID is allocated separately because we need HOST_WIDE_INTs which may
+   be wider than a splay_tree_key. */
+
+static void
+lto_splay_tree_insert (splay_tree t, unsigned HOST_WIDE_INT id,
+		       struct lto_file_decl_data *file_data)
+{
+  unsigned HOST_WIDE_INT *idp = XCNEW (unsigned HOST_WIDE_INT);
+  *idp = id;
+  splay_tree_insert (t, (splay_tree_key) idp, (splay_tree_value) file_data);
+}
+
+/* Create a splay tree.  */
+
+static splay_tree
+lto_splay_tree_new (void)
+{
+  return splay_tree_new (lto_splay_tree_compare_ids,
+	 	         lto_splay_tree_delete_id,
+			 NULL);
+}
+
 /* Read the constructors and inits.  */
 
 static void
@@ -944,14 +1009,16 @@  lto_resolution_read (splay_tree file_ids, FILE *resolution, lto_file *file)
   for (i = 0; i < num_symbols; i++)
     {
       int t;
-      unsigned index, id;
+      unsigned index;
+      unsigned HOST_WIDE_INT id;
       char r_str[27];
       enum ld_plugin_symbol_resolution r = (enum ld_plugin_symbol_resolution) 0;
       unsigned int j;
       unsigned int lto_resolution_str_len =
 	sizeof (lto_resolution_str) / sizeof (char *);
 
-      t = fscanf (resolution, "%u %x %26s %*[^\n]\n", &index, &id, r_str);
+      t = fscanf (resolution, "%u " HOST_WIDE_INT_PRINT_HEX_PURE " %26s %*[^\n]\n", 
+		  &index, &id, r_str);
       if (t != 3)
         internal_error ("invalid line in the resolution file");
       if (index > max_index)
@@ -968,11 +1035,12 @@  lto_resolution_read (splay_tree file_ids, FILE *resolution, lto_file *file)
       if (j == lto_resolution_str_len)
 	internal_error ("invalid resolution in the resolution file");
 
-      if (!(nd && nd->key == id))
+      if (!(nd && lto_splay_tree_id_equal_p (nd->key, id)))
 	{
-	  nd = splay_tree_lookup (file_ids, id);
+	  nd = lto_splay_tree_lookup (file_ids, id);
 	  if (nd == NULL)
-	    internal_error ("resolution sub id %x not in object file", id);
+	    internal_error ("resolution sub id " HOST_WIDE_INT_PRINT_HEX_PURE
+			    " not in object file", id);
 	}
 
       file_data = (struct lto_file_decl_data *)nd->value;
@@ -1015,7 +1083,7 @@  create_subid_section_table (void **slot, void *data)
     return 1;
   
   /* Find hash table of sub module id */
-  nd = splay_tree_lookup (file_ids, id);
+  nd = lto_splay_tree_lookup (file_ids, id);
   if (nd != NULL)
     {
       file_data = (struct lto_file_decl_data *)nd->value;
@@ -1026,7 +1094,7 @@  create_subid_section_table (void **slot, void *data)
       memset(file_data, 0, sizeof (struct lto_file_decl_data));
       file_data->id = id;
       file_data->section_hash_table = lto_obj_create_section_hash_table ();;
-      splay_tree_insert (file_ids, id, (splay_tree_value)file_data);
+      lto_splay_tree_insert (file_ids, id, file_data);
     }
 
   /* Copy section into sub module hash table */
@@ -1104,7 +1172,7 @@  lto_file_read (lto_file *file, FILE *resolution_file, int *count)
 
   /* Find all sub modules in the object and put their sections into new hash
      tables in a splay tree. */
-  file_ids = splay_tree_new (splay_tree_compare_ints, NULL, NULL);
+  file_ids = lto_splay_tree_new ();
   htab_traverse (section_hash_table, create_subid_section_table, file_ids);
   
   /* Add resolutions to file ids */
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index 4b5828b..9323bd2 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -80,12 +80,13 @@  along with this program; see the file COPYING3.  If not see
 
 /* The part of the symbol table the plugin has to keep track of. Note that we
    must keep SYMS until all_symbols_read is called to give the linker time to
-   copy the symbol information. */
+   copy the symbol information. 
+   The id must be 64bit to minimze collisions. */
 
 struct sym_aux
 {
   uint32_t slot;
-  unsigned id;
+  unsigned long long id;
   unsigned next_conflict;
 };
 
@@ -94,7 +95,7 @@  struct plugin_symtab
   int nsyms;
   struct sym_aux *aux;
   struct ld_plugin_symbol *syms;
-  unsigned id;
+  unsigned long long id;
 };
 
 /* Encapsulates object file data during symbol scan.  */
@@ -359,7 +360,8 @@  dump_symtab (FILE *f, struct plugin_symtab *symtab)
       
       assert (resolution != LDPR_UNKNOWN);
 
-      fprintf (f, "%u %x %s %s\n", (unsigned int) slot, symtab->aux[j].id,
+      fprintf (f, "%u %llx %s %s\n",
+               (unsigned int) slot, symtab->aux[j].id,
 	       lto_resolution_str[resolution], 
 	       symtab->syms[j].name);
     }
@@ -759,7 +761,7 @@  resolve_conflicts (struct plugin_symtab *t, struct plugin_symtab *conflicts)
 	    {
 	      SWAP (struct ld_plugin_symbol, *orig, *s);
 	      SWAP (uint32_t, orig_aux->slot, aux->slot);
-	      SWAP (unsigned, orig_aux->id, aux->id);
+	      SWAP (unsigned long long, orig_aux->id, aux->id);
 	      /* Don't swap conflict chain pointer */
 	    } 
 
@@ -809,7 +811,7 @@  process_symtab (void *data, const char *name, off_t offset, off_t length)
 
   s = strrchr (name, '.');
   if (s)
-    sscanf (s, ".%x", &obj->out->id);
+    sscanf (s, ".%llx", &obj->out->id);
   secdata = xmalloc (length);
   offset += obj->file->offset;
   if (offset != lseek (obj->file->fd, offset, SEEK_SET)