public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug debug/44712]  New: Debug info for partially inlined functions
@ 2010-06-29 12:58 jakub at gcc dot gnu dot org
  2010-06-29 13:25 ` [Bug debug/44712] " hubicka at ucw dot cz
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: jakub at gcc dot gnu dot org @ 2010-06-29 12:58 UTC (permalink / raw)
  To: gcc-bugs

/* { dg-options "-g -O2" } */
extern void abort (void);
extern void exit (int);
extern int printf (const char *, ...);

static int
foo (int x)
{
  typedef int T;
  T z = 2 * x;
  if (x <= 0)
    {
      printf ("foo\n");
      printf ("foo\n");
      printf ("foo\n");
      exit (0);
    }
  return 6;
}

__attribute__((noinline))
int bar (int x)
{
  return foo (x) + foo (6) + foo (x);
}

int
main (void)
{
  int l;
  asm volatile ("" : "=r" (l) : "0" (5));
  if (bar (l) != 18)
    abort ();
  bar (l - 10);
  abort ();
}

Debugging experience on this testcase isn't ideal, work will be needed both on
the gcc side and gdb side.  Roland has some ideas what should be done,
certainly DW_AT_artificial should be set on the foo.part* function, and perhaps
it should have some DW_TAG_lexical_block from the abstract DW_TAG_subprogram as
DW_AT_abstract_origin instead of the whole DW_TAG_subroutine (or perhaps some
artificial DW_TAG_lexical_block created just for that purpose?).
I'll let Roland write the details here himself.


-- 
           Summary: Debug info for partially inlined functions
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Keywords: wrong-debug
          Severity: normal
          Priority: P3
         Component: debug
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jakub at gcc dot gnu dot org


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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Bug debug/44712]  New: Debug info for partially inlined functions
  2010-06-29 12:58 [Bug debug/44712] New: Debug info for partially inlined functions jakub at gcc dot gnu dot org
  2010-06-29 13:25 ` [Bug debug/44712] " hubicka at ucw dot cz
@ 2010-06-29 13:25 ` Jan Hubicka
  2010-07-01 18:56 ` [Bug debug/44712] " roland at redhat dot com
  2 siblings, 0 replies; 5+ messages in thread
From: Jan Hubicka @ 2010-06-29 13:25 UTC (permalink / raw)
  To: jakub at gcc dot gnu dot org; +Cc: gcc-bugs

Thanks for opening PR on this.  One thing I was planning to look into soon is to make
progress at least reversible - i.e. find way to declare the fact that function is part
of another in GCC and make inliner to produce the problem block tree after inlining
them back together.
I wonder what the representation should be?

Honza


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug debug/44712] Debug info for partially inlined functions
  2010-06-29 12:58 [Bug debug/44712] New: Debug info for partially inlined functions jakub at gcc dot gnu dot org
@ 2010-06-29 13:25 ` hubicka at ucw dot cz
  2010-06-29 13:25 ` [Bug debug/44712] New: " Jan Hubicka
  2010-07-01 18:56 ` [Bug debug/44712] " roland at redhat dot com
  2 siblings, 0 replies; 5+ messages in thread
From: hubicka at ucw dot cz @ 2010-06-29 13:25 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from hubicka at ucw dot cz  2010-06-29 13:25 -------
Subject: Re:   New: Debug info for partially inlined
        functions

Thanks for opening PR on this.  One thing I was planning to look into soon is
to make
progress at least reversible - i.e. find way to declare the fact that function
is part
of another in GCC and make inliner to produce the problem block tree after
inlining
them back together.
I wonder what the representation should be?

Honza


-- 


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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug debug/44712] Debug info for partially inlined functions
  2010-06-29 12:58 [Bug debug/44712] New: Debug info for partially inlined functions jakub at gcc dot gnu dot org
  2010-06-29 13:25 ` [Bug debug/44712] " hubicka at ucw dot cz
  2010-06-29 13:25 ` [Bug debug/44712] New: " Jan Hubicka
@ 2010-07-01 18:56 ` roland at redhat dot com
  2 siblings, 0 replies; 5+ messages in thread
From: roland at redhat dot com @ 2010-07-01 18:56 UTC (permalink / raw)
  To: gcc-bugs



------- 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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug debug/44712] Debug info for partially inlined functions
       [not found] <bug-44712-4@http.gcc.gnu.org/bugzilla/>
@ 2024-03-16 19:15 ` pinskia at gcc dot gnu.org
  0 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-03-16 19:15 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-03-16
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-03-16 19:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-29 12:58 [Bug debug/44712] New: Debug info for partially inlined functions jakub at gcc dot gnu dot org
2010-06-29 13:25 ` [Bug debug/44712] " hubicka at ucw dot cz
2010-06-29 13:25 ` [Bug debug/44712] New: " Jan Hubicka
2010-07-01 18:56 ` [Bug debug/44712] " roland at redhat dot com
     [not found] <bug-44712-4@http.gcc.gnu.org/bugzilla/>
2024-03-16 19:15 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).