On Tue, 2020-07-21 at 22:49 +0000, Gary Oblock via Gcc wrote:
> Some background:
>
> This is in the dreaded structure reorganization optimization that I'm
> working on. It's running at LTRANS time with '-flto-partition=one'.
>
> My issues in order of importance are:
>
> 1) In gimple-ssa.h, the equal method for ssa_name_hasher
> has a segfault because the "var" field of "a" is (nil).
>
> struct ssa_name_hasher : ggc_ptr_hash<tree_node>
> {
> /* Hash a tree in a uid_decl_map. */
>
> static hashval_t
> hash (tree item)
> {
> return item->ssa_name.var->decl_minimal.uid;
> }
>
> /* Return true if the DECL_UID in both trees are equal. */
>
> static bool
> equal (tree a, tree b)
> {
> return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var-
> >decl_minimal.uid);
> }
> };
I notice that tree.h has:
/* Returns the variable being referenced. This can be NULL_TREE for
temporaries not associated with any user variable.
Once released, this is the only field that can be relied upon. */
#define SSA_NAME_VAR(NODE) \
(SSA_NAME_CHECK (NODE)->ssa_name.var == NULL_TREE \
|| TREE_CODE ((NODE)->ssa_name.var) == IDENTIFIER_NODE \
? NULL_TREE : (NODE)->ssa_name.var)
So presumably that ssa_name_hasher is making an implicit assumption
that such temporaries aren't present in the hash_table; maybe they are
for yours?
Is this a hash_table that you're populating yourself?
With the caveat that I'm sleep-deprived, another way this could happen
is if "a" is not an SSA_NAME but is in fact some other kind of tree;
you could try replacing
a->ssa_name.ver
with
SSA_NAME_CHECK (a)->ssa_name.var
(and similarly for b)
But the first explanation seems more likely.
>
[...snip qn 2...]
> 3) For my bug in (1) I got so distraught that I ran valgrind which
> in my experience is an act of desperation for compilers.
>
> None of the errors it spotted are associated with my optimization
> (although it oh so cleverly pointed out the segfault) however it
> showed the following:
>
> ==18572== Invalid read of size 8
> ==18572== at 0x1079DC1: execute_one_pass(opt_pass*)
> (passes.c:2550)
What is line 2550 of passes.c in your working copy?
==18572== by 0x107ABD3: execute_ipa_pass_list(opt_pass*)
> (passes.c:2929)
> ==18572== by 0xAC0E52: symbol_table::compile() (cgraphunit.c:2786)
> ==18572== by 0x9915A9: lto_main() (lto.c:653)
> ==18572== by 0x11EE4A0: compile_file() (toplev.c:458)
> ==18572== by 0x11F1888: do_compile() (toplev.c:2302)
> ==18572== by 0x11F1BA3: toplev::main(int, char**) (toplev.c:2441)
> ==18572== by 0x23C021E: main (main.c:39)
> ==18572== Address 0x5842880 is 16 bytes before a block of size 88
> alloc'd
> ==18572== at 0x4C3017F: operator new(unsigned long) (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==18572== by 0x21E00B7: make_pass_ipa_prototype(gcc::context*)
> (ipa-prototype.c:329)
You say above that none of the errors are associated with your
optimization, but presumably this is your new pass, right? Can you
post the code somewhere?
> ==18572== by 0x106E987:
> gcc::pass_manager::pass_manager(gcc::context*) (pass-
> instances.def:178)
> ==18572== by 0x11EFCE8: general_init(char const*, bool)
> (toplev.c:1250)
> ==18572== by 0x11F1A86: toplev::main(int, char**) (toplev.c:2391)
> ==18572== by 0x23C021E: main (main.c:39)
> ==18572==
>
> Are these known issues with lto or is this a valgrind issue?
Hope this is helpful
Dave