-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[TypeProf][PGO]Support skipping vtable comparisons for a class and its derived ones #110575
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
Changes from 2 commits
bc43354
2695641
f14c6d5
255edce
28e2363
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,6 +132,14 @@ static cl::opt<int> ICPMaxNumVTableLastCandidate( | |
| "icp-max-num-vtable-last-candidate", cl::init(1), cl::Hidden, | ||
| cl::desc("The maximum number of vtable for the last candidate.")); | ||
|
|
||
| static cl::opt<DenseSet<StringRef>> ICPIgnoredBaseTypes( | ||
|
||
| "icp-ignored-base-types", cl::Hidden, cl::init(DenseSet<StringRef>()), | ||
| cl::desc("A comma-separated list of mangled vtable names. Classes " | ||
| "specified by the vtables and their derived ones will not be " | ||
| "vtable-ICP'ed. Useful when the profiled types and actual types " | ||
| "in the optimized binary could be different due to profiling " | ||
| "limitations.")); | ||
|
|
||
| namespace { | ||
|
|
||
| // The key is a vtable global variable, and the value is a map. | ||
|
|
@@ -851,8 +859,27 @@ bool IndirectCallPromoter::isProfitableToCompareVTables( | |
| LLVM_DEBUG(dbgs() << "\n"); | ||
|
|
||
| uint64_t CandidateVTableCount = 0; | ||
| for (auto &[GUID, Count] : VTableGUIDAndCounts) | ||
| SmallVector<MDNode *, 2> Types; | ||
|
||
| for (auto &[GUID, Count] : VTableGUIDAndCounts) { | ||
| CandidateVTableCount += Count; | ||
| auto *VTableVar = Symtab->getGlobalVariable(GUID); | ||
|
||
|
|
||
| assert(VTableVar && | ||
| "VTableVar must exist for GUID in VTableGUIDAndCounts"); | ||
|
|
||
| Types.clear(); | ||
| VTableVar->getMetadata(LLVMContext::MD_type, Types); | ||
|
|
||
| const DenseSet<StringRef> &VTableSet = ICPIgnoredBaseTypes.getValue(); | ||
| for (auto *Type : Types) | ||
| if (auto *TypeId = dyn_cast<MDString>(Type->getOperand(1).get())) | ||
| if (VTableSet.contains(TypeId->getString().str())) { | ||
| LLVM_DEBUG(dbgs() | ||
| << " vtable profiles are known to be " | ||
|
||
| "unrepresentative. Bail out vtable comparison."); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| if (CandidateVTableCount < Candidate.Count * ICPVTablePercentageThreshold) { | ||
| LLVM_DEBUG( | ||
|
|
||
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.
Are you certain that the contents of
StringRef Argoutlives the DenseSet returned? All the others above return the contents by value.I would prefer a cl::optstd::string which is parsed and validated in the ICP pass. Is there an advantage to your proposed approach and are there any precedents in the codebase? IMO this option feels overly restrictive when rejecting duplicated strings from the user.
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.
I took another look (at a couple of callsites of
cl::ParseCommandLineOptions), and couldn't easily figure out if referenced strings remain alive for all passes. FrontendOptions.h and cc1as_main.cpp are two places which holdsvector<std::string>for LLVM args. But IMO ifcl::ParseCommandLineOptions(as a frequently-called function in LLVM and downstream repositories) doesn't require caller keep the argument contents alive, it's not a good idea forcl::optto even use StringRef (users will have a hard time).I updated to
cl::list<std::string>to save a call tollvm::SplitStrings. And one interesting finding is that bothcl::optandcl::listsupports internal or external storage [1], with internal storage as the default.[1] https://llvm.org/docs/CommandLine.html#the-cl-list-class