On Thu, Sep 10, 2020 at 04:09:24PM +0200, Richard Biener wrote:
> So we're usually streaming the bits and the tree portion of SCCs
> separately so I really wonder how we can end up with recursion here?
> For stmts they should only refer to BLOCKs also in the BLOCK tree
> which is streamed in before we stream in the stmts(?).
> 
> So - isn't this an undetected stmt/tree references BLOCK not in
> BLOCK tree bug?  See verify_location which might or might not
> handle all locations "correctly" though it looks like it obviously
> verifies all stmts locations this way.  So the question is whether
> the function would pass verification at stream-out time ...

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  <ja...@redhat.com>

        * lto-streamer-out.c (collect_block_tree_leafs): Recurse on
        root rather than BLOCK_SUBBLOCKS (root).

--- gcc/lto-streamer-out.c.jj   2020-09-10 15:52:36.401413518 +0200
+++ gcc/lto-streamer-out.c      2020-09-10 17:14:24.934503237 +0200
@@ -2294,7 +2294,7 @@ collect_block_tree_leafs (tree root, vec
     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


(gdb) p debug_tree (((tree)0x7fffea71d700)->decl_common.initial)
 <block 0x7fffea6f9ea0 used tree_0
    supercontext <function_decl 0x7fffea71d700 main
        type <function_type 0x7fffea8259d8 type <integer_type 0x7fffea8145e8 
int>
            QI
            size <integer_cst 0x7fffea7f5f60 constant 8>
            unit-size <integer_cst 0x7fffea7f5f78 constant 1>
            align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7fffea8259d8
            arg-types <tree_list 0x7fffea80a8e8 value <void_type 0x7fffea814f18 
void>>>
        addressable nothrow public static function-specific-target 
function-specific-opt decl_5 QI 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C:23:1 align:8 
warn_if_not_align:0 context <translation_unit_decl 0x7fffea803168 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C> initial <block 
0x7fffea6f9ea0>
        result <result_decl 0x7fffea70de10 D.6516 type <integer_type 
0x7fffea8145e8 int>
            ignored SI 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C:23:11
            size <integer_cst 0x7fffea8170c0 constant 32>
            unit-size <integer_cst 0x7fffea8170d8 constant 4>
            align:32 warn_if_not_align:0 context <function_decl 0x7fffea71d700 
main>>
        struct-function 0x7fffea714840
        chain <var_decl 0x7fffea719120 s type <record_type 0x7fffea71a0a8 S>
            addressable used public static read BLK 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C:20:69
            size <integer_cst 0x7fffea817330 constant 192>
            unit-size <integer_cst 0x7fffea817300 constant 24>
            align:128 warn_if_not_align:0 context <translation_unit_decl 
0x7fffea803168 /usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C> chain 
<type_decl 0x7fffea718098 S>>>
    subblocks <block 0x7fffea7384e0 used supercontext <block 0x7fffea6f9ea0>
        subblocks <block 0x7fffea738540 used supercontext <block 0x7fffea7384e0>
            subblocks <block 0x7fffea7385a0 used supercontext <block 
0x7fffea738540>
                abstract_origin <block 0x7fffea6f9a80 used supercontext 
<function_decl 0x7fffea713b00 __ct >>> abstract_origin <block 0x7fffea6f9a80>>
        chain <block 0x7fffea7383c0 used supercontext <block 0x7fffea6f9ea0>
            subblocks <block 0x7fffea738480 used supercontext <block 
0x7fffea7383c0>

                             ^^^^^^^^^^^^^^ HERE

                abstract_origin <block 0x7fffea6f9c00 used supercontext 
<function_decl 0x7fffea713c00 __dt >>>
            chain <block 0x7fffea7381e0 used supercontext <block 0x7fffea6f9ea0>
                subblocks <block 0x7fffea738240 used supercontext <block 
0x7fffea7381e0>
                    subblocks <block 0x7fffea7382a0 used supercontext <block 
0x7fffea738240> abstract_origin <block 0x7fffea6f9a80>> abstract_origin <block 
0x7fffea6f9a80>>
                chain <block 0x7fffea6f9f00 used supercontext <block 
0x7fffea6f9ea0>
                    subblocks <block 0x7fffea738000 used supercontext <block 
0x7fffea6f9f00> abstract_origin <block 0x7fffea6f9c00>> abstract_origin 
<function_decl 0x7fffea717200 __dt_base >> abstract_origin <function_decl 
0x7fffea713b00 __ct >> abstract_origin <function_decl 0x7fffea717200 __dt_base 
>>
        abstract_origin <function_decl 0x7fffea713b00 __ct  type <method_type 
0x7fffea711498>
            addressable asm_written used nothrow public static abstract 
external weak autoinline decl_5 QI defer-output 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C:14:3 align:16 
warn_if_not_align:0 context <translation_unit_decl 0x7fffea803168 
/usr/src/gcc-10/gcc/testsuite/g++.dg/ubsan/align-3.C> initial <error_mark 
0x7fffea7f5e58> chain <function_decl 0x7fffea717000 __ct_base >>>>


        Jakub

Reply via email to