Three issues

Gary Oblock gary@amperecomputing.com
Wed Jul 22 18:52:53 GMT 2020


David,

Note, for the first explanation, this is the hash table for the default defs and not
some private pass specific table so I'm not directly touching it in way. However, that
doesn't mean some other common or not so common function I'm invoking has
the side effect of doing this in some pathological way (you point this out by asking
if they are my temporaries.) I do create temporaries but I certainly make no attempt
to add them to the default defs. In fact, I went so far as to instrument the code that
adds them to see if I was doing this but I found nothing. This likely means I'm causing
a subtle memory corruption or something I'm doing has bad side effects.

The second option (not an explanation) has me diddling some fairly important stuff
that I don't know all that much about therefore I prefer to find and fix the root cause.

Thanks,

Gary



________________________________
From: David Malcolm <dmalcolm@redhat.com>
Sent: Wednesday, July 22, 2020 12:31 AM
To: Gary Oblock <gary@amperecomputing.com>; gcc@gcc.gnu.org <gcc@gcc.gnu.org>
Subject: Re: Three issues

[EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please be mindful of safe email handling and proprietary information protection practices.]


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



More information about the Gcc mailing list