[debug-early] C++ clones and limbo DIEs
Aldy Hernandez
aldyh@redhat.com
Mon Feb 16 20:46:00 GMT 2015
On 02/12/2015 11:27 AM, Jason Merrill wrote:
> On 02/12/2015 01:04 PM, Aldy Hernandez wrote:
>> On 02/10/2015 02:52 AM, Richard Biener wrote:
>>> On Fri, Feb 6, 2015 at 5:42 PM, Aldy Hernandez <aldyh@redhat.com> wrote:
>>
>>> Of course I wonder why you need to separate handling of functions and
>>> variables
>>
>> The variables need to be handled earlier, else the call to
>> analyze_functions() will remove some optimized global variables away,
>> and we'll never see them. I believe that Jason said they were needed
>> up-thread.
>>
>>> variables. What breaks if you emit debug info for functions before
>>> the first analyze_functions () call?
>> >
>> > I also wonder why you restrict it to functions with a GIMPLE body.
>>
>> The functions, on the other hand, need to be handled after the second
>> call to analyze_function (and with a GIMPLE body) else we get far more
>> function DIEs than mainline currently does, especially wrt C++ clones.
>> Otherwise, we get DIEs for base constructors, complete constructors, and
>> what-have-yous. Jason wanted less DIEs, more attune to what mainline is
>> currently doing.
>
> I think it makes sense to generate DIEs for everything defined in the TU
> if we don't have -feliminate-unused-debug-symbols. But since clones are
> artificial, emit them only if they're used.
Ok, just so we're on the same page. I'm thinking that for
-fNO-eliminate-unused-debug-symbols, we can iterate through
FOR_EACH_DEFINED_FUNCTION before unreachable functions have been
removed. There we can output all non-clones.
Then for the -feliminate-unused-debug-symbols case, we can output
reachable functions after the unreachable ones have been removed. Here
we can also dump the clones we ignored for
-fNO-eliminate-unused-debug-symbols above, since we only want to emit
them if they're reachable (regardless of -feliminate-unused-debug-symbols).
In either case, we always ignore those without a gimple body, otherwise
we end up generating DIEs for the _ZN1AC2Ei constructor in the attached
function unnecessarily. See how the bits end up in the attached testcase:
(Oh, and we determine clonehood with DECL_ABSTRACT_ORIGIN)
Before any calls to analyze_functions()
---------------------------------------
Function: 'int main()' (Mangled: main) gimple_body=1 DECL_ABSTRACT_ORIGIN=0
Function: 'A::A(int)' (Mangled: _ZN1AC1Ei) gimple_body=0
DECL_ABSTRACT_ORIGIN=1
Function: 'A::A(int)' (Mangled: _ZN1AC2Ei) gimple_body=1
DECL_ABSTRACT_ORIGIN=1
Function: 'void foo(int)' (Mangled: _Z3fooi) gimple_body=1
DECL_ABSTRACT_ORIGIN=0
Function: 'int bar()' (Mangled: _Z3barv) gimple_body=1
DECL_ABSTRACT_ORIGIN=0
Function: 'void unreachable_func()' (Mangled: _ZL16unreachable_funcv)
gimple_body=1 DECL_ABSTRACT_ORIGIN=0
After reachability analysis
(after first call to analyze_functions())
-----------------------------------------
Function: 'int main()' (Mangled: main) gimple_body=1 DECL_ABSTRACT_ORIGIN=0
Function: 'A::A(int)' (Mangled: _ZN1AC1Ei) gimple_body=0
DECL_ABSTRACT_ORIGIN=1
Function: 'A::A(int)' (Mangled: _ZN1AC2Ei) gimple_body=1
DECL_ABSTRACT_ORIGIN=1
Function: 'void foo(int)' (Mangled: _Z3fooi) gimple_body=1
DECL_ABSTRACT_ORIGIN=0
Function: 'int bar()' (Mangled: _Z3barv) gimple_body=1
DECL_ABSTRACT_ORIGIN=0
Is this what you had in mind? I can provide a patch to make things clearer.
Aldy
-------------- next part --------------
extern "C" void abort ();
struct A { A (int); int a; };
int i;
static void unreachable_func()
{
i = 5;
}
__attribute__((noinline, noclone)) int
bar (void)
{
return 40;
}
__attribute__((noinline, noclone)) void
foo (int x)
{
__asm volatile ("" : : "r" (x) : "memory");
}
A::A (int x)
{
static int p = bar ();
foo (p);
a = ++p;
}
int
main ()
{
A a (42);
if (a.a != 41)
abort ();
}
More information about the Gcc-patches
mailing list