This is an archive of the discontinued LLVM Phabricator instance.

[DWARF] Force a linkage_name on an inlined subprogram's abstract origin
ClosedPublic

Authored by probinson on Apr 1 2016, 11:44 AM.

Details

Summary

When we suppress linkage names, for a non-inlined subprogram the name
can still be found in the object-file symbol table, because we have
the code address of the subprogram. This is not the case for an
inlined subprogram, so we still want to emit the linkage name in the
DWARF. Put this on the abstract-origin DIE because it's common to all
inlined instances.

Diff Detail

Event Timeline

probinson updated this revision to Diff 52403.Apr 1 2016, 11:44 AM
probinson retitled this revision from to [DWARF] Force a linkage_name on an inlined subprogram's abstract origin.
probinson updated this object.
probinson added reviewers: echristo, dblaikie, aprantl.
probinson added a subscriber: llvm-commits.
dblaikie edited edge metadata.Apr 1 2016, 2:38 PM

Got data on how much this grows the size of output (optimized clang selfhost, perhaps?)

I've had a few conversations about where linkage names should and should not appear, and have yet to understand/hear a coherent position about what consumers want to use them for. Perhaps you could outline your use case, so we can at least think about how that applies across LLVM?

test/DebugInfo/Generic/linkage-name-abstract.ll
11–17

If you're demonstrating inlining, I find this to be the simplest option:

void f1();
__attribute__((always_inline)) void f2() {
  f1();
}
void f3() {
  f2();
}

That way there's no confusion about whether the return values are relevant, if the operations (like addition) are relevant, if an optimization could constant propagate/fold away the value, etc. The call to f1 is unoptimizable, can't be coalesced with anything, etc.

Also meant to ask whether there was a way to avoid passing in a constant
from the two callers and then conditionalizing later. It'd be nice to just
bubble up the behavior and do it in the place that needs it and not do it
in the place that doesn't.

Not sure if that's possible/practical (I see it overlaps with the 'minimal'
flag, which makes it trickier) - but I'll give it some more thought.

The abstract instances are really no different from other subprogram declarations, which is why most of how they get handled is no different from other subprogram declarations. I'm not keen on passing the flag down through several layers either, but I don't see else to figure out we really want the linkage name after all, at the point where we actually add it. When I conditionalized linkage-name in the first place, Eric wanted the caller not to have to think too hard, and let addLinkageName itself do all the deciding.

Use case has to do with sample-based PGO, we want to be able to attribute data for an inlined instance to that function and not its caller. The collected data uses the mangled name as the key, or something; I'm not directly involved in that work.

I'll look at redoing the test case using your model, thanks for the tip!

No size data yet, a self-host clang with extra options is befuddling me.

Re not passing constants down: It looks like applySubprogramDefinitionAttributes could figure out if the SP is abstract with something like this?

bool Abstract = DU->getAbstractSPDies().lookup(SP);

I can't do that in addLinkageName because it has only the DIE, not the DISubprogram. But then I wouldn't have to fuss with all those other APIs.

probinson updated this revision to Diff 52575.Apr 4 2016, 10:11 AM
probinson edited edge metadata.

Less invasive implementation. Revise test per suggestion.

Built Clang with Clang 3 times: linkage names Enabled, linkage names Disabled but with the patch, linkage names Disabled without the patch (aka: all names, some names, no names).
'all names' and 'no names' are the options we have today; this patch replaces 'no names' with 'some names.'

Total ELF size of 'all names' is 11.2% larger than 'no names'; sum of all .debug_* sections is 11.9% larger.
Total ELF size of 'some names' is 0.6% larger than 'no names'; sum of all .debug_* sections is 0.6% larger.
The bulk of the difference obviously in .debug_str, with some in .debug_info and .debug_abbrev.

(Debug info turns out to be about 95% of the total ELF size, without LTO or .debug_types or any other deduplication; hence the ELF and .debug_* percentages are naturally very similar.)

A size cost of <1% seems pretty reasonable here.

Oh, and if you're interested in mangled names, you might be interested in
some old patches I came across yesterday related to them. I haven't double
checked the behavior, but according to my patch descriptions it sounds like
it might be describing some holes/inconsistencies in our frontend handling
of mangled names that may impact your scenarios.

Built Clang with Clang 3 times: linkage names Enabled, linkage names Disabled but with the patch, linkage names Disabled without the patch (aka: all names, some names, no names).
'all names' and 'no names' are the options we have today; this patch replaces 'no names' with 'some names.'

dblaikie wrote (in email):

Which option(s) are you referring to here ^ (do we have a flag or somesuch that
allows enabling/disabling linkage names?)

Yes, DwarfDebug.cpp has -dwarf-linkage-names={Enable,Disable} which is disabled by default when tuning for SCE, otherwise enabled by default. This is what DD->useLinkageNames() is referring to, in addLinkageName(), giving us the all/none options.
My patch obviously substitutes 'some' for 'none'.

Seems this makes the flag (dwarf-linkage-names=*) a bit erroneous, no?
Would it be better to trigger this directly off the debugger tuning flag
now & drop the specific named flag?

Seems this makes the flag (dwarf-linkage-names=*) a bit erroneous, no?

That's true, it doesn't completely disable linkage names any more. Make that a 3-way flag? -dwarf-linkage-names={All,Abstract,None}. The more complicated decision-making can be buried inside useLinkageNames() which would now take a bool saying whether the DIE is abstract.

Would it be better to trigger this directly off the debugger tuning flag
now & drop the specific named flag?

No. The original discussion over "tuning" specifically concluded that tuning should expand to defaults for feature-specific flags, and never be a controlling condition on its own. It should always be possible to override a tuning with specific flags.

probinson updated this revision to Diff 52854.Apr 6 2016, 2:43 PM

Make linkage-name policy a proper 3-way choice.

Would it be better to trigger this directly off the debugger tuning flag
now & drop the specific named flag?

No. The original discussion over "tuning" specifically concluded that tuning should expand to defaults for feature-specific flags, and never be a controlling condition on its own. It should always be possible to override a tuning with specific flags.

This policy is documented in include/llvm/Target/TargetOptions.h, see the definition of enum DebuggerKind.

probinson updated this revision to Diff 52967.Apr 7 2016, 4:00 PM

Remove the "none" option per request from David Blaikie. The choices are "All" or "Abstract" (subprograms).

Re not passing constants down: It looks like applySubprogramDefinitionAttributes could figure out if the SP is abstract with something like this?

What I was thinking of was more raising the addition of the linkage name up into the callers - so that we don't turn a static property at the call site into a dynamic property of the caller if we can avoid it without complicating things.

But I suppose pushing up/duplicating the logic for getting the decl linkage name, testing !Minimal, etc, isn't really any good...

I'm fine with either way, then.

Also - depending on how far you want to go, you could probably skip the mangled name for abstract subprograms that have a concrete definition (it'd mean having to search through the DWARF to find the concrete subprogram, then looking at its high/low pc to find the symbol in the symbol table with the mangled name there)

lib/CodeGen/AsmPrinter/DwarfDebug.cpp
108–123

Why did this need to become a 3 state when it was a boolean before? (when it's still only about 2 states, I think - before it was all-or-nothing, and now it's all-or-abstract)

Also - depending on how far you want to go, you could probably skip the mangled name for abstract subprograms that have a concrete definition (it'd mean having to search through the DWARF to find the concrete subprogram, then looking at its high/low pc to find the symbol in the symbol table with the mangled name there)

If the concrete out-of-line instance gets LTO'd away, that won't work.

lib/CodeGen/AsmPrinter/DwarfDebug.cpp
108–123

This is about the command-line option, which used to be the 3-state DefaultOnOff and is now this new enum because the choices aren't really On and Off anymore. The DwarfDebug flag is still a bool.

Also - depending on how far you want to go, you could probably skip the mangled name for abstract subprograms that have a concrete definition (it'd mean having to search through the DWARF to find the concrete subprogram, then looking at its high/low pc to find the symbol in the symbol table with the mangled name there)

If the concrete out-of-line instance gets LTO'd away, that won't work.

Sorry, senior moment. If it gets dead-stripped by the linker, that won't work.

dblaikie accepted this revision.Apr 13 2016, 1:21 PM
dblaikie edited edge metadata.
This revision is now accepted and ready to land.Apr 13 2016, 1:21 PM
dblaikie added inline comments.Apr 13 2016, 1:22 PM
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
668–669

Actually, one thing - could you pull the useLinkageName/abstract part out into the caller, perhaps?

What I'm thinking is that if it's sufficiently re-structured, the AbstractSPDies lookup shouldn't be necessary except when this option is enabled.

probinson updated this revision to Diff 53619.Apr 13 2016, 2:21 PM
probinson edited edge metadata.

Try to do fewer lookups.

Try to do fewer lookups.

This means every call to addLinkageName has to be guarded. When I did the option originally (as an on/off), Eric was not a fan of guarding the calls, which is why it ended up inside the method. But now the condition is different in the two places that call the method, so maybe that's okay?

dblaikie added inline comments.Apr 13 2016, 3:03 PM
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
1175–1176

Just roll these conditions into the previous 'if', perhaps?

probinson updated this revision to Diff 53639.Apr 13 2016, 4:31 PM
probinson marked an inline comment as done.

Combine two 'if's into one.

Ping. @dblaikie, you had accepted this but then had further comments so I'm not 100% sure it still applies.

Sorry for any ambiguity - like I said in my last message, whichever way you
want to go with it out of the two choices (in both design issues mentioned

  • in terms of number of lookups and whether to pass a flag around or do a

lookup) is fine. Commit whichever you're most comfortable with.

This revision was automatically updated to reflect the committed changes.