lto: Fix up lto BLOCK tree streaming
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Sep 2020 18:55:46 +0000 (20:55 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 10 Sep 2020 18:55:46 +0000 (20:55 +0200)
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).

gcc/lto-streamer-out.c

index 354ba01b59723be8fed6d1d4faa369fced125f11..7882c89388dc49e40f14d52eaf94e211367b6946 100644 (file)
@@ -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