This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Symtab cleanup 10/17 remove unnecesary DECL_ARGUMENTS and DECL_RESULT


> 
> But we still refer to the local entity from TREE_TYPE of the function decl,
> no?

depending on definition of local entity.  I tought we was discussing if PARM_DECL
is local or not.

I spent some time thining about the whole streaming scheme and I think we do have
important side cases handled incorrectly.  Lets try to discuss things.  I will try
to summarize my understanding to make sure we are on sync and I do not miss something
important.

So we now have two types of streams
  - the global stream
    this stream is one per compilation unit and it gets load into WPA
    and merged with other streams by tree mergina and LTO-symtab resolution.
  - local stream.
    this stream is local for function (and hope for variable initializer soon, too),
    it is read when we need the function body and it is not in any way merged with
    global stream, except that the references to global streams are resolved
    after merging

We do have way to express references from local stream to global stream.  We however
can not express
  A) references from global stream to local stream 
  B) references in between two different local streams.

The decision what should go to local or global stream is basically motivated by
  1) everything needed for interprocedural optimization has to be global
  2) everything related to function bodies should be local.

For tree nodes, the decision about where the node goes is made by
tree_is_indexable.  The current set of rules is
 - parm_decl/result_decl is local
   (before my change resut_decl was global and parm_decl was local, why those
    was not the same escapes me, but it needed ugly fixup in ipa-prop that
    needed to reconnect global DECL pointers to local DECL pointers after
    streaming in)
 - function variables are local if they are not static.
   (Even external declarations are local, not only automatic vars.)
 - Types are global unless they are variably modified types
   (The variably modified type code walks into subtypes, so even pointers
   to variably modified type are local or function declarations mentioning
   these.)
 - FIELD_DECL is global unless it is part of variably modified type.
 - SSA_NAME is local despite logic of tree_is_indexable because it is handled
   separately as part of gimple and gimple is always local.
 - LABEL_DECLs are global even when their address is not taken and it would make
   more sense to hide it in the body sections

Now I think we are safe only when our references never violate A) and B) and moreover 
C) same entity that needs to be unique (such as declarations by one decl rule
   or BLOCK) is not streamed into multiple streams.  We never merge things
   between streams and duplicating those is forbidden by design.

It is an irritating property of our streaming machinery that it is not
diagnozing violations of A/B/C. Violations of type A and B are basically hidden
by introducing violations of type C and compiler tends to be resistant to those
in a sense that is usually does not ICE.

Now I only once added sanity check for C and larnt that

 1) variably sized types may end up being twice - in global stream because they are
    mentioned by FUNCTION_DECL/VARIABLE_DECL or TYPE_DECL
    and local stream because of tree_is_indexable rule

    Moreover they violate A after landing in global stream because they refer
    to temporaries in the gimple body.
    As you mentioned, we may want to clear TYPE_SIZE and variable DECL_FIELD_OFFSET.
    But sadly I think dwarf2out needs both and gimple land needs DECL_FIELD_OFFSET.
 2) TYPE_DECLS of local types (common in C++) tends to drag into global stream
    BLOCK that later brings to global stream the local variables.

    Making function local TYPE_DECLs local seems cool, but it break A because
    function/local static variable types may reffer to them.
 3) _ORIGIN pointers violate B by design.
 4) LABEL_DECL with address taken violate A and B.

I am sure this list is not complette.

Now we can play about what can be global or local.  Like putting PARM_DECL into global
stream only, or returning RESULT_DECL into global decl stream.  But
I do not really see how much chance it has to fix 1-4.  I think the general flaw
is that functions/static variables (we absolutely need in global stream) may reffer
to local entities by contextes and variably sized types.  

Either we need to consistently not stream pointers causing the violations above
- i.e. clear them in free_lang_data and make backend not dependent on them. Or
we need to find way to make references of type A and perhaps B possible.  I can
think of <local_ref function_decl localid> tree construct that we patch in and
replace by actual declaration after reading function_decl body when it is
needed (by dwarf2out or tree optimizers), but it does not seem cool to me either.
We will like soon notice that with comdats localid needs to be unique across
the merged comdat bodies or somehting similarly nasty.

Another alternative I can think of is to declare duplication in between streams
sane and allowed, but teach streaming in code to patch in the in-memory
representation from global stream by local stream one when this happens.  It
seems bit tricky to implement - the decl states of functions would need to
explicitly record the duplications in between local and global streams.

Honza


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]