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

Reply via email to