This is an archive of the discontinued LLVM Phabricator instance.

[lib/Analysis] - Mark personality functions as live.
ClosedPublic

Authored by grimar on Aug 17 2017, 8:13 AM.

Details

Summary

This is PR33245.

Case I am fixing is next:
Imagine we have 2 BC files, one defines and uses personality routine,
second has only declaration and also uses it.

Previously algorithm comuting dead symbols (llvm::computeDeadSymbols) did
not know about personality routines and leaved them dead even if function that
has routine was live.

As a result thinLTOInternalizeAndPromoteGUID() method changed binding for
such symbol to local. Later when LLD tried to link these objects it failed
because one object had undefined global symbol for routine and second
object contained local definition instead of global.

Patch set the live root flag on the corresponding FunctionSummary
for personality routines when we build the per-module summaries
during the compile step.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar created this revision.Aug 17 2017, 8:13 AM
tejohnson edited edge metadata.Aug 17 2017, 12:51 PM

Rather than modifying the index format, can you just set the live root flag on the corresponding FunctionSummary for personality routines when we build the per-module summaries during the compile step? I.e. here: http://llvm-cs.pcc.me.uk/lib/Analysis/ModuleSummaryAnalysis.cpp#278?

grimar updated this revision to Diff 111658.Aug 18 2017, 5:41 AM
  • Addressed review comment.
grimar retitled this revision from [lib/LTO] - Mark personality functions as live when them are live. to [lib/Analysis] - Mark personality functions as live..Aug 18 2017, 5:44 AM
grimar edited the summary of this revision. (Show Details)
davide edited edge metadata.Aug 18 2017, 6:33 AM

This is a step in the right direction.

lib/Analysis/ModuleSummaryAnalysis.cpp
406–408 ↗(On Diff #111658)

Needs a comment.

tejohnson added inline comments.Aug 18 2017, 6:34 AM
lib/Analysis/ModuleSummaryAnalysis.cpp
408 ↗(On Diff #111658)

Can the personality function ever have local linkage? If so, this particular interface won't work, since it will compute the GUID used to key into the index via just the name (and for locals the GUID is computed a little differently). The current setLiveRoot method was added for the case of a set of special globals accessed by name, so doesn't currently support the local case. What you can do is simply add another setLiveRoot method that takes the result of getPersonalityFn (which I see returns a Constant, so casted to a GlobalValue - would it ever not be a GV?), and invokes GV->getGUID() on the supplied GlobalValue (instead of the static getGUID invoked with on the supplied name in the current method).

If the personality fn should never be local, please add an assert here to that effect with a comment about the GUID computation in this setLiveRoot method not being correct for locals.

grimar added inline comments.Aug 18 2017, 11:42 AM
lib/Analysis/ModuleSummaryAnalysis.cpp
408 ↗(On Diff #111658)

Thanks a lot for providing these details !

I performed an experiment and found that it is possible for personality function to be local, even though it
is probably uncommon situation in general.

I took little c++ sample that throws exception and modified it slightly:
added my own personality routine personality_routine with internal binding to replace
__gxx_personality_v0 one used by default.
In my routine I just printf() some test text to check it is called.
(shared code here FWIW: https://justpaste.it/1a88c)

And it works, I see my text and personality function is local as expected:

13: 0000000000201180    16 FUNC    LOCAL  DEFAULT   14 personality_routine

I'll update the patch to fix this case at monday.

grimar added inline comments.Aug 21 2017, 4:54 AM
lib/Analysis/ModuleSummaryAnalysis.cpp
408 ↗(On Diff #111658)

After closer look it seems to me it is correct to use setLiveRoot here.

Imagine we have code:
define internal i32 @personality_routine(i32, i32, i64, i8*, i8*) {

call void @foo()
ret i32 0

}

personality_routine is local here. But computeFunctionSummary() adds all functions to index using
'f.getName()' and not 'F.getGUID()':
https://github.com/llvm-mirror/llvm/blob/master/lib/Analysis/ModuleSummaryAnalysis.cpp#L317

So it keeps it name like it is global and not local. That looks intentional logic, because
ModuleSummaruIndexBitcodeReader has code that calculates local GUID, but also stores
global GUID as OriginalNameID
(https://github.com/llvm-mirror/llvm/blob/master/lib/Bitcode/Reader/BitcodeReader.cpp#L4774)

And if I would use GV->getGUID() for doing setLiveRoot, It would not find value info for such
GUID, because computeFunctionSummary() adds it as by simple name. So code would be unable
to find VI and set live flag.

I'll update the diff with new testcase to show that local personality routines work with current version.

grimar updated this revision to Diff 111955.Aug 21 2017, 5:06 AM
  • Added comment and testcase.
tejohnson accepted this revision.Aug 21 2017, 9:02 AM

LGTM

lib/Analysis/ModuleSummaryAnalysis.cpp
408 ↗(On Diff #111658)

Sorry for the noise - you are right, it is only in the combined index that we use the GUID! Thanks for adding the test case showing that this will work for local personality routines.

This revision is now accepted and ready to land.Aug 21 2017, 9:02 AM
grimar added inline comments.Aug 21 2017, 9:05 AM
lib/Analysis/ModuleSummaryAnalysis.cpp
408 ↗(On Diff #111658)

Thanks for review ! I'll commit this tomorrow.

davide accepted this revision.Aug 21 2017, 9:17 AM

Thanks for this fix. A couple of minors, otherwise LGTM.

lib/Analysis/ModuleSummaryAnalysis.cpp
406–407 ↗(On Diff #111955)

Minor: The common terminology is DCE rather than "dead value analysis".

408 ↗(On Diff #111955)

Can you use the explicit type here? (up to you).

grimar added inline comments.Aug 21 2017, 9:33 AM
lib/Analysis/ModuleSummaryAnalysis.cpp
406–407 ↗(On Diff #111955)

Ok, will use it, thanks.
FWIW I stole "dead value analysis" from comment below initially:

// The linker doesn't know about these LLVM produced values, so we need
// to flag them as live in the index to ensure index-based dead value
// analysis treats them as live roots of the analysis.
408 ↗(On Diff #111955)

Will do.

This revision was automatically updated to reflect the committed changes.