diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-09-10 20:55:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-09-10 20:55:46 +0200 |
commit | a8f9b4c54cc350625accbb2c6b4005acb42d4c2e (patch) | |
tree | aeb1f58c4a5e0c404dff92e04f33f87417b23ccd | |
parent | 1d5589d11e61fa78b0c0e845728412b1cc6043d8 (diff) | |
download | gcc-a8f9b4c54cc350625accbb2c6b4005acb42d4c2e.zip gcc-a8f9b4c54cc350625accbb2c6b4005acb42d4c2e.tar.gz gcc-a8f9b4c54cc350625accbb2c6b4005acb42d4c2e.tar.bz2 |
lto: Fix up lto BLOCK tree streaming
When I've tried to backport recent LTO changes of mine, I've ran into
FAIL: g++.dg/ubsan/align-3.C -O2 -flto -fno-use-linker-plugin -flto-partition=none output pattern test
FAIL: g++.dg/ubsan/align-3.C -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects output pattern test
regressions that don't for some reason show up on the trunk.
I've tracked it down to input_location_and_block being called recursively,
first on some UBSAN_NULL ifn call's location which needs to stream a BLOCK
that hasn't been streamed yet, which in turn needs to stream some locations
for the decls in the BLOCK.
Looking at that align-3.C testcase on the trunk, I also see the recursive
lto_output_location_1 calls as well. First on block:
$18 = <block 0x7fffea738480>
which is in the block tree from what I can see just fine (see the end of
mail).
Now, output_function has code that should stream the BLOCK tree leafs:
/* Output DECL_INITIAL for the function, which contains the tree of
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;
if (DECL_INITIAL (function))
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);
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);
}
but the problem is that it is broken, it doesn't cover all block leafs,
but only leafs with an odd depth from DECL_INITIAL (and only some of those).
The following patch fixes that, but I guess we are going to stream at that
point significantly more blocks than before (though I guess most of the time
we'd stream them later on when streaming the gimple_locations that refer to
them).
2020-09-10 Jakub Jelinek <jakub@redhat.com>
* lto-streamer-out.c (collect_block_tree_leafs): Recurse on
root rather than BLOCK_SUBBLOCKS (root).
-rw-r--r-- | gcc/lto-streamer-out.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 354ba01..7882c89 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -2294,7 +2294,7 @@ collect_block_tree_leafs (tree root, vec<tree> &leafs) if (! BLOCK_SUBBLOCKS (root)) leafs.safe_push (root); else - collect_block_tree_leafs (BLOCK_SUBBLOCKS (root), leafs); + collect_block_tree_leafs (root, leafs); } /* This performs function body modifications that are needed for streaming |