mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
Resubmit r297897: [PGO] Value profile for size of memory intrinsic calls
R297897 inadvertently enabled annotation for memop profiling. This new patch fixed it. llvm-svn: 297996
This commit is contained in:
parent
95bcf12f18
commit
cd36e86346
@ -196,6 +196,10 @@ OPTIONS
|
||||
|
||||
Specify that the input profile is a sample-based profile.
|
||||
|
||||
.. option:: -memop-sizes
|
||||
|
||||
Show the profiled sizes of the memory intrinsic calls for shown functions.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
|
@ -94,6 +94,11 @@ inline StringRef getInstrProfValueProfFuncName() {
|
||||
return INSTR_PROF_VALUE_PROF_FUNC_STR;
|
||||
}
|
||||
|
||||
/// Return the name profile runtime entry point to do value range profiling.
|
||||
inline StringRef getInstrProfValueRangeProfFuncName() {
|
||||
return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR;
|
||||
}
|
||||
|
||||
/// Return the name of the section containing function coverage mapping
|
||||
/// data.
|
||||
inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
|
||||
@ -689,12 +694,15 @@ struct InstrProfRecord {
|
||||
|
||||
private:
|
||||
std::vector<InstrProfValueSiteRecord> IndirectCallSites;
|
||||
std::vector<InstrProfValueSiteRecord> MemOPSizes;
|
||||
const std::vector<InstrProfValueSiteRecord> &
|
||||
|
||||
getValueSitesForKind(uint32_t ValueKind) const {
|
||||
switch (ValueKind) {
|
||||
case IPVK_IndirectCallTarget:
|
||||
return IndirectCallSites;
|
||||
case IPVK_MemOPSize:
|
||||
return MemOPSizes;
|
||||
default:
|
||||
llvm_unreachable("Unknown value kind!");
|
||||
}
|
||||
|
@ -153,7 +153,17 @@ INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)
|
||||
VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \
|
||||
INSTR_PROF_COMMA
|
||||
VALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA
|
||||
#ifndef VALUE_RANGE_PROF
|
||||
VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
|
||||
#else /* VALUE_RANGE_PROF */
|
||||
VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) \
|
||||
INSTR_PROF_COMMA
|
||||
VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeStart, Type::getInt64Ty(Ctx)) \
|
||||
INSTR_PROF_COMMA
|
||||
VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeLast, Type::getInt64Ty(Ctx)) \
|
||||
INSTR_PROF_COMMA
|
||||
VALUE_PROF_FUNC_PARAM(uint64_t, LargeValue, Type::getInt64Ty(Ctx))
|
||||
#endif /*VALUE_RANGE_PROF */
|
||||
#undef VALUE_PROF_FUNC_PARAM
|
||||
#undef INSTR_PROF_COMMA
|
||||
/* VALUE_PROF_FUNC_PARAM end */
|
||||
@ -174,13 +184,15 @@ VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
|
||||
* name hash and the function address.
|
||||
*/
|
||||
VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0)
|
||||
/* For memory intrinsic functions size profiling. */
|
||||
VALUE_PROF_KIND(IPVK_MemOPSize, 1)
|
||||
/* These two kinds must be the last to be
|
||||
* declared. This is to make sure the string
|
||||
* array created with the template can be
|
||||
* indexed with the kind value.
|
||||
*/
|
||||
VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget)
|
||||
VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget)
|
||||
VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize)
|
||||
|
||||
#undef VALUE_PROF_KIND
|
||||
/* VALUE_PROF_KIND end */
|
||||
@ -649,6 +661,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
|
||||
#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target
|
||||
#define INSTR_PROF_VALUE_PROF_FUNC_STR \
|
||||
INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)
|
||||
#define INSTR_PROF_VALUE_RANGE_PROF_FUNC __llvm_profile_instrument_range
|
||||
#define INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR \
|
||||
INSTR_PROF_QUOTE(INSTR_PROF_VALUE_RANGE_PROF_FUNC)
|
||||
|
||||
/* InstrProfile per-function control data alignment. */
|
||||
#define INSTR_PROF_DATA_ALIGNMENT 8
|
||||
|
@ -59,6 +59,14 @@ private:
|
||||
GlobalVariable *NamesVar;
|
||||
size_t NamesSize;
|
||||
|
||||
// The start value of precise value profile range for memory intrinsic sizes.
|
||||
const int64_t DefaultMemOPSizeRangeStart = 0;
|
||||
int64_t MemOPSizeRangeStart;
|
||||
// The end value of precise value profile range for memory intrinsic sizes.
|
||||
const int64_t DefaultMemOPSizeRangeLast = 8;
|
||||
int64_t MemOPSizeRangeLast;
|
||||
int64_t MemOPSizeLargeVal;
|
||||
|
||||
bool isMachO() const;
|
||||
|
||||
/// Get the section name for the counter variables.
|
||||
@ -109,6 +117,9 @@ private:
|
||||
/// Create a static initializer for our data, on platforms that need it,
|
||||
/// and for any profile output file that was specified.
|
||||
void emitInitialization();
|
||||
|
||||
/// Helper funtion that parsing the MemOPSize value profile options
|
||||
void getMemOPSizeOptions();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -77,6 +77,17 @@ cl::opt<double> NumCountersPerValueSite(
|
||||
// is usually smaller than 2.
|
||||
cl::init(1.0));
|
||||
|
||||
cl::opt<std::string> MemOPSizeRange(
|
||||
"memop-size-range",
|
||||
cl::desc("Set the range of size in memory intrinsic calls to be profiled "
|
||||
"precisely, in a format of <start_val>:<end_val>"),
|
||||
cl::init(""));
|
||||
cl::opt<unsigned> MemOPSizeLarge(
|
||||
"memop-size-large",
|
||||
cl::desc("Set large value thresthold in memory intrinsic size profiling. "
|
||||
"Value of 0 disables the large value profiling."),
|
||||
cl::init(8192));
|
||||
|
||||
class InstrProfilingLegacyPass : public ModulePass {
|
||||
InstrProfiling InstrProf;
|
||||
|
||||
@ -165,6 +176,7 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
|
||||
NamesSize = 0;
|
||||
ProfileDataMap.clear();
|
||||
UsedVars.clear();
|
||||
getMemOPSizeOptions();
|
||||
|
||||
// We did not know how many value sites there would be inside
|
||||
// the instrumented function. This is counting the number of instrumented
|
||||
@ -217,17 +229,34 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
|
||||
}
|
||||
|
||||
static Constant *getOrInsertValueProfilingCall(Module &M,
|
||||
const TargetLibraryInfo &TLI) {
|
||||
const TargetLibraryInfo &TLI,
|
||||
bool IsRange = false) {
|
||||
LLVMContext &Ctx = M.getContext();
|
||||
auto *ReturnTy = Type::getVoidTy(M.getContext());
|
||||
Type *ParamTypes[] = {
|
||||
|
||||
Constant *Res;
|
||||
if (!IsRange) {
|
||||
Type *ParamTypes[] = {
|
||||
#define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
};
|
||||
auto *ValueProfilingCallTy =
|
||||
FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
|
||||
Constant *Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
|
||||
ValueProfilingCallTy);
|
||||
};
|
||||
auto *ValueProfilingCallTy =
|
||||
FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
|
||||
Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
|
||||
ValueProfilingCallTy);
|
||||
} else {
|
||||
Type *RangeParamTypes[] = {
|
||||
#define VALUE_RANGE_PROF 1
|
||||
#define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
|
||||
#include "llvm/ProfileData/InstrProfData.inc"
|
||||
#undef VALUE_RANGE_PROF
|
||||
};
|
||||
auto *ValueRangeProfilingCallTy =
|
||||
FunctionType::get(ReturnTy, makeArrayRef(RangeParamTypes), false);
|
||||
Res = M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(),
|
||||
ValueRangeProfilingCallTy);
|
||||
}
|
||||
|
||||
if (Function *FunRes = dyn_cast<Function>(Res)) {
|
||||
if (auto AK = TLI.getExtAttrForI32Param(false))
|
||||
FunRes->addAttribute(3, AK);
|
||||
@ -261,11 +290,24 @@ void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
|
||||
Index += It->second.NumValueSites[Kind];
|
||||
|
||||
IRBuilder<> Builder(Ind);
|
||||
Value *Args[3] = {Ind->getTargetValue(),
|
||||
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
|
||||
Builder.getInt32(Index)};
|
||||
CallInst *Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI),
|
||||
Args);
|
||||
bool IsRange = (Ind->getValueKind()->getZExtValue() ==
|
||||
llvm::InstrProfValueKind::IPVK_MemOPSize);
|
||||
CallInst *Call = nullptr;
|
||||
if (!IsRange) {
|
||||
Value *Args[3] = {Ind->getTargetValue(),
|
||||
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
|
||||
Builder.getInt32(Index)};
|
||||
Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI), Args);
|
||||
} else {
|
||||
Value *Args[6] = {Ind->getTargetValue(),
|
||||
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
|
||||
Builder.getInt32(Index),
|
||||
Builder.getInt64(MemOPSizeRangeStart),
|
||||
Builder.getInt64(MemOPSizeRangeLast),
|
||||
Builder.getInt64(MemOPSizeLargeVal)};
|
||||
Call =
|
||||
Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI, true), Args);
|
||||
}
|
||||
if (auto AK = TLI->getExtAttrForI32Param(false))
|
||||
Call->addAttribute(3, AK);
|
||||
Ind->replaceAllUsesWith(Call);
|
||||
@ -658,3 +700,24 @@ void InstrProfiling::emitInitialization() {
|
||||
|
||||
appendToGlobalCtors(*M, F, 0);
|
||||
}
|
||||
|
||||
void InstrProfiling::getMemOPSizeOptions() {
|
||||
// Parse the value profile options.
|
||||
MemOPSizeRangeStart = DefaultMemOPSizeRangeStart;
|
||||
MemOPSizeRangeLast = DefaultMemOPSizeRangeLast;
|
||||
if (!MemOPSizeRange.empty()) {
|
||||
auto Pos = MemOPSizeRange.find(":");
|
||||
if (Pos != std::string::npos) {
|
||||
if (Pos > 0)
|
||||
MemOPSizeRangeStart = atoi(MemOPSizeRange.substr(0, Pos).c_str());
|
||||
if (Pos < MemOPSizeRange.size() - 1)
|
||||
MemOPSizeRangeLast = atoi(MemOPSizeRange.substr(Pos + 1).c_str());
|
||||
} else
|
||||
MemOPSizeRangeLast = atoi(MemOPSizeRange.c_str());
|
||||
}
|
||||
assert(MemOPSizeRangeLast >= MemOPSizeRangeStart);
|
||||
|
||||
MemOPSizeLargeVal = MemOPSizeLarge;
|
||||
if (MemOPSizeLargeVal == 0)
|
||||
MemOPSizeLargeVal = INT64_MIN;
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ using namespace llvm;
|
||||
|
||||
STATISTIC(NumOfPGOInstrument, "Number of edges instrumented.");
|
||||
STATISTIC(NumOfPGOSelectInsts, "Number of select instruction instrumented.");
|
||||
STATISTIC(NumOfPGOMemIntrinsics, "Number of mem intrinsics instrumented.");
|
||||
STATISTIC(NumOfPGOEdge, "Number of edges.");
|
||||
STATISTIC(NumOfPGOBB, "Number of basic-blocks.");
|
||||
STATISTIC(NumOfPGOSplit, "Number of critical edge splits.");
|
||||
@ -168,6 +169,10 @@ static cl::opt<bool>
|
||||
"display to only one function, use "
|
||||
"filtering option -view-bfi-func-name."));
|
||||
|
||||
// Command line option to enable/disable memop intrinsic calls..
|
||||
static cl::opt<bool> PGOInstrMemOP("pgo-instr-memop", cl::init(true),
|
||||
cl::Hidden);
|
||||
|
||||
// Command line option to turn on CFG dot dump after profile annotation.
|
||||
// Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
|
||||
extern cl::opt<bool> PGOViewCounts;
|
||||
@ -235,6 +240,40 @@ struct SelectInstVisitor : public InstVisitor<SelectInstVisitor> {
|
||||
unsigned getNumOfSelectInsts() const { return NSIs; }
|
||||
};
|
||||
|
||||
/// Instruction Visitor class to visit memory intrinsic calls.
|
||||
struct MemIntrinsicVisitor : public InstVisitor<MemIntrinsicVisitor> {
|
||||
Function &F;
|
||||
unsigned NMemIs = 0; // Number of memIntrinsics instrumented.
|
||||
VisitMode Mode = VM_counting; // Visiting mode.
|
||||
unsigned CurCtrId = 0; // Current counter index.
|
||||
unsigned TotalNumCtrs = 0; // Total number of counters
|
||||
GlobalVariable *FuncNameVar = nullptr;
|
||||
uint64_t FuncHash = 0;
|
||||
PGOUseFunc *UseFunc = nullptr;
|
||||
|
||||
MemIntrinsicVisitor(Function &Func) : F(Func) {}
|
||||
|
||||
void countMemIntrinsics(Function &Func) {
|
||||
NMemIs = 0;
|
||||
Mode = VM_counting;
|
||||
visit(Func);
|
||||
}
|
||||
void instrumentMemIntrinsics(Function &Func, unsigned TotalNC,
|
||||
GlobalVariable *FNV, uint64_t FHash) {
|
||||
Mode = VM_instrument;
|
||||
TotalNumCtrs = TotalNC;
|
||||
FuncHash = FHash;
|
||||
FuncNameVar = FNV;
|
||||
visit(Func);
|
||||
}
|
||||
|
||||
// Visit the IR stream and annotate all mem intrinsic call instructions.
|
||||
void instrumentOneMemIntrinsic(MemIntrinsic &MI);
|
||||
// Visit \p MI instruction and perform tasks according to visit mode.
|
||||
void visitMemIntrinsic(MemIntrinsic &SI);
|
||||
unsigned getNumOfMemIntrinsics() const { return NMemIs; }
|
||||
};
|
||||
|
||||
class PGOInstrumentationGenLegacyPass : public ModulePass {
|
||||
public:
|
||||
static char ID;
|
||||
@ -354,6 +393,7 @@ private:
|
||||
public:
|
||||
std::vector<std::vector<Instruction *>> ValueSites;
|
||||
SelectInstVisitor SIVisitor;
|
||||
MemIntrinsicVisitor MIVisitor;
|
||||
std::string FuncName;
|
||||
GlobalVariable *FuncNameVar;
|
||||
// CFG hash value for this function.
|
||||
@ -384,11 +424,13 @@ public:
|
||||
bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,
|
||||
BlockFrequencyInfo *BFI = nullptr)
|
||||
: F(Func), ComdatMembers(ComdatMembers), ValueSites(IPVK_Last + 1),
|
||||
SIVisitor(Func), FunctionHash(0), MST(F, BPI, BFI) {
|
||||
SIVisitor(Func), MIVisitor(Func), FunctionHash(0), MST(F, BPI, BFI) {
|
||||
|
||||
// This should be done before CFG hash computation.
|
||||
SIVisitor.countSelects(Func);
|
||||
MIVisitor.countMemIntrinsics(Func);
|
||||
NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
|
||||
NumOfPGOMemIntrinsics += MIVisitor.getNumOfMemIntrinsics();
|
||||
ValueSites[IPVK_IndirectCallTarget] = findIndirectCallSites(Func);
|
||||
|
||||
FuncName = getPGOFuncName(F);
|
||||
@ -605,6 +647,10 @@ static void instrumentOneFunc(
|
||||
Builder.getInt32(NumIndirectCallSites++)});
|
||||
}
|
||||
NumOfPGOICall += NumIndirectCallSites;
|
||||
|
||||
// Now instrument memop intrinsic calls.
|
||||
FuncInfo.MIVisitor.instrumentMemIntrinsics(
|
||||
F, NumCounters, FuncInfo.FuncNameVar, FuncInfo.FunctionHash);
|
||||
}
|
||||
|
||||
// This class represents a CFG edge in profile use compilation.
|
||||
@ -1076,6 +1122,42 @@ void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
|
||||
llvm_unreachable("Unknown visiting mode");
|
||||
}
|
||||
|
||||
void MemIntrinsicVisitor::instrumentOneMemIntrinsic(MemIntrinsic &MI) {
|
||||
Module *M = F.getParent();
|
||||
IRBuilder<> Builder(&MI);
|
||||
Type *Int64Ty = Builder.getInt64Ty();
|
||||
Type *I8PtrTy = Builder.getInt8PtrTy();
|
||||
Value *Length = MI.getLength();
|
||||
assert(!dyn_cast<ConstantInt>(Length));
|
||||
Builder.CreateCall(
|
||||
Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile),
|
||||
{llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
|
||||
Builder.getInt64(FuncHash), Builder.CreatePtrToInt(Length, Int64Ty),
|
||||
Builder.getInt32(IPVK_MemOPSize), Builder.getInt32(CurCtrId)});
|
||||
++CurCtrId;
|
||||
}
|
||||
|
||||
void MemIntrinsicVisitor::visitMemIntrinsic(MemIntrinsic &MI) {
|
||||
if (!PGOInstrMemOP)
|
||||
return;
|
||||
Value *Length = MI.getLength();
|
||||
// Not instrument constant length calls.
|
||||
if (dyn_cast<ConstantInt>(Length))
|
||||
return;
|
||||
|
||||
switch (Mode) {
|
||||
case VM_counting:
|
||||
NMemIs++;
|
||||
return;
|
||||
case VM_instrument:
|
||||
instrumentOneMemIntrinsic(MI);
|
||||
return;
|
||||
case VM_annotate:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Unknown visiting mode");
|
||||
}
|
||||
|
||||
// Traverse all valuesites and annotate the instructions for all value kind.
|
||||
void PGOUseFunc::annotateValueSites() {
|
||||
if (DisableValueProfiling)
|
||||
@ -1085,7 +1167,9 @@ void PGOUseFunc::annotateValueSites() {
|
||||
createPGOFuncNameMetadata(F, FuncInfo.FuncName);
|
||||
|
||||
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
|
||||
annotateValueSites(Kind);
|
||||
// TBD: Only handle IPVK_IndirectCallTarget for now.
|
||||
if (Kind == IPVK_IndirectCallTarget)
|
||||
annotateValueSites(Kind);
|
||||
}
|
||||
|
||||
// Annotate the instructions for a specific value kind.
|
||||
|
@ -15,13 +15,13 @@ $_Z3barIvEvv = comdat any
|
||||
|
||||
; CHECK-NOT: __profn__Z3barIvEvv
|
||||
; CHECK: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__profv__Z3barIvEvv), align 8
|
||||
; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data{{.*}}", comdat($__profv__Z3barIvEvv), align 8
|
||||
; CHECK: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data{{.*}}", comdat($__profv__Z3barIvEvv), align 8
|
||||
; CHECK: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names"
|
||||
|
||||
|
||||
; COFF-NOT: __profn__Z3barIvEvv
|
||||
; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat, align 8
|
||||
; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data{{.*}}", comdat($__profc__Z3barIvEvv), align 8
|
||||
|
||||
|
||||
declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1
|
||||
|
@ -37,9 +37,9 @@ attributes #0 = { nounwind }
|
||||
; DYN-NOT: @__profvp_foo
|
||||
; DYN-NOT: @__llvm_prf_vnodes
|
||||
|
||||
; STATIC: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 0)
|
||||
; STATIC-EXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 zeroext 0)
|
||||
; STATIC-SEXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 signext 0)
|
||||
; STATIC: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*), i32 0)
|
||||
; STATIC-EXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*), i32 zeroext 0)
|
||||
; STATIC-SEXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*), i32 signext 0)
|
||||
|
||||
; STATIC: declare void @__llvm_profile_instrument_target(i64, i8*, i32)
|
||||
; STATIC-EXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 zeroext)
|
||||
|
@ -14,9 +14,9 @@ $foo = comdat any
|
||||
; CHECK: @__llvm_profile_raw_version = constant i64 {{[0-9]+}}, comdat
|
||||
; CHECK-NOT: __profn__stdin__foo
|
||||
; CHECK: @__profc__stdin__foo.[[FOO_HASH]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
|
||||
; CHECK: @__profd__stdin__foo.[[FOO_HASH]] = private global { i64, i64, i64*, i8*, i8*, i32, [1 x i16] } { i64 -5640069336071256030, i64 [[FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[FOO_HASH]], i32 0, i32 0), i8* null
|
||||
; CHECK: @__profd__stdin__foo.[[FOO_HASH]] = private global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -5640069336071256030, i64 [[FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[FOO_HASH]], i32 0, i32 0), i8* null
|
||||
; CHECK-NOT: bitcast (i32 ()* @foo to i8*)
|
||||
; CHECK-SAME: , i8* null, i32 1, [1 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
|
||||
; CHECK-SAME: , i8* null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
|
||||
; CHECK: @__llvm_prf_nm
|
||||
; CHECK: @llvm.used
|
||||
|
||||
|
@ -458,7 +458,7 @@ typedef struct ValueSitesStats {
|
||||
|
||||
static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
|
||||
ValueSitesStats &Stats, raw_fd_ostream &OS,
|
||||
InstrProfSymtab &Symtab) {
|
||||
InstrProfSymtab *Symtab) {
|
||||
uint32_t NS = Func.getNumValueSites(VK);
|
||||
Stats.TotalNumValueSites += NS;
|
||||
for (size_t I = 0; I < NS; ++I) {
|
||||
@ -473,8 +473,11 @@ static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
|
||||
}
|
||||
for (uint32_t V = 0; V < NV; V++) {
|
||||
OS << "\t[ " << I << ", ";
|
||||
OS << Symtab.getFuncName(VD[V].Value) << ", " << VD[V].Count;
|
||||
OS << " ]\n";
|
||||
if (Symtab == nullptr)
|
||||
OS << VD[V].Value;
|
||||
else
|
||||
OS << Symtab->getFuncName(VD[V].Value);
|
||||
OS << ", " << VD[V].Count << " ]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -494,7 +497,7 @@ static void showValueSitesStats(raw_fd_ostream &OS, uint32_t VK,
|
||||
}
|
||||
|
||||
static int showInstrProfile(const std::string &Filename, bool ShowCounts,
|
||||
bool ShowIndirectCallTargets,
|
||||
bool ShowIndirectCallTargets, bool ShowMemOPSizes,
|
||||
bool ShowDetailedSummary,
|
||||
std::vector<uint32_t> DetailedSummaryCutoffs,
|
||||
bool ShowAllFunctions,
|
||||
@ -547,6 +550,11 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
|
||||
OS << " Indirect Call Site Count: "
|
||||
<< Func.getNumValueSites(IPVK_IndirectCallTarget) << "\n";
|
||||
|
||||
uint32_t NumMemOPCalls = Func.getNumValueSites(IPVK_MemOPSize);
|
||||
if (ShowMemOPSizes && NumMemOPCalls > 0)
|
||||
OS << " Number of Memory Intrinsics Calls: " << NumMemOPCalls
|
||||
<< "\n";
|
||||
|
||||
if (ShowCounts) {
|
||||
OS << " Block counts: [";
|
||||
size_t Start = (IsIRInstr ? 0 : 1);
|
||||
@ -560,7 +568,13 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
|
||||
OS << " Indirect Target Results:\n";
|
||||
traverseAllValueSites(Func, IPVK_IndirectCallTarget,
|
||||
VPStats[IPVK_IndirectCallTarget], OS,
|
||||
Reader->getSymtab());
|
||||
&(Reader->getSymtab()));
|
||||
}
|
||||
|
||||
if (ShowMemOPSizes && NumMemOPCalls > 0) {
|
||||
OS << " Memory Instrinsic Size Results:\n";
|
||||
traverseAllValueSites(Func, IPVK_MemOPSize, VPStats[IPVK_MemOPSize], OS,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -575,12 +589,18 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts,
|
||||
OS << "Total functions: " << PS->getNumFunctions() << "\n";
|
||||
OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
|
||||
OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
|
||||
|
||||
if (ShownFunctions && ShowIndirectCallTargets) {
|
||||
OS << "Statistics for indirect call sites profile:\n";
|
||||
showValueSitesStats(OS, IPVK_IndirectCallTarget,
|
||||
VPStats[IPVK_IndirectCallTarget]);
|
||||
}
|
||||
|
||||
if (ShownFunctions && ShowMemOPSizes) {
|
||||
OS << "Statistics for memory intrinsic calls sizes profile:\n";
|
||||
showValueSitesStats(OS, IPVK_MemOPSize, VPStats[IPVK_MemOPSize]);
|
||||
}
|
||||
|
||||
if (ShowDetailedSummary) {
|
||||
OS << "Detailed summary:\n";
|
||||
OS << "Total number of blocks: " << PS->getNumCounts() << "\n";
|
||||
@ -629,6 +649,10 @@ static int show_main(int argc, const char *argv[]) {
|
||||
cl::opt<bool> ShowIndirectCallTargets(
|
||||
"ic-targets", cl::init(false),
|
||||
cl::desc("Show indirect call site target values for shown functions"));
|
||||
cl::opt<bool> ShowMemOPSizes(
|
||||
"memop-sizes", cl::init(false),
|
||||
cl::desc("Show the profiled sizes of the memory intrinsic calls "
|
||||
"for shown functions"));
|
||||
cl::opt<bool> ShowDetailedSummary("detailed-summary", cl::init(false),
|
||||
cl::desc("Show detailed profile summary"));
|
||||
cl::list<uint32_t> DetailedSummaryCutoffs(
|
||||
@ -667,8 +691,9 @@ static int show_main(int argc, const char *argv[]) {
|
||||
DetailedSummaryCutoffs.end());
|
||||
if (ProfileKind == instr)
|
||||
return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
|
||||
ShowDetailedSummary, DetailedSummaryCutoffs,
|
||||
ShowAllFunctions, ShowFunction, TextFormat, OS);
|
||||
ShowMemOPSizes, ShowDetailedSummary,
|
||||
DetailedSummaryCutoffs, ShowAllFunctions,
|
||||
ShowFunction, TextFormat, OS);
|
||||
else
|
||||
return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
|
||||
ShowFunction, OS);
|
||||
|
Loading…
Reference in New Issue
Block a user