-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support VFE in thinLTO #69735
base: main
Are you sure you want to change the base?
Support VFE in thinLTO #69735
Conversation
We add a run of GlobalDCEPass with ImportSummary. When ImportSummary is true, we remove virtual functions in vtables with VCallVisibility not Public. In this run, the regular GlobalDCEPass::AddVirtualFunctionDependencies will be bypassed, we will use ImportSummary to decide which virtual functions to remove. Discussion points: 1> FuncsWithNonVtableRef: this is currently in ModuleSummaryIndex, does it make sense to be part of FunctionSummary? std::set<GlobalValue::GUID> FuncsWithNonVtableRef; 2> ComputeDependencies is copied from GlobalDCE to ModuleSummaryAnalysis, for the former, ConstantDependenciesCache is a member variable 3> match from summary to Function in IR Resolution is saved in std::set<GlobalValue::GUID> VFuncsToBeRemoved Use F->getGUID() or GlobalValue::getGUID(F->getName()) when searching in VFuncsToBeRemoved TODO: 1> support hybrid Regular/ThinLTO 2> support legacy thinLTO backend (ThinLTOCodeGenerator)
0468281
to
1adce63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch! I didn't go through in too much detail yet, but have some mostly higher level comments and suggestions.
@@ -1362,6 +1362,8 @@ class ModuleSummaryIndex { | |||
// Temporary map while building StackIds list. Clear when index is completely | |||
// built via releaseTemporaryMemory. | |||
std::map<uint64_t, unsigned> StackIdToIndex; | |||
std::set<GlobalValue::GUID> FuncsWithNonVtableRef; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of sets of GUIDs, it would probably be more efficient to represent, and to access, to just add new function flags (FFlags in the FunctionSummary).
@@ -1362,6 +1362,8 @@ class ModuleSummaryIndex { | |||
// Temporary map while building StackIds list. Clear when index is completely | |||
// built via releaseTemporaryMemory. | |||
std::map<uint64_t, unsigned> StackIdToIndex; | |||
std::set<GlobalValue::GUID> FuncsWithNonVtableRef; | |||
std::set<GlobalValue::GUID> VFuncsToBeRemoved; // no need to serialize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would need to be serialized for distributed thinlto. A better thing would be to describe which of these are produced by the per-module analysis and used by the thin link, vs produced by the thin link and consumed by the ThinLTO backends. However, I suggest making these flags as noted above (but those should be documented with this information too)
std::map<ValueInfo, std::vector<VirtFuncOffset>> &VFESafeVTablesAndFns, | ||
std::map<ValueInfo, std::vector<ValueInfo>> &VFuncsAndCallers) { | ||
// Go through Function summarys for intrinsics, also funcHasNonVTableRef to | ||
// erase entries from VFESafeVTableAndFns. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why and when are entries being erased? More qualitative comments about what this algorithm is doing would be helpful.
continue; | ||
} | ||
|
||
// Go through VS->vTableFuncs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you expand on the comment - what is this code doing and why?
} | ||
llvm::errs() << "VFEThinLTO number of TIds: " << NameByGUID.size() << "\n"; | ||
|
||
// VFESafeVTablesAndFns: map from VI for vTable to VI for vfunc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment seems to be in the wrong place, can you add a description of the below data structure (and describe VFESafeVTablesAndFns somewhere too, maybe where it is defined?)
} | ||
} | ||
} | ||
llvm::errs() << "VFEThinLTO number of vTables: " << vFuncSet.size() << " " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be optimization remarks or debug messages?
} | ||
} | ||
|
||
void runVFEOnIndex(ModuleSummaryIndex &Summary, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add an overview of the algorithm as a comment above this?
@@ -775,6 +783,58 @@ static void computeVariableSummary(ModuleSummaryIndex &Index, | |||
Index.addGlobalValueSummary(V, std::move(GVarSummary)); | |||
} | |||
|
|||
static void ComputeDependencies( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: function should be lowerCamelCase
// again. | ||
if (vfuncsRemoved.count(F->getGUID())) | ||
return true; | ||
if (vfuncsRemoved.count(GlobalValue::getGUID(F->getName()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lookups are a little dangerous as I think there are cases where we might rename and it wouldn't find the right function. For internalization we tag the function with an attribute before any thinlto renaming, linkage changes, or other optimization passes. See
V->addAttribute("thinlto-internalize"); |
We add a run of GlobalDCEPass with ImportSummary. When ImportSummary is true, we remove virtual functions in vtables with VCallVisibility not Public. In this run, the regular GlobalDCEPass::AddVirtualFunctionDependencies will be bypassed, we will use ImportSummary to decide which virtual functions to remove.
Discussion points:
1> FuncsWithNonVtableRef: this is currently in ModuleSummaryIndex, does it
make sense to be part of FunctionSummary?
std::setGlobalValue::GUID FuncsWithNonVtableRef;
2> ComputeDependencies is copied from GlobalDCE to ModuleSummaryAnalysis, for the former,
ConstantDependenciesCache is a member variable
3> match from summary to Function in IR
Resolution is saved in std::setGlobalValue::GUID VFuncsToBeRemoved
Use F->getGUID() or GlobalValue::getGUID(F->getName()) when searching in VFuncsToBeRemoved
TODO:
1> support hybrid Regular/ThinLTO
2> support legacy thinLTO backend (ThinLTOCodeGenerator)