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;