[debug-early] call debug_hooks->late_global_decl for optimized away symbols

Aldy Hernandez aldyher@gmail.com
Thu May 7 00:43:00 GMT 2015


This is a problem I found while bootstrapping on ppc64-linux, but is a 
problem we will run into sooner or later.

As I've mentioned before, the fact that we call 
debug_hooks->late_global_decl() on symbols from the symbol table means 
that we miss out on symbols that were removed from the symbol table.  
Why our symbol table design removes optimized symbols is beyond me, but 
that's just me...

So imagine a variable Foo that will be optimized away:

     typedef float FloatVect __attribute__((__vector_size__(16)));
     static FloatVect Foo = { 250000000.0, 0.0, 0.0, 0.0 };

On ppc64 with AldyVec, Foo is marked as constant, DECL_INITIAL is set to 
a vector constant, and all that.  The dwarf debugging back end would 
like to mark the DIE as constant (by looking at the tree decl if 
possible), but it never sees it through late_global_decl() because 
late_global_decl() only gets symtab entries, and this symbol has been 
removed.

This may also cause problems with non-dwarf backends, because they were 
used to seeing optimized-away symbols.

I thought about this, and figured that we could call late_global_decl() 
on symbols right before we delete them, thus giving the debug backends 
one last chance to look at the symbol before they get wiped out.  So, 
with this idea, we can have our cake and eat it too: late_global_decl() 
gets called on optimized away symbols giving dwarf a chance to perhaps 
look at tree bits that may determine usability, while still keeping our 
generic interface iterating through the remaining symbol table.

The attached patch fixes the regression and gets ppc64-linux on par with 
x86_64-linux.  And if AIX ever finishes the tests I started this morning 
(may require a few more months), we can verify stabs happiness.

Committing to branch.

Both x86-64 Linux and ppc64 Linux are ready to go.  Once AIX is happy, I 
will post the full patch for review.

Aldy
-------------- next part --------------
commit e817b2d5c219c7b1bc6918de01c39ea66b01cf15
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Wed May 6 17:22:16 2015 -0700

    Call late_global_decl on DECLs that are about to be removed from the
    symbol table.

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0873162..faa953a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1131,6 +1131,19 @@ analyze_functions (bool first_time)
 	{
 	  if (symtab->dump_file)
 	    fprintf (symtab->dump_file, " %s", node->name ());
+
+	  /* See if the debugger can use anything before the DECL
+	     passes away.  Perhaps it can notice a DECL that is now a
+	     constant and can tag the early DIE with an appropriate
+	     attribute.
+
+	     Otherwise, this is the last chance the debug_hooks have
+	     at looking at optimized away DECLs, since
+	     late_global_decl will subsequently be called from the
+	     contents of the now pruned symbol table.  */
+	  if (!decl_function_context (node->decl))
+	    (*debug_hooks->late_global_decl) (node->decl);
+
 	  node->remove ();
 	  continue;
 	}
diff --git a/gcc/debug.h b/gcc/debug.h
index c360e5c..251642f 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -119,7 +119,8 @@ struct gcc_debug_hooks
      after the compilation proper has finished and cgraph information
      is available.
 
-     Location information is available at this point.
+     Location information is usually available at this point, unless
+     the hook is being called for a decl that has been optimized away.
 
      This hook may be called on VAR_DECLs or FUNCTION_DECLs.  It is up
      to the hook to use what it needs.  */
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index fb07821..8e82a9b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -25467,7 +25467,11 @@ dwarf2out_early_finish (void)
 	 free-lang-data.  */
       if (((!flag_generate_lto && !flag_generate_offload)
 	   || DECL_ASSEMBLER_NAME_SET_P (decl))
-	  && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
+	  && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)
+	  /* A missing DECL_ASSEMBLER_NAME can be a constant DIE that
+	     ended up in in deferred_asm_name before we knew it was
+	     constant and never written to disk.  */
+	  && DECL_ASSEMBLER_NAME (decl))
 	{
 	  add_linkage_attr (node->die, decl);
 	  move_linkage_attr (node->die);


More information about the Gcc-patches mailing list