[WPD] Add statistics

Add statistics to count overall devirtualized targets as well as the
various types of devirtualizations applied at callsites.

Differential Revision: https://reviews.llvm.org/D123152
This commit is contained in:
Teresa Johnson 2022-04-05 11:35:16 -07:00
parent ced1250b0f
commit ced9a795fd
5 changed files with 64 additions and 10 deletions

View File

@ -57,6 +57,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AssumptionCache.h"
@ -109,6 +110,15 @@ using namespace wholeprogramdevirt;
#define DEBUG_TYPE "wholeprogramdevirt"
STATISTIC(NumDevirtTargets, "Number of whole program devirtualization targets");
STATISTIC(NumSingleImpl, "Number of single implementation devirtualizations");
STATISTIC(NumBranchFunnel, "Number of branch funnels");
STATISTIC(NumUniformRetVal, "Number of uniform return value optimizations");
STATISTIC(NumUniqueRetVal, "Number of unique return value optimizations");
STATISTIC(NumVirtConstProp1Bit,
"Number of 1 bit virtual constant propagations");
STATISTIC(NumVirtConstProp, "Number of virtual constant propagations");
static cl::opt<PassSummaryAction> ClSummaryAction(
"wholeprogramdevirt-summary-action",
cl::desc("What to do with the summary when running this pass"),
@ -1142,6 +1152,7 @@ void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
if (RemarksEnabled)
VCallSite.emitRemark("single-impl",
TheFn->stripPointerCasts()->getName(), OREGetter);
NumSingleImpl++;
auto &CB = VCallSite.CB;
assert(!CB.getCalledFunction() && "devirtualizing direct call?");
IRBuilder<> Builder(&CB);
@ -1247,7 +1258,7 @@ bool DevirtModule::trySingleImplDevirt(
return false;
// If so, update each call site to call that implementation directly.
if (RemarksEnabled)
if (RemarksEnabled || AreStatisticsEnabled())
TargetsForSlot[0].WasDevirt = true;
bool IsExported = false;
@ -1318,7 +1329,7 @@ bool DevirtIndex::trySingleImplDevirt(MutableArrayRef<ValueInfo> TargetsForSlot,
return false;
// Collect functions devirtualized at least for one call site for stats.
if (PrintSummaryDevirt)
if (PrintSummaryDevirt || AreStatisticsEnabled())
DevirtTargets.insert(TheFn);
auto &S = TheFn.getSummaryList()[0];
@ -1424,6 +1435,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
!FSAttr.getValueAsString().contains("+retpoline"))
continue;
NumBranchFunnel++;
if (RemarksEnabled)
VCallSite.emitRemark("branch-funnel",
JT->stripPointerCasts()->getName(), OREGetter);
@ -1515,6 +1527,7 @@ void DevirtModule::applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
for (auto Call : CSInfo.CallSites) {
if (!OptimizedCalls.insert(&Call.CB).second)
continue;
NumUniformRetVal++;
Call.replaceAndErase(
"uniform-ret-val", FnName, RemarksEnabled, OREGetter,
ConstantInt::get(cast<IntegerType>(Call.CB.getType()), TheRetVal));
@ -1538,7 +1551,7 @@ bool DevirtModule::tryUniformRetValOpt(
}
applyUniformRetValOpt(CSInfo, TargetsForSlot[0].Fn->getName(), TheRetVal);
if (RemarksEnabled)
if (RemarksEnabled || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
return true;
@ -1631,6 +1644,7 @@ void DevirtModule::applyUniqueRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
B.CreateICmp(IsOne ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE, Call.VTable,
B.CreateBitCast(UniqueMemberAddr, Call.VTable->getType()));
Cmp = B.CreateZExt(Cmp, Call.CB.getType());
NumUniqueRetVal++;
Call.replaceAndErase("unique-ret-val", FnName, RemarksEnabled, OREGetter,
Cmp);
}
@ -1675,7 +1689,7 @@ bool DevirtModule::tryUniqueRetValOpt(
UniqueMemberAddr);
// Update devirtualization statistics for targets.
if (RemarksEnabled)
if (RemarksEnabled || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
@ -1704,11 +1718,13 @@ void DevirtModule::applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName,
Value *Bits = B.CreateLoad(Int8Ty, Addr);
Value *BitsAndBit = B.CreateAnd(Bits, Bit);
auto IsBitSet = B.CreateICmpNE(BitsAndBit, ConstantInt::get(Int8Ty, 0));
NumVirtConstProp1Bit++;
Call.replaceAndErase("virtual-const-prop-1-bit", FnName, RemarksEnabled,
OREGetter, IsBitSet);
} else {
Value *ValAddr = B.CreateBitCast(Addr, RetType->getPointerTo());
Value *Val = B.CreateLoad(RetType, ValAddr);
NumVirtConstProp++;
Call.replaceAndErase("virtual-const-prop", FnName, RemarksEnabled,
OREGetter, Val);
}
@ -1794,7 +1810,7 @@ bool DevirtModule::tryVirtualConstProp(
setAfterReturnValues(TargetsForSlot, AllocAfter, BitWidth, OffsetByte,
OffsetBit);
if (RemarksEnabled)
if (RemarksEnabled || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
@ -2282,7 +2298,7 @@ bool DevirtModule::run() {
}
// Collect functions devirtualized at least for one call site for stats.
if (RemarksEnabled)
if (RemarksEnabled || AreStatisticsEnabled())
for (const auto &T : TargetsForSlot)
if (T.WasDevirt)
DevirtTargets[std::string(T.Fn->getName())] = T.Fn;
@ -2315,6 +2331,8 @@ bool DevirtModule::run() {
}
}
NumDevirtTargets += DevirtTargets.size();
removeRedundantTypeTests();
// Rebuild each global we touched as part of virtual constant propagation to
@ -2406,4 +2424,6 @@ void DevirtIndex::run() {
if (PrintSummaryDevirt)
for (const auto &DT : DevirtTargets)
errs() << "Devirtualized call to " << DT << "\n";
NumDevirtTargets += DevirtTargets.size();
}

View File

@ -1,4 +1,7 @@
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt %s 2>&1 | FileCheck %s
; -stats requires asserts
; REQUIRES: asserts
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -stats %s 2>&1 | FileCheck %s
target datalayout = "e-p:64:64"
target triple = "x86_64-unknown-linux-gnu"
@ -45,3 +48,6 @@ declare void @llvm.assume(i1)
!6 = !DILocation(line: 30, column: 32, scope: !5)
!7 = distinct !DISubprogram(name: "vf", linkageName: "_ZN3vt12vfEv", scope: !1, file: !1, line: 13, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: false, unit: !0)
!8 = !{i32 0, !"typeid"}
; CHECK: 1 wholeprogramdevirt - Number of whole program devirtualization targets
; CHECK: 1 wholeprogramdevirt - Number of single implementation devirtualizations

View File

@ -1,8 +1,15 @@
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s | FileCheck %s
; -stats requires asserts
; REQUIRES: asserts
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -stats %s 2>&1 | FileCheck %s
target datalayout = "e-p:64:64"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: remark: {{.*}} uniform-ret-val: devirtualized a call to vf1
; CHECK: remark: {{.*}} devirtualized vf1
; CHECK: remark: {{.*}} devirtualized vf2
@vt1 = constant [1 x i8*] [i8* bitcast (i32 (i8*)* @vf1 to i8*)], !type !0
@vt2 = constant [1 x i8*] [i8* bitcast (i32 (i8*)* @vf2 to i8*)], !type !0
@ -34,3 +41,6 @@ declare i1 @llvm.type.test(i8*, metadata)
declare void @llvm.assume(i1)
!0 = !{i32 0, !"typeid"}
; CHECK: 2 wholeprogramdevirt - Number of whole program devirtualization targets
; CHECK: 1 wholeprogramdevirt - Number of uniform return value optimizations

View File

@ -1,8 +1,16 @@
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s | FileCheck %s
; -stats requires asserts
; REQUIRES: asserts
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -stats %s 2>&1 | FileCheck %s
target datalayout = "e-p:64:64"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: remark: {{.*}} unique-ret-val: devirtualized a call to vf0
; CHECK: remark: {{.*}} unique-ret-val: devirtualized a call to vf0
; CHECK: remark: {{.*}} devirtualized vf0
; CHECK: remark: {{.*}} devirtualized vf1
@vt1 = constant [1 x i8*] [i8* bitcast (i1 (i8*)* @vf0 to i8*)], !type !0
@vt2 = constant [1 x i8*] [i8* bitcast (i1 (i8*)* @vf0 to i8*)], !type !0, !type !1
@vt3 = constant [1 x i8*] [i8* bitcast (i1 (i8*)* @vf1 to i8*)], !type !0, !type !1
@ -55,3 +63,6 @@ declare void @llvm.assume(i1)
!0 = !{i32 0, !"typeid1"}
!1 = !{i32 0, !"typeid2"}
; CHECK: 2 wholeprogramdevirt - Number of whole program devirtualization targets
; CHECK: 2 wholeprogramdevirt - Number of unique return value optimizations

View File

@ -1,4 +1,7 @@
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt %s 2>&1 | FileCheck %s
; -stats requires asserts
; REQUIRES: asserts
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -stats %s 2>&1 | FileCheck %s
; Skipping vf0i1 is identical to setting public LTO visibility. We don't devirtualize vf0i1 and all other
; virtual call targets.
; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility -pass-remarks=wholeprogramdevirt -wholeprogramdevirt-skip=vf0i1 %s 2>&1 | FileCheck %s --check-prefix=SKIP
@ -162,3 +165,7 @@ declare void @__cxa_pure_virtual()
; CHECK: [[T0]] = !{i32 0, !"typeid"}
!0 = !{i32 0, !"typeid"}
; CHECK: 6 wholeprogramdevirt - Number of whole program devirtualization targets
; CHECK: 1 wholeprogramdevirt - Number of virtual constant propagations
; CHECK: 2 wholeprogramdevirt - Number of 1 bit virtual constant propagations