This implements what was probably intended(?) -- streaming DECL_INITIAL
as a whole (full BLOCK tree plus associated BLOCK_VARs) in
output_function.  Currently we only stream the outermost BLOCK
(and its vars) and the rest lazily during statement streaming
when we somehow get a BLOCK reference or a VAR_DECL reference.

I'm not sure we're not missing unreferenced BLOCKs with still used
VAR_DECLs of them and thus will fail to annotate the VAR_DECL DIEs
with locations in late LTO debug.

LTO bootstrap / regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-10-07  Richard Biener  <rguent...@suse.de>

        * lto-streamer-out.c (collect_block_tree_leafs): New helper.
        (output_function): Properly stream the whole block tree.
        * lto-streamer-in.c (input_function): Likewise.

Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c      (revision 240855)
+++ gcc/lto-streamer-out.c      (working copy)
@@ -2016,6 +2016,18 @@ output_struct_function_base (struct outp
 }
 
 
+/* Collect all leaf BLOCKs beyond ROOT into LEAFS.  */
+
+static void
+collect_block_tree_leafs (tree root, vec<tree> &leafs)
+{
+  for (root = BLOCK_SUBBLOCKS (root); root; root = BLOCK_CHAIN (root))
+    if (! BLOCK_SUBBLOCKS (root))
+      leafs.safe_push (root);
+    else
+      collect_block_tree_leafs (BLOCK_SUBBLOCKS (root), leafs);
+}
+
 /* Output the body of function NODE->DECL.  */
 
 static void
@@ -2048,10 +2060,15 @@ output_function (struct cgraph_node *nod
   streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
 
   /* Output DECL_INITIAL for the function, which contains the tree of
-     lexical scopes.
-     ???  This only streams the outermost block because we do not
-     recurse into BLOCK_SUBBLOCKS but re-build those on stream-in.  */
+     lexical scopes.  */
   stream_write_tree (ob, DECL_INITIAL (function), true);
+  /* As we do not recurse into BLOCK_SUBBLOCKS but only BLOCK_SUPERCONTEXT
+     collect block tree leafs and stream those.  */
+  auto_vec<tree> block_tree_leafs;
+  collect_block_tree_leafs (DECL_INITIAL (function), block_tree_leafs);
+  streamer_write_uhwi (ob, block_tree_leafs.length ());
+  for (unsigned i = 0; i < block_tree_leafs.length (); ++i)
+    stream_write_tree (ob, block_tree_leafs[i], true);
 
   /* We also stream abstract functions where we stream only stuff needed for
      debug info.  */
Index: gcc/lto-streamer-in.c
===================================================================
--- gcc/lto-streamer-in.c       (revision 240855)
+++ gcc/lto-streamer-in.c       (working copy)
@@ -1036,6 +1036,9 @@ input_function (tree fn_decl, struct dat
 
   /* Read the tree of lexical scopes for the function.  */
   DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
+  unsigned block_leaf_count = streamer_read_uhwi (ib);
+  while (block_leaf_count--)
+    stream_read_tree (ib, data_in);
 
   if (!streamer_read_uhwi (ib))
     return;

Reply via email to