This is an archive of the discontinued LLVM Phabricator instance.

IR: Use pointers instead of GUIDs to represent edges in the module summary. NFCI.
ClosedPublic

Authored by pcc on Apr 24 2017, 9:52 PM.

Details

Summary

When profiling a no-op incremental link of Chromium I found that the functions
computeImportForFunction and computeDeadSymbols were consuming roughly 10% of
the profile. The goal of this change is to improve the performance of those
functions by changing the map lookups that they were previously doing into
pointer dereferences.

This is achieved by changing the ValueInfo data structure to be a pointer to
an element of the global value map owned by ModuleSummaryIndex, and changing
reference lists in the GlobalValueSummary to hold ValueInfos instead of GUIDs.
This means that a ValueInfo will take a client directly to the summary list
for a given GUID.

Depends on D32469

Depends on D32470

Diff Detail

Repository
rL LLVM

Event Timeline

pcc created this revision.Apr 24 2017, 9:52 PM
pcc edited the summary of this revision. (Show Details)Apr 24 2017, 10:01 PM
tejohnson edited edge metadata.May 2 2017, 2:18 PM

Nice compile time improvements! I didn't get too far, but have a few questions so far.

llvm/include/llvm/IR/ModuleSummaryIndex.h
557 ↗(On Diff #96500)

Confused by something here - if getOrInsertValueInfo ends up inserting a new ValueInfo, it's Ref pointer will be null, but the below addGlobalValueSummary will unconditionally dereference it.

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
68 ↗(On Diff #96500)

We should always be running the NameAnonGlobal pass before we build the index (when preparing for ThinLTO in the pass manager builder, event at -O0) to avoid needing such checks. Are you seeing somewhere that is not happening properly? There seem to be quite a few changes here where the hasName() guard was added.

Hmm, looks like were somewhat inconsistent about this. In several places in this file we assert that hasName(), but I see Davide added a guard to the AllRefsCanBeExternallyReferenced lambda a couple months ago. Can that occur outside of testing? I don't think so but maybe I am missing a case.

467 ↗(On Diff #96500)

Why this added check? Previously we always asserted that we had a list of size 1. Are we inserting GUIDs into the index too eagarly now?

pcc updated this revision to Diff 97540.May 2 2017, 7:23 PM
  • Address review comments
llvm/include/llvm/IR/ModuleSummaryIndex.h
557 ↗(On Diff #96500)

getOrInsertValueInfo ends up inserting a new ValueInfo, it's Ref pointer will be null,

That should never be the case. If it inserts, the Ref pointer should refer to the newly created map entry.

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
68 ↗(On Diff #96500)

This particular change was necessary to handle the test case that Davide added in r295861 because we needed to be able to compute a GUID for any global reference. I discussed the change with him on IRC, and he agreed that we should revert it, so I did that in r301991.

Regarding the other changes related to anonymous globals, they seem unnecessary at this point, so I've undone them as well.

467 ↗(On Diff #96500)

Yes, when we see a reference we need to add a GUID to the index. If the reference is undefined in the current module the summary list will be empty.

Looks pretty good, just a few more comments/questions.

llvm/include/llvm/IR/ModuleSummaryIndex.h
557 ↗(On Diff #96500)

You're right, nevermind.

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
467 ↗(On Diff #96500)

Ah ok, previously the index only held entries for defined globals, now it contains entries for all referenced globals as well. Maybe add a comment above the empty check (checking if the global is defined in this module).

llvm/lib/Bitcode/Reader/BitcodeReader.cpp
705 ↗(On Diff #97540)

Name and description need update. Is there a good reason to switch from a map to a std::vector? It makes the update code messier because you always have to check for a resize.

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
3274 ↗(On Diff #97540)

When would a declaration have !VI - would that be a declaration that isn't referenced?

llvm/lib/Transforms/IPO/FunctionImport.cpp
196 ↗(On Diff #97540)

What if VI also has an empty summary list?

436 ↗(On Diff #97540)

Can this loop be merged with the earlier one that builds the initial LiveSymbols set?

472 ↗(On Diff #97540)

Should the OriginalName in the AliasSummary also be saved as a ValueInfo instead of GUID (not necessary in this patch, but as a follow on)?

pcc updated this revision to Diff 97761.May 3 2017, 6:40 PM
pcc marked 2 inline comments as done.
  • Address review comments
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
705 ↗(On Diff #97540)

I saw this as a potential perf improvement, but admittedly I hadn't profiled it in isolation.

I've reverted it for now and if it comes up again we can reconsider.

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
3274 ↗(On Diff #97540)

Yes, I think that's the only case where that can happen.

llvm/lib/Transforms/IPO/FunctionImport.cpp
196 ↗(On Diff #97540)

We will fall through and enter selectCallee which will return nullptr, so we will not import anything for this call.

472 ↗(On Diff #97540)

Maybe. If I get a chance I want to rethink how we represent aliases in the summary. I think it should be possible to represent them using either a FunctionSummary or GlobalValueSummary built using the aliasee.

This revision is now accepted and ready to land.May 3 2017, 8:27 PM
This revision was automatically updated to reflect the committed changes.
mehdi_amini added inline comments.Jul 30 2017, 2:07 PM
llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
54

I don't understand why/where this is needed/used, the comment does not seem enough here.
It seems to me that this make the in-memory CombinedIndex unnecessary larger.

73

The doc here does not seem complete/accurate

81

There is no doc about when this is valid.

I feel the invariant of the whole system are quite hard to grasp.