llvm.org GIT mirror llvm / 670b422
[PGO] Value profile for size of memory intrinsic calls This patch adds the value profile support to profile the size parameter of memory intrinsic calls: memcpy, memcmp, and memmov. Differential Revision: http://reviews.llvm.org/D28965 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297897 91177308-0d34-0410-b5e6-96231b3b80d8 Rong Xu 2 years ago
10 changed file(s) with 236 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
195195
196196 Specify that the input profile is a sample-based profile.
197197
198 .. option:: -memop-sizes
199
200 Show the profiled sizes of the memory intrinsic calls for shown functions.
201
198202 EXIT STATUS
199203 -----------
200204
9393 return INSTR_PROF_VALUE_PROF_FUNC_STR;
9494 }
9595
96 /// Return the name profile runtime entry point to do value range profiling.
97 inline StringRef getInstrProfValueRangeProfFuncName() {
98 return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR;
99 }
100
96101 /// Return the name of the section containing function coverage mapping
97102 /// data.
98103 inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
688693
689694 private:
690695 std::vector IndirectCallSites;
696 std::vector MemOPSizes;
691697 const std::vector &
692698
693699 getValueSitesForKind(uint32_t ValueKind) const {
694700 switch (ValueKind) {
695701 case IPVK_IndirectCallTarget:
696702 return IndirectCallSites;
703 case IPVK_MemOPSize:
704 return MemOPSizes;
697705 default:
698706 llvm_unreachable("Unknown value kind!");
699707 }
152152 VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \
153153 INSTR_PROF_COMMA
154154 VALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA
155 #ifndef VALUE_RANGE_PROF
155156 VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
157 #else /* VALUE_RANGE_PROF */
158 VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) \
159 INSTR_PROF_COMMA
160 VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeStart, Type::getInt64Ty(Ctx)) \
161 INSTR_PROF_COMMA
162 VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeLast, Type::getInt64Ty(Ctx)) \
163 INSTR_PROF_COMMA
164 VALUE_PROF_FUNC_PARAM(uint64_t, LargeValue, Type::getInt64Ty(Ctx))
165 #endif /*VALUE_RANGE_PROF */
156166 #undef VALUE_PROF_FUNC_PARAM
157167 #undef INSTR_PROF_COMMA
158168 /* VALUE_PROF_FUNC_PARAM end */
173183 * name hash and the function address.
174184 */
175185 VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0)
186 /* For memory intrinsic functions size profiling. */
187 VALUE_PROF_KIND(IPVK_MemOPSize, 1)
176188 /* These two kinds must be the last to be
177189 * declared. This is to make sure the string
178190 * array created with the template can be
179191 * indexed with the kind value.
180192 */
181193 VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget)
182 VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget)
194 VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize)
183195
184196 #undef VALUE_PROF_KIND
185197 /* VALUE_PROF_KIND end */
648660 #define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target
649661 #define INSTR_PROF_VALUE_PROF_FUNC_STR \
650662 INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)
663 #define INSTR_PROF_VALUE_RANGE_PROF_FUNC __llvm_profile_instrument_range
664 #define INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR \
665 INSTR_PROF_QUOTE(INSTR_PROF_VALUE_RANGE_PROF_FUNC)
651666
652667 /* InstrProfile per-function control data alignment. */
653668 #define INSTR_PROF_DATA_ALIGNMENT 8
5858 GlobalVariable *NamesVar;
5959 size_t NamesSize;
6060
61 // The start value of precise value profile range for memory intrinsic sizes.
62 const int64_t DefaultMemOPSizeRangeStart = 0;
63 int64_t MemOPSizeRangeStart;
64 // The end value of precise value profile range for memory intrinsic sizes.
65 const int64_t DefaultMemOPSizeRangeLast = 8;
66 int64_t MemOPSizeRangeLast;
67 int64_t MemOPSizeLargeVal;
68
6169 bool isMachO() const;
6270
6371 /// Get the section name for the counter variables.
108116 /// Create a static initializer for our data, on platforms that need it,
109117 /// and for any profile output file that was specified.
110118 void emitInitialization();
119
120 /// Helper funtion that parsing the MemOPSize value profile options
121 void getMemOPSizeOptions();
111122 };
112123
113124 } // end namespace llvm
7676 // is usually smaller than 2.
7777 cl::init(1.0));
7878
79 cl::opt MemOPSizeRange(
80 "memop-size-range",
81 cl::desc("Set the range of size in memory intrinsic calls to be profiled "
82 "precisely, in a format of :"),
83 cl::init(""));
84 cl::opt MemOPSizeLarge(
85 "memop-size-large",
86 cl::desc("Set large value thresthold in memory intrinsic size profiling. "
87 "Value of 0 disables the large value profiling."),
88 cl::init(8192));
89
7990 class InstrProfilingLegacyPass : public ModulePass {
8091 InstrProfiling InstrProf;
8192
164175 NamesSize = 0;
165176 ProfileDataMap.clear();
166177 UsedVars.clear();
178 getMemOPSizeOptions();
167179
168180 // We did not know how many value sites there would be inside
169181 // the instrumented function. This is counting the number of instrumented
216228 }
217229
218230 static Constant *getOrInsertValueProfilingCall(Module &M,
219 const TargetLibraryInfo &TLI) {
231 const TargetLibraryInfo &TLI,
232 bool IsRange = false) {
220233 LLVMContext &Ctx = M.getContext();
221234 auto *ReturnTy = Type::getVoidTy(M.getContext());
222 Type *ParamTypes[] = {
235
236 Constant *Res;
237 if (!IsRange) {
238 Type *ParamTypes[] = {
223239 #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
224240 #include "llvm/ProfileData/InstrProfData.inc"
225 };
226 auto *ValueProfilingCallTy =
227 FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
228 Constant *Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
229 ValueProfilingCallTy);
241 };
242 auto *ValueProfilingCallTy =
243 FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
244 Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
245 ValueProfilingCallTy);
246 } else {
247 Type *RangeParamTypes[] = {
248 #define VALUE_RANGE_PROF 1
249 #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType
250 #include "llvm/ProfileData/InstrProfData.inc"
251 #undef VALUE_RANGE_PROF
252 };
253 auto *ValueRangeProfilingCallTy =
254 FunctionType::get(ReturnTy, makeArrayRef(RangeParamTypes), false);
255 Res = M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(),
256 ValueRangeProfilingCallTy);
257 }
258
230259 if (Function *FunRes = dyn_cast(Res)) {
231260 if (auto AK = TLI.getExtAttrForI32Param(false))
232261 FunRes->addAttribute(3, AK);
260289 Index += It->second.NumValueSites[Kind];
261290
262291 IRBuilder<> Builder(Ind);
263 Value *Args[3] = {Ind->getTargetValue(),
264 Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
265 Builder.getInt32(Index)};
266 CallInst *Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI),
267 Args);
292 bool IsRange = (Ind->getValueKind()->getZExtValue() ==
293 llvm::InstrProfValueKind::IPVK_MemOPSize);
294 CallInst *Call = nullptr;
295 if (!IsRange) {
296 Value *Args[3] = {Ind->getTargetValue(),
297 Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
298 Builder.getInt32(Index)};
299 Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI), Args);
300 } else {
301 Value *Args[6] = {Ind->getTargetValue(),
302 Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
303 Builder.getInt32(Index),
304 Builder.getInt64(MemOPSizeRangeStart),
305 Builder.getInt64(MemOPSizeRangeLast),
306 Builder.getInt64(MemOPSizeLargeVal)};
307 Call =
308 Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI, true), Args);
309 }
268310 if (auto AK = TLI->getExtAttrForI32Param(false))
269311 Call->addAttribute(3, AK);
270312 Ind->replaceAllUsesWith(Call);
657699
658700 appendToGlobalCtors(*M, F, 0);
659701 }
702
703 void InstrProfiling::getMemOPSizeOptions() {
704 // Parse the value profile options.
705 MemOPSizeRangeStart = DefaultMemOPSizeRangeStart;
706 MemOPSizeRangeLast = DefaultMemOPSizeRangeLast;
707 if (!MemOPSizeRange.empty()) {
708 auto Pos = MemOPSizeRange.find(":");
709 if (Pos != std::string::npos) {
710 if (Pos > 0)
711 MemOPSizeRangeStart = std::stoi(MemOPSizeRange.substr(0, Pos));
712 if (Pos < MemOPSizeRange.size() - 1)
713 MemOPSizeRangeLast = std::stoi(MemOPSizeRange.substr(Pos + 1));
714 } else
715 MemOPSizeRangeLast = std::stoi(MemOPSizeRange);
716 }
717 assert(MemOPSizeRangeLast >= MemOPSizeRangeStart);
718
719 MemOPSizeLargeVal = MemOPSizeLarge;
720 if (MemOPSizeLargeVal == 0)
721 MemOPSizeLargeVal = INT64_MIN;
722 }
9090
9191 STATISTIC(NumOfPGOInstrument, "Number of edges instrumented.");
9292 STATISTIC(NumOfPGOSelectInsts, "Number of select instruction instrumented.");
93 STATISTIC(NumOfPGOMemIntrinsics, "Number of mem intrinsics instrumented.");
9394 STATISTIC(NumOfPGOEdge, "Number of edges.");
9495 STATISTIC(NumOfPGOBB, "Number of basic-blocks.");
9596 STATISTIC(NumOfPGOSplit, "Number of critical edge splits.");
166167 "-pgo-view-counts. To limit graph "
167168 "display to only one function, use "
168169 "filtering option -view-bfi-func-name."));
170
171 // Command line option to enable/disable memop intrinsic calls..
172 static cl::opt PGOInstrMemOP("pgo-instr-memop", cl::init(true),
173 cl::Hidden);
169174
170175 // Command line option to turn on CFG dot dump after profile annotation.
171176 // Defined in Analysis/BlockFrequencyInfo.cpp: -pgo-view-counts
232237 // Return the number of select instructions. This needs be called after
233238 // countSelects().
234239 unsigned getNumOfSelectInsts() const { return NSIs; }
240 };
241
242 /// Instruction Visitor class to visit memory intrinsic calls.
243 struct MemIntrinsicVisitor : public InstVisitor {
244 Function &F;
245 unsigned NMemIs = 0; // Number of memIntrinsics instrumented.
246 VisitMode Mode = VM_counting; // Visiting mode.
247 unsigned CurCtrId = 0; // Current counter index.
248 unsigned TotalNumCtrs = 0; // Total number of counters
249 GlobalVariable *FuncNameVar = nullptr;
250 uint64_t FuncHash = 0;
251 PGOUseFunc *UseFunc = nullptr;
252
253 MemIntrinsicVisitor(Function &Func) : F(Func) {}
254
255 void countMemIntrinsics(Function &Func) {
256 NMemIs = 0;
257 Mode = VM_counting;
258 visit(Func);
259 }
260 void instrumentMemIntrinsics(Function &Func, unsigned TotalNC,
261 GlobalVariable *FNV, uint64_t FHash) {
262 Mode = VM_instrument;
263 TotalNumCtrs = TotalNC;
264 FuncHash = FHash;
265 FuncNameVar = FNV;
266 visit(Func);
267 }
268
269 // Visit the IR stream and annotate all mem intrinsic call instructions.
270 void instrumentOneMemIntrinsic(MemIntrinsic &MI);
271 // Visit \p MI instruction and perform tasks according to visit mode.
272 void visitMemIntrinsic(MemIntrinsic &SI);
273 unsigned getNumOfMemIntrinsics() const { return NMemIs; }
235274 };
236275
237276 class PGOInstrumentationGenLegacyPass : public ModulePass {
353392 public:
354393 std::vector> ValueSites;
355394 SelectInstVisitor SIVisitor;
395 MemIntrinsicVisitor MIVisitor;
356396 std::string FuncName;
357397 GlobalVariable *FuncNameVar;
358398 // CFG hash value for this function.
383423 bool CreateGlobalVar = false, BranchProbabilityInfo *BPI = nullptr,
384424 BlockFrequencyInfo *BFI = nullptr)
385425 : F(Func), ComdatMembers(ComdatMembers), ValueSites(IPVK_Last + 1),
386 SIVisitor(Func), FunctionHash(0), MST(F, BPI, BFI) {
426 SIVisitor(Func), MIVisitor(Func), FunctionHash(0), MST(F, BPI, BFI) {
387427
388428 // This should be done before CFG hash computation.
389429 SIVisitor.countSelects(Func);
430 MIVisitor.countMemIntrinsics(Func);
390431 NumOfPGOSelectInsts += SIVisitor.getNumOfSelectInsts();
432 NumOfPGOMemIntrinsics += MIVisitor.getNumOfMemIntrinsics();
391433 ValueSites[IPVK_IndirectCallTarget] = findIndirectCallSites(Func);
392434
393435 FuncName = getPGOFuncName(F);
604646 Builder.getInt32(NumIndirectCallSites++)});
605647 }
606648 NumOfPGOICall += NumIndirectCallSites;
649
650 // Now instrument memop intrinsic calls.
651 FuncInfo.MIVisitor.instrumentMemIntrinsics(
652 F, NumCounters, FuncInfo.FuncNameVar, FuncInfo.FunctionHash);
607653 }
608654
609655 // This class represents a CFG edge in profile use compilation.
10751121 llvm_unreachable("Unknown visiting mode");
10761122 }
10771123
1124 void MemIntrinsicVisitor::instrumentOneMemIntrinsic(MemIntrinsic &MI) {
1125 Module *M = F.getParent();
1126 IRBuilder<> Builder(&MI);
1127 Type *Int64Ty = Builder.getInt64Ty();
1128 Type *I8PtrTy = Builder.getInt8PtrTy();
1129 Value *Length = MI.getLength();
1130 assert(!dyn_cast(Length));
1131 Builder.CreateCall(
1132 Intrinsic::getDeclaration(M, Intrinsic::instrprof_value_profile),
1133 {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
1134 Builder.getInt64(FuncHash), Builder.CreatePtrToInt(Length, Int64Ty),
1135 Builder.getInt32(IPVK_MemOPSize), Builder.getInt32(CurCtrId)});
1136 ++CurCtrId;
1137 }
1138
1139 void MemIntrinsicVisitor::visitMemIntrinsic(MemIntrinsic &MI) {
1140 if (!PGOInstrMemOP)
1141 return;
1142 Value *Length = MI.getLength();
1143 // Not instrument constant length calls.
1144 if (dyn_cast(Length))
1145 return;
1146
1147 NMemIs++;
1148 switch (Mode) {
1149 case VM_counting:
1150 return;
1151 case VM_instrument:
1152 instrumentOneMemIntrinsic(MI);
1153 return;
1154 case VM_annotate:
1155 break;
1156 }
1157 llvm_unreachable("Unknown visiting mode");
1158 }
1159
10781160 // Traverse all valuesites and annotate the instructions for all value kind.
10791161 void PGOUseFunc::annotateValueSites() {
10801162 if (DisableValueProfiling)
1414
1515 ; CHECK-NOT: __profn__Z3barIvEvv
1616 ; CHECK: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__profv__Z3barIvEvv), align 8
17 ; 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
17 ; 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
1818 ; CHECK: @__llvm_prf_nm = private constant [{{.*}} x i8] c"{{.*}}", section "{{.*}}__llvm_prf_names"
1919
2020
2121 ; COFF-NOT: __profn__Z3barIvEvv
2222 ; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat, align 8
23 ; 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
23 ; 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
2424
2525
2626 declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1
3636 ; DYN-NOT: @__profvp_foo
3737 ; DYN-NOT: @__llvm_prf_vnodes
3838
39 ; 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)
40 ; 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)
41 ; 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)
39 ; 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)
40 ; 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)
41 ; 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)
4242
4343 ; STATIC: declare void @__llvm_profile_instrument_target(i64, i8*, i32)
4444 ; STATIC-EXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 zeroext)
1313 ; CHECK: @__llvm_profile_raw_version = constant i64 {{[0-9]+}}, comdat
1414 ; CHECK-NOT: __profn__stdin__foo
1515 ; CHECK: @__profc__stdin__foo.[[FOO_HASH]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
16 ; 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
16 ; 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
1717 ; CHECK-NOT: bitcast (i32 ()* @foo to i8*)
18 ; CHECK-SAME: , i8* null, i32 1, [1 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
18 ; CHECK-SAME: , i8* null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
1919 ; CHECK: @__llvm_prf_nm
2020 ; CHECK: @llvm.used
2121
457457
458458 static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
459459 ValueSitesStats &Stats, raw_fd_ostream &OS,
460 InstrProfSymtab &Symtab) {
460 InstrProfSymtab *Symtab) {
461461 uint32_t NS = Func.getNumValueSites(VK);
462462 Stats.TotalNumValueSites += NS;
463463 for (size_t I = 0; I < NS; ++I) {
472472 }
473473 for (uint32_t V = 0; V < NV; V++) {
474474 OS << "\t[ " << I << ", ";
475 OS << Symtab.getFuncName(VD[V].Value) << ", " << VD[V].Count;
476 OS << " ]\n";
475 if (Symtab == nullptr)
476 OS << VD[V].Value;
477 else
478 OS << Symtab->getFuncName(VD[V].Value);
479 OS << ", " << VD[V].Count << " ]\n";
477480 }
478481 }
479482 }
493496 }
494497
495498 static int showInstrProfile(const std::string &Filename, bool ShowCounts,
496 bool ShowIndirectCallTargets,
499 bool ShowIndirectCallTargets, bool ShowMemOPSizes,
497500 bool ShowDetailedSummary,
498501 std::vector DetailedSummaryCutoffs,
499502 bool ShowAllFunctions,
546549 OS << " Indirect Call Site Count: "
547550 << Func.getNumValueSites(IPVK_IndirectCallTarget) << "\n";
548551
552 uint32_t NumMemOPCalls = Func.getNumValueSites(IPVK_MemOPSize);
553 if (ShowMemOPSizes && NumMemOPCalls > 0)
554 OS << " Number of Memory Intrinsics Calls: " << NumMemOPCalls
555 << "\n";
556
549557 if (ShowCounts) {
550558 OS << " Block counts: [";
551559 size_t Start = (IsIRInstr ? 0 : 1);
559567 OS << " Indirect Target Results:\n";
560568 traverseAllValueSites(Func, IPVK_IndirectCallTarget,
561569 VPStats[IPVK_IndirectCallTarget], OS,
562 Reader->getSymtab());
570 &(Reader->getSymtab()));
571 }
572
573 if (ShowMemOPSizes && NumMemOPCalls > 0) {
574 OS << " Memory Instrinsic Size Results:\n";
575 traverseAllValueSites(Func, IPVK_MemOPSize, VPStats[IPVK_MemOPSize], OS,
576 nullptr);
563577 }
564578 }
565579 }
574588 OS << "Total functions: " << PS->getNumFunctions() << "\n";
575589 OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
576590 OS << "Maximum internal block count: " << PS->getMaxInternalCount() << "\n";
591
577592 if (ShownFunctions && ShowIndirectCallTargets) {
578593 OS << "Statistics for indirect call sites profile:\n";
579594 showValueSitesStats(OS, IPVK_IndirectCallTarget,
580595 VPStats[IPVK_IndirectCallTarget]);
596 }
597
598 if (ShownFunctions && ShowMemOPSizes) {
599 OS << "Statistics for memory intrinsic calls sizes profile:\n";
600 showValueSitesStats(OS, IPVK_MemOPSize, VPStats[IPVK_MemOPSize]);
581601 }
582602
583603 if (ShowDetailedSummary) {
628648 cl::opt ShowIndirectCallTargets(
629649 "ic-targets", cl::init(false),
630650 cl::desc("Show indirect call site target values for shown functions"));
651 cl::opt ShowMemOPSizes(
652 "memop-sizes", cl::init(false),
653 cl::desc("Show the profiled sizes of the memory intrinsic calls "
654 "for shown functions"));
631655 cl::opt ShowDetailedSummary("detailed-summary", cl::init(false),
632656 cl::desc("Show detailed profile summary"));
633657 cl::list DetailedSummaryCutoffs(
666690 DetailedSummaryCutoffs.end());
667691 if (ProfileKind == instr)
668692 return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
669 ShowDetailedSummary, DetailedSummaryCutoffs,
670 ShowAllFunctions, ShowFunction, TextFormat, OS);
693 ShowMemOPSizes, ShowDetailedSummary,
694 DetailedSummaryCutoffs, ShowAllFunctions,
695 ShowFunction, TextFormat, OS);
671696 else
672697 return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
673698 ShowFunction, OS);