7
7
// ===----------------------------------------------------------------------===//
8
8
#include " ProfileGenerator.h"
9
9
#include " ErrorHandling.h"
10
+ #include " PerfReader.h"
10
11
#include " ProfiledBinary.h"
11
12
#include " llvm/DebugInfo/Symbolize/SymbolizableModule.h"
12
13
#include " llvm/ProfileData/ProfileCommon.h"
13
14
#include < algorithm>
14
15
#include < float.h>
15
16
#include < unordered_set>
17
+ #include < utility>
16
18
17
19
cl::opt<std::string> OutputFilename (" output" , cl::value_desc(" output" ),
18
20
cl::Required,
@@ -109,7 +111,7 @@ bool ProfileGeneratorBase::UseFSDiscriminator = false;
109
111
110
112
std::unique_ptr<ProfileGeneratorBase>
111
113
ProfileGeneratorBase::create (ProfiledBinary *Binary,
112
- const ContextSampleCounterMap & SampleCounters,
114
+ const ContextSampleCounterMap * SampleCounters,
113
115
bool ProfileIsCSFlat) {
114
116
std::unique_ptr<ProfileGeneratorBase> Generator;
115
117
if (ProfileIsCSFlat) {
@@ -125,6 +127,24 @@ ProfileGeneratorBase::create(ProfiledBinary *Binary,
125
127
return Generator;
126
128
}
127
129
130
+ std::unique_ptr<ProfileGeneratorBase>
131
+ ProfileGeneratorBase::create (ProfiledBinary *Binary,
132
+ const SampleProfileMap &&Profiles,
133
+ bool ProfileIsCSFlat) {
134
+ std::unique_ptr<ProfileGeneratorBase> Generator;
135
+ if (ProfileIsCSFlat) {
136
+ if (Binary->useFSDiscriminator ())
137
+ exitWithError (" FS discriminator is not supported in CS profile." );
138
+ Generator.reset (new CSProfileGenerator (Binary, std::move (Profiles)));
139
+ } else {
140
+ Generator.reset (new ProfileGenerator (Binary, std::move (Profiles)));
141
+ }
142
+ ProfileGeneratorBase::UseFSDiscriminator = Binary->useFSDiscriminator ();
143
+ FunctionSamples::ProfileIsFS = Binary->useFSDiscriminator ();
144
+
145
+ return Generator;
146
+ }
147
+
128
148
void ProfileGeneratorBase::write (std::unique_ptr<SampleProfileWriter> Writer,
129
149
SampleProfileMap &ProfileMap) {
130
150
// Populate profile symbol list if extended binary format is used.
@@ -372,31 +392,39 @@ void ProfileGeneratorBase::updateTotalSamples() {
372
392
373
393
void ProfileGeneratorBase::collectProfiledFunctions () {
374
394
std::unordered_set<const BinaryFunction *> ProfiledFunctions;
375
- // Go through all the stacks, ranges and branches in sample counters, use the
376
- // start of the range to look up the function it belongs and record the
377
- // function.
378
- for (const auto &CI : SampleCounters) {
379
- if (const auto *CtxKey = dyn_cast<AddrBasedCtxKey>(CI.first .getPtr ())) {
380
- for (auto Addr : CtxKey->Context ) {
381
- if (FuncRange *FRange = Binary->findFuncRangeForOffset (
382
- Binary->virtualAddrToOffset (Addr)))
395
+ if (SampleCounters) {
396
+ // Go through all the stacks, ranges and branches in sample counters, use
397
+ // the start of the range to look up the function it belongs and record the
398
+ // function.
399
+ for (const auto &CI : *SampleCounters) {
400
+ if (const auto *CtxKey = dyn_cast<AddrBasedCtxKey>(CI.first .getPtr ())) {
401
+ for (auto Addr : CtxKey->Context ) {
402
+ if (FuncRange *FRange = Binary->findFuncRangeForOffset (
403
+ Binary->virtualAddrToOffset (Addr)))
404
+ ProfiledFunctions.insert (FRange->Func );
405
+ }
406
+ }
407
+
408
+ for (auto Item : CI.second .RangeCounter ) {
409
+ uint64_t StartOffset = Item.first .first ;
410
+ if (FuncRange *FRange = Binary->findFuncRangeForOffset (StartOffset))
383
411
ProfiledFunctions.insert (FRange->Func );
384
412
}
385
- }
386
413
387
- for (auto Item : CI.second .RangeCounter ) {
388
- uint64_t StartOffset = Item.first .first ;
389
- if (FuncRange *FRange = Binary->findFuncRangeForOffset (StartOffset))
390
- ProfiledFunctions.insert (FRange->Func );
414
+ for (auto Item : CI.second .BranchCounter ) {
415
+ uint64_t SourceOffset = Item.first .first ;
416
+ uint64_t TargetOffset = Item.first .first ;
417
+ if (FuncRange *FRange = Binary->findFuncRangeForOffset (SourceOffset))
418
+ ProfiledFunctions.insert (FRange->Func );
419
+ if (FuncRange *FRange = Binary->findFuncRangeForOffset (TargetOffset))
420
+ ProfiledFunctions.insert (FRange->Func );
421
+ }
391
422
}
392
-
393
- for (auto Item : CI.second .BranchCounter ) {
394
- uint64_t SourceOffset = Item.first .first ;
395
- uint64_t TargetOffset = Item.first .first ;
396
- if (FuncRange *FRange = Binary->findFuncRangeForOffset (SourceOffset))
397
- ProfiledFunctions.insert (FRange->Func );
398
- if (FuncRange *FRange = Binary->findFuncRangeForOffset (TargetOffset))
399
- ProfiledFunctions.insert (FRange->Func );
423
+ } else {
424
+ // This is for the case the input is a llvm sample profile.
425
+ for (const auto &FS : ProfileMap) {
426
+ if (auto *Func = Binary->getBinaryFunction (FS.first .getName ()))
427
+ ProfiledFunctions.insert (Func);
400
428
}
401
429
}
402
430
@@ -416,11 +444,18 @@ ProfileGenerator::getTopLevelFunctionProfile(StringRef FuncName) {
416
444
417
445
void ProfileGenerator::generateProfile () {
418
446
collectProfiledFunctions ();
419
- if (Binary->usePseudoProbes ()) {
420
- generateProbeBasedProfile ();
421
- } else {
422
- generateLineNumBasedProfile ();
447
+
448
+ if (Binary->usePseudoProbes ())
449
+ Binary->decodePseudoProbe ();
450
+
451
+ if (SampleCounters) {
452
+ if (Binary->usePseudoProbes ()) {
453
+ generateProbeBasedProfile ();
454
+ } else {
455
+ generateLineNumBasedProfile ();
456
+ }
423
457
}
458
+
424
459
postProcessProfiles ();
425
460
}
426
461
@@ -448,9 +483,9 @@ void ProfileGenerator::trimColdProfiles(const SampleProfileMap &Profiles,
448
483
}
449
484
450
485
void ProfileGenerator::generateLineNumBasedProfile () {
451
- assert (SampleCounters. size () == 1 &&
486
+ assert (SampleCounters-> size () == 1 &&
452
487
" Must have one entry for profile generation." );
453
- const SampleCounter &SC = SampleCounters. begin ()->second ;
488
+ const SampleCounter &SC = SampleCounters-> begin ()->second ;
454
489
// Fill in function body samples
455
490
populateBodySamplesForAllFunctions (SC.RangeCounter );
456
491
// Fill in boundary sample counts as well as call site samples for calls
@@ -460,12 +495,11 @@ void ProfileGenerator::generateLineNumBasedProfile() {
460
495
}
461
496
462
497
void ProfileGenerator::generateProbeBasedProfile () {
463
- assert (SampleCounters. size () == 1 &&
498
+ assert (SampleCounters-> size () == 1 &&
464
499
" Must have one entry for profile generation." );
465
- Binary->decodePseudoProbe ();
466
500
// Enable pseudo probe functionalities in SampleProf
467
501
FunctionSamples::ProfileIsProbeBased = true ;
468
- const SampleCounter &SC = SampleCounters. begin ()->second ;
502
+ const SampleCounter &SC = SampleCounters-> begin ()->second ;
469
503
// Fill in function body samples
470
504
populateBodySamplesWithProbesForAllFunctions (SC.RangeCounter );
471
505
// Fill in boundary sample counts as well as call site samples for calls
@@ -687,10 +721,15 @@ void CSProfileGenerator::generateProfile() {
687
721
688
722
collectProfiledFunctions ();
689
723
690
- if (Binary->usePseudoProbes ()) {
691
- generateProbeBasedProfile ();
692
- } else {
693
- generateLineNumBasedProfile ();
724
+ if (Binary->usePseudoProbes ())
725
+ Binary->decodePseudoProbe ();
726
+
727
+ if (SampleCounters) {
728
+ if (Binary->usePseudoProbes ()) {
729
+ generateProbeBasedProfile ();
730
+ } else {
731
+ generateLineNumBasedProfile ();
732
+ }
694
733
}
695
734
696
735
if (Binary->getTrackFuncContextSize ())
@@ -709,7 +748,7 @@ void CSProfileGenerator::computeSizeForProfiledFunctions() {
709
748
}
710
749
711
750
void CSProfileGenerator::generateLineNumBasedProfile () {
712
- for (const auto &CI : SampleCounters) {
751
+ for (const auto &CI : * SampleCounters) {
713
752
const auto *CtxKey = cast<StringBasedCtxKey>(CI.first .getPtr ());
714
753
715
754
// Get or create function profile for the range
@@ -967,10 +1006,9 @@ extractPrefixContextStack(SampleContextFrameVector &ContextStack,
967
1006
}
968
1007
969
1008
void CSProfileGenerator::generateProbeBasedProfile () {
970
- Binary->decodePseudoProbe ();
971
1009
// Enable pseudo probe functionalities in SampleProf
972
1010
FunctionSamples::ProfileIsProbeBased = true ;
973
- for (const auto &CI : SampleCounters) {
1011
+ for (const auto &CI : * SampleCounters) {
974
1012
const AddrBasedCtxKey *CtxKey =
975
1013
dyn_cast<AddrBasedCtxKey>(CI.first .getPtr ());
976
1014
SampleContextFrameVector ContextStack;
0 commit comments