mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 23:23:38 -04:00
[WPD] Fix incorrect devirtualization after indirect call promotion
Summary: Add a dominance check to ensure that the possible devirtualizable call is actually dominated by the type test/checked load intrinsic being analyzed. With PGO, after indirect call promotion is performed during the compile step, followed by inlining, we may have a type test in the promoted and inlined sequence that allows an indirect call in that sequence to be devirtualized. That indirect call (inserted by inlining after promotion) will share the same vtable pointer as the fallback indirect call that cannot be devirtualized. Before this patch the code was incorrectly devirtualizing the fallback indirect call. See the new test and the example described there for more details. Reviewers: pcc, vitalybuka Subscribers: mehdi_amini, Prazek, eraman, steven_wu, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D52514 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -147,7 +147,8 @@ static void addIntrinsicToSummary(
|
||||
SetVector<FunctionSummary::VFuncId> &TypeTestAssumeVCalls,
|
||||
SetVector<FunctionSummary::VFuncId> &TypeCheckedLoadVCalls,
|
||||
SetVector<FunctionSummary::ConstVCall> &TypeTestAssumeConstVCalls,
|
||||
SetVector<FunctionSummary::ConstVCall> &TypeCheckedLoadConstVCalls) {
|
||||
SetVector<FunctionSummary::ConstVCall> &TypeCheckedLoadConstVCalls,
|
||||
DominatorTree &DT) {
|
||||
switch (CI->getCalledFunction()->getIntrinsicID()) {
|
||||
case Intrinsic::type_test: {
|
||||
auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
|
||||
@@ -172,7 +173,7 @@ static void addIntrinsicToSummary(
|
||||
|
||||
SmallVector<DevirtCallSite, 4> DevirtCalls;
|
||||
SmallVector<CallInst *, 4> Assumes;
|
||||
findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI);
|
||||
findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI, DT);
|
||||
for (auto &Call : DevirtCalls)
|
||||
addVCallToSet(Call, Guid, TypeTestAssumeVCalls,
|
||||
TypeTestAssumeConstVCalls);
|
||||
@@ -192,7 +193,7 @@ static void addIntrinsicToSummary(
|
||||
SmallVector<Instruction *, 4> Preds;
|
||||
bool HasNonCallUses = false;
|
||||
findDevirtualizableCallsForTypeCheckedLoad(DevirtCalls, LoadedPtrs, Preds,
|
||||
HasNonCallUses, CI);
|
||||
HasNonCallUses, CI, DT);
|
||||
// Any non-call uses of the result of llvm.type.checked.load will
|
||||
// prevent us from optimizing away the llvm.type.test.
|
||||
if (HasNonCallUses)
|
||||
@@ -208,11 +209,10 @@ static void addIntrinsicToSummary(
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||
const Function &F, BlockFrequencyInfo *BFI,
|
||||
ProfileSummaryInfo *PSI, bool HasLocalsInUsedOrAsm,
|
||||
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||
static void computeFunctionSummary(
|
||||
ModuleSummaryIndex &Index, const Module &M, const Function &F,
|
||||
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT,
|
||||
bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||
// Summary not currently supported for anonymous functions, they should
|
||||
// have been named.
|
||||
assert(F.hasName());
|
||||
@@ -273,7 +273,7 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||
if (CI && CalledFunction->isIntrinsic()) {
|
||||
addIntrinsicToSummary(
|
||||
CI, TypeTests, TypeTestAssumeVCalls, TypeCheckedLoadVCalls,
|
||||
TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls);
|
||||
TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls, DT);
|
||||
continue;
|
||||
}
|
||||
// We should have named any anonymous globals
|
||||
@@ -488,18 +488,19 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
||||
if (F.isDeclaration())
|
||||
continue;
|
||||
|
||||
DominatorTree DT(const_cast<Function &>(F));
|
||||
BlockFrequencyInfo *BFI = nullptr;
|
||||
std::unique_ptr<BlockFrequencyInfo> BFIPtr;
|
||||
if (GetBFICallback)
|
||||
BFI = GetBFICallback(F);
|
||||
else if (F.hasProfileData()) {
|
||||
LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
|
||||
LoopInfo LI{DT};
|
||||
BranchProbabilityInfo BPI{F, LI};
|
||||
BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
|
||||
BFI = BFIPtr.get();
|
||||
}
|
||||
|
||||
computeFunctionSummary(Index, M, F, BFI, PSI,
|
||||
computeFunctionSummary(Index, M, F, BFI, PSI, DT,
|
||||
!LocalsUsed.empty() || HasLocalInlineAsmSymbol,
|
||||
CantBePromoted);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user