Patchwork Fix non-deterministic output order for type stubs in DWARF output

login
register
mail settings
Submitter Cary Coutant
Date April 24, 2013, 10:50 p.m.
Message ID <CAHACq4o0k1RsGpn9XhjiPQ7qj+3JkPJLwW4xD4WPEkk6C0N+RQ@mail.gmail.com>
Download mbox | patch
Permalink /patch/239328/
State New
Headers show

Comments

Cary Coutant - April 24, 2013, 10:50 p.m.
Jason, would you like to take a look at this patch before I commit it?

If I turn on -fdebug-types-section, I get a random failure in
g++.dg/pch/system-2.C. This failure is being caused by
non-deterministic order of the type stubs emitted by
optimize_external_refs, because it's using the address of the DIE as a
hash for the extern_map hash table. This patch makes the output order
deterministic by using either the die_symbol (as a string) or the type
signature for the hash value.

Bootstrapped on x86_64 with no regressions.

(I'm not planning to turn on -fdebug-types-section by default; I'm
just trying to make sure the test suite is clean with it on so that I
can turn it on in the google branches.)

-cary


2013-04-24  Cary Coutant  <ccoutant@google.com>

gcc/
        * dwarf2out.c (hash_external_ref): Use die_symbol or signature
        for hash so that hash table traversal order is deterministic.
Cary Coutant - June 10, 2013, 11:50 p.m.
I've committed this patch.

-cary


2013-06-10  Cary Coutant  <ccoutant@google.com>

gcc/
        * dwarf2out.c (hash_external_ref): Use die_symbol or signature
        for hash so that hash table traversal order is deterministic.



> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c     (revision 198260)
> +++ gcc/dwarf2out.c     (working copy)
> @@ -7385,7 +7385,22 @@ static hashval_t
>  hash_external_ref (const void *p)
>  {
>    const struct external_ref *r = (const struct external_ref *)p;
> -  return htab_hash_pointer (r->type);
> +  dw_die_ref die = r->type;
> +  hashval_t h = 0;
> +
> +  /* We can't use the address of the DIE for hashing, because
> +     that will make the order of the stub DIEs non-deterministic.  */
> +  if (! die->comdat_type_p)
> +    /* We have a symbol; use it to compute a hash.  */
> +    h = htab_hash_string (die->die_id.die_symbol);
> +  else
> +    {
> +      /* We have a type signature; use a subset of the bits as the hash.
> +         The 8-byte signature is at least as large as hashval_t.  */
> +      comdat_type_node_ref type_node = die->die_id.die_type_node;
> +      memcpy (&h, type_node->signature, sizeof (h));
> +    }
> +  return h;
>  }
>
>  /* Compare external_refs.  */

Patch

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c     (revision 198260)
+++ gcc/dwarf2out.c     (working copy)
@@ -7385,7 +7385,22 @@  static hashval_t
 hash_external_ref (const void *p)
 {
   const struct external_ref *r = (const struct external_ref *)p;
-  return htab_hash_pointer (r->type);
+  dw_die_ref die = r->type;
+  hashval_t h = 0;
+
+  /* We can't use the address of the DIE for hashing, because
+     that will make the order of the stub DIEs non-deterministic.  */
+  if (! die->comdat_type_p)
+    /* We have a symbol; use it to compute a hash.  */
+    h = htab_hash_string (die->die_id.die_symbol);
+  else
+    {
+      /* We have a type signature; use a subset of the bits as the hash.
+         The 8-byte signature is at least as large as hashval_t.  */
+      comdat_type_node_ref type_node = die->die_id.die_type_node;
+      memcpy (&h, type_node->signature, sizeof (h));
+    }
+  return h;
 }

 /* Compare external_refs.  */