This is the mail archive of the gcc-bugs@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]

[Bug debug/44712] Debug info for partially inlined functions



------- Comment #2 from roland at redhat dot com  2010-07-01 18:56 -------
The foo.part.0 DW_TAG_subprogram should get DW_AT_artificial.
IMHO that is equivalent to any other hypothetical case where
the compiler decides to spin a function where there was not
exactly one in the source.  That fits OpenMP cases, and also
any other hypothetical case, e.g. if for plain:

        for (i = ...) { long stretch of cse'able using i }
        for (j = ...) { long stretch of cse'able using j }

the compiler decides the best thing is to make a subroutine
of { long stretch of cse'able using argument } and turn each
loop body into a call.

It's not immediately clear to me what purpose is served by
DW_AT_abstract_origin on the foo.part.0 DW_TAG_subprogram.  In the
trivial example as given, I'm not sure there is any positive reason to
have it at all.  But I suppose there is a DW_TAG_formal_parameter for
foo.part.0's argument, and that should have DW_AT_abstract_origin to the
source foo DW_TAG_subprogram's DW_TAG_formal_parameter.

If there are various unperturbed things in the foo scope (types, statics,
unused variables, etc.) then DW_AT_abstract_origin is right to indicate
those are in scope where foo.part.0's PC ranges lie.

It would be nice to get the implied semantic copying of whatever is not
overridden in the cases less close to an inline.  e.g. my "cse'able"
case above (or real-world OpenMP equivalent), would like to have the
compiler-invented subroutine use DW_AT_abstract_origin or equivalent to
pull in the scope of the DW_TAG_lexical_block or whatever it was that is
the semantic scope of the synthetic callee.

IMHO the foo.part.0 case should actually be considered one of these
cases rather than a traditional "out of line instance of an abstract
inline instance".  foo.part.0 is not really the equivalent of any source
subprogram.  It's really a subset of that, equivalent either to some
source DW_TAG_lexical_block or just to a portion of a DW_TAG_subprogram.

I think we should recommend new DWARF spec wording (extending 3.3.8) for
this use.  Such uses are squarely within the "permissive rather than
prescriptive" principle (1.3) anyway.

Let any scope entry, i.e. DW_TAG_lexical_block et al, be an "abstract
instance root", not just DW_TAG_subprogram.  (Possibly you could put a
DW_AT_inline on such entries, but that doesn't really make sense.
Instead just reword 3.3.8.1 to define "abstract instance entry"
independent of DW_AT_inline.)  Then some DW_TAG_subprogram might have
DW_AT_abstract_origin pointing to that abstract instance root, and have
children with DW_AT_abstract_origin pointing to a corresponding child of
the non-subprogram abstract instance root.

When a concrete instance entry points to an abstract instance entry of a
different tag, it only makes sense if the concrete instance entry is
marked artificial.  e.g., artifical subprogram -> lexical_block.  (If
the subprogram weren't artificial, there would be a source-centric
abstract instance entry for it to point to that is a subprogram.)

In some cases there may be no natural source-centric abstract instance
entry to refer to.  (This is probably so in the "bar" example--it is if
foo.part.0 takes the "x" parameter and contains the "if (x <= 0)" test,
not just its then-block.  It certainly would be in a case where "foo"
were written without braces in that then-clause.)  Then I see two
options that might make sense:

1. Use the containing semantic scope as DW_AT_abstract_origin for the
   artificial subprogram.  In the example, foo.part.0 points to the
   DW_AT_subprogram for "foo" (as you say it happens to do today).
   This seems fine when the artificial subprogram is quite close to a
   semantic match for the source subprogram, i.e. a close subset like
   foo.part.0 is of the source foo.

   But it's less clear when it would be some large subprogram (or
   other, inner scope entry), of which the synthetic call represents
   only a small part.  e.g. my "cse'able" cases when those loops
   appear inside a huge "main" with a hundred other things.

   It also becomes potentially ambiguous how to take it.  If the
   referent is a DW_TAG_subprogram that does not have DW_AT_inline,
   then you could say that this must be the container of an artificial
   call rather than the normal abstract inline instance entry
   corresponding to a normal concrete inline instance entry.  But if
   the referent DW_TAG_subprogram happens to be an abstract inline
   instance root independently, it would have DW_AT_inline though that
   means nothing for this reference.  I suppose you always know
   whether the referring subprogram is marked artifical and that alone
   disambiguates, so maybe this is OK.  Still it's perhaps just too
   subtle/confusing what this kind of reference means.

2. Emit an artifical entry in the semantic scope of the code that was
   moved into the synthetic callee, just to be what the artificial
   subprogram's abstract_origin points to.

   This could overload an existing tag with a close-enough meaning,
   e.g. DW_TAG_label with DW_AT_artificial (and no name).  It could even
   be DW_TAG_dwarf_procedure (generalizing its meaning to any
   "placeholder for purpose of being some reference attribute's target").
   The entry just serves as a placeholder that is owned by the
   appropriate scope, and (perhaps) sits in the relative ordering of
   other semantic source-based entries for the scope's control flow as
   would a source label at the beginning of the code that got folded into
   the synthetic subroutine.

   In the long run this should probably instead be a new tag that
   specifically to an emitted call site, here marked artificial.

If the artificial subprogram has parameters, these will have a
formal_parameter entry there (with location).  If a formal_parameter
corresponds exactly to a parameter of the caller frame, then it has an
abstract_origin pointer to the caller's formal_parameter entry (which
gives it a name, etc.).  If things haven't gone awry (and modulo source
code that changes the parameter variables' values), then each such
parameter's value in the inner frame will be the same as you'd see in the
caller frame for the referent formal_parameter.  If there are other
parameters to the synthetic subroutine that do not correspond directly to
a caller parameter, then these formal_parameter entries get no name, and
DW_AT_artificial.  (If they instead correspond exactly to other locals in
the caller frame, then these formal_parameter entries might have an
abstract_origin pointing to the DW_TAG_variable in the caller.)  Another
artificial parameter that just refers to some anonymous calculation in
the semantic scope of the caller might have no attributes except
artifical and location.  But it could always have DW_AT_description if
there is something to say, or it might one day get something akin to
declaration coordinates, with a column number where the source expression
was.  Or perhaps for that sort of thing it would have an abstract_origin
to a call_site_parameter entry in the caller, which also has artificial
(and no name) alongside whatever attributes normally indicate the genesis
of the value being passed.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44712


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