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