16
16
#include " llvm/Debuginfod/HTTPClient.h"
17
17
#include " llvm/IR/LLVMContext.h"
18
18
#include " llvm/Object/Binary.h"
19
+ #include " llvm/ProfileData/DataAccessProf.h"
19
20
#include " llvm/ProfileData/InstrProfCorrelator.h"
20
21
#include " llvm/ProfileData/InstrProfReader.h"
21
22
#include " llvm/ProfileData/InstrProfWriter.h"
@@ -52,23 +53,23 @@ using ProfCorrelatorKind = InstrProfCorrelator::ProfCorrelatorKind;
52
53
53
54
// https://llvm.org/docs/CommandGuide/llvm-profdata.html has documentations
54
55
// on each subcommand.
55
- static cl::SubCommand ShowSubcommand (
56
+ cl::SubCommand ShowSubcommand (
56
57
" show" ,
57
58
" Takes a profile data file and displays the profiles. See detailed "
58
59
" documentation in "
59
60
" https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-show" );
60
- static cl::SubCommand OrderSubcommand (
61
+ cl::SubCommand OrderSubcommand (
61
62
" order" ,
62
63
" Reads temporal profiling traces from a profile and outputs a function "
63
64
" order that reduces the number of page faults for those traces. See "
64
65
" detailed documentation in "
65
66
" https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-order" );
66
- static cl::SubCommand OverlapSubcommand (
67
+ cl::SubCommand OverlapSubcommand (
67
68
" overlap" ,
68
69
" Computes and displays the overlap between two profiles. See detailed "
69
70
" documentation in "
70
71
" https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-overlap" );
71
- static cl::SubCommand MergeSubcommand (
72
+ cl::SubCommand MergeSubcommand (
72
73
" merge" ,
73
74
" Takes several profiles and merge them together. See detailed "
74
75
" documentation in "
@@ -91,11 +92,12 @@ enum class ShowFormat { Text, Json, Yaml };
91
92
} // namespace
92
93
93
94
// Common options.
94
- static cl::opt<std::string>
95
- OutputFilename (" output" , cl::value_desc(" output" ), cl::init(" -" ),
96
- cl::desc(" Output file" ), cl::sub(ShowSubcommand),
97
- cl::sub(OrderSubcommand), cl::sub(OverlapSubcommand),
98
- cl::sub(MergeSubcommand));
95
+ cl::opt<std::string> OutputFilename (" output" , cl::value_desc(" output" ),
96
+ cl::init(" -" ), cl::desc(" Output file" ),
97
+ cl::sub(ShowSubcommand),
98
+ cl::sub(OrderSubcommand),
99
+ cl::sub(OverlapSubcommand),
100
+ cl::sub(MergeSubcommand));
99
101
// NOTE: cl::alias must not have cl::sub(), since aliased option's cl::sub()
100
102
// will be used. llvm::cl::alias::done() method asserts this condition.
101
103
static cl::alias OutputFilenameA (" o" , cl::desc(" Alias for --output" ),
@@ -525,9 +527,9 @@ static void exitWithError(Twine Message, StringRef Whence = "",
525
527
static void exitWithError (Error E, StringRef Whence = " " ) {
526
528
if (E.isA <InstrProfError>()) {
527
529
handleAllErrors (std::move (E), [&](const InstrProfError &IPE) {
528
- instrprof_error InstrError = IPE.get ();
530
+ instrprof_error instrError = IPE.get ();
529
531
StringRef Hint = " " ;
530
- if (InstrError == instrprof_error::unrecognized_format) {
532
+ if (instrError == instrprof_error::unrecognized_format) {
531
533
// Hint in case user missed specifying the profile type.
532
534
Hint = " Perhaps you forgot to use the --sample or --memory option?" ;
533
535
}
@@ -634,7 +636,7 @@ class SymbolRemapper {
634
636
return New.empty () ? Name : FunctionId (New);
635
637
}
636
638
};
637
- } // namespace
639
+ }
638
640
639
641
struct WeightedFile {
640
642
std::string Filename;
@@ -824,18 +826,18 @@ loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
824
826
// Only show hint the first time an error occurs.
825
827
auto [ErrCode, Msg] = InstrProfError::take (std::move (E));
826
828
std::unique_lock<std::mutex> ErrGuard{WC->ErrLock };
827
- bool FirstTime = WC->WriterErrorCodes .insert (ErrCode).second ;
829
+ bool firstTime = WC->WriterErrorCodes .insert (ErrCode).second ;
828
830
handleMergeWriterError (make_error<InstrProfError>(ErrCode, Msg),
829
- Input.Filename , FuncName, FirstTime );
831
+ Input.Filename , FuncName, firstTime );
830
832
});
831
833
}
832
834
833
835
if (KeepVTableSymbols) {
834
- const InstrProfSymtab &Symtab = Reader->getSymtab ();
835
- const auto &VTableNames = Symtab .getVTableNames ();
836
+ const InstrProfSymtab &symtab = Reader->getSymtab ();
837
+ const auto &VTableNames = symtab .getVTableNames ();
836
838
837
- for (const auto &KV : VTableNames)
838
- WC->Writer .addVTableName (KV .getKey ());
839
+ for (const auto &kv : VTableNames)
840
+ WC->Writer .addVTableName (kv .getKey ());
839
841
}
840
842
841
843
if (Reader->hasTemporalProfile ()) {
@@ -876,8 +878,8 @@ static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) {
876
878
Dst->Writer .mergeRecordsFromWriter (std::move (Src->Writer ), [&](Error E) {
877
879
auto [ErrorCode, Msg] = InstrProfError::take (std::move (E));
878
880
std::unique_lock<std::mutex> ErrGuard{Dst->ErrLock };
879
- bool FirstTime = Dst->WriterErrorCodes .insert (ErrorCode).second ;
880
- if (FirstTime )
881
+ bool firstTime = Dst->WriterErrorCodes .insert (ErrorCode).second ;
882
+ if (firstTime )
881
883
warn (toString (make_error<InstrProfError>(ErrorCode, Msg)));
882
884
});
883
885
}
@@ -887,32 +889,34 @@ getFuncName(const StringMap<InstrProfWriter::ProfilingData>::value_type &Val) {
887
889
return Val.first ();
888
890
}
889
891
890
- static std::string getFuncName (const SampleProfileMap::value_type &Val) {
892
+ static std::string
893
+ getFuncName (const SampleProfileMap::value_type &Val) {
891
894
return Val.second .getContext ().toString ();
892
895
}
893
896
894
- template <typename T> static void filterFunctions (T &ProfileMap) {
895
- bool HasFilter = !FuncNameFilter.empty ();
896
- bool HasNegativeFilter = !FuncNameNegativeFilter.empty ();
897
- if (!HasFilter && !HasNegativeFilter)
897
+ template <typename T>
898
+ static void filterFunctions (T &ProfileMap) {
899
+ bool hasFilter = !FuncNameFilter.empty ();
900
+ bool hasNegativeFilter = !FuncNameNegativeFilter.empty ();
901
+ if (!hasFilter && !hasNegativeFilter)
898
902
return ;
899
903
900
904
// If filter starts with '?' it is MSVC mangled name, not a regex.
901
905
llvm::Regex ProbablyMSVCMangledName (" [?@$_0-9A-Za-z]+" );
902
- if (HasFilter && FuncNameFilter[0 ] == ' ?' &&
906
+ if (hasFilter && FuncNameFilter[0 ] == ' ?' &&
903
907
ProbablyMSVCMangledName.match (FuncNameFilter))
904
908
FuncNameFilter = llvm::Regex::escape (FuncNameFilter);
905
- if (HasNegativeFilter && FuncNameNegativeFilter[0 ] == ' ?' &&
909
+ if (hasNegativeFilter && FuncNameNegativeFilter[0 ] == ' ?' &&
906
910
ProbablyMSVCMangledName.match (FuncNameNegativeFilter))
907
911
FuncNameNegativeFilter = llvm::Regex::escape (FuncNameNegativeFilter);
908
912
909
913
size_t Count = ProfileMap.size ();
910
914
llvm::Regex Pattern (FuncNameFilter);
911
915
llvm::Regex NegativePattern (FuncNameNegativeFilter);
912
916
std::string Error;
913
- if (HasFilter && !Pattern.isValid (Error))
917
+ if (hasFilter && !Pattern.isValid (Error))
914
918
exitWithError (Error);
915
- if (HasNegativeFilter && !NegativePattern.isValid (Error))
919
+ if (hasNegativeFilter && !NegativePattern.isValid (Error))
916
920
exitWithError (Error);
917
921
918
922
// Handle MD5 profile, so it is still able to match using the original name.
@@ -924,10 +928,10 @@ template <typename T> static void filterFunctions(T &ProfileMap) {
924
928
auto Tmp = I++;
925
929
const auto &FuncName = getFuncName (*Tmp);
926
930
// Negative filter has higher precedence than positive filter.
927
- if ((HasNegativeFilter &&
931
+ if ((hasNegativeFilter &&
928
932
(NegativePattern.match (FuncName) ||
929
933
(FunctionSamples::UseMD5 && NegativeMD5Name == FuncName))) ||
930
- (HasFilter && !(Pattern.match (FuncName) ||
934
+ (hasFilter && !(Pattern.match (FuncName) ||
931
935
(FunctionSamples::UseMD5 && MD5Name == FuncName))))
932
936
ProfileMap.erase (Tmp);
933
937
}
@@ -1188,7 +1192,7 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
1188
1192
StringMap<StringRef> StaticFuncMap;
1189
1193
InstrProfSummaryBuilder IPBuilder (ProfileSummaryBuilder::DefaultCutoffs);
1190
1194
1191
- auto CheckSampleProfileHasFUnique = [&Reader]() {
1195
+ auto checkSampleProfileHasFUnique = [&Reader]() {
1192
1196
for (const auto &PD : Reader->getProfiles ()) {
1193
1197
auto &FContext = PD.second .getContext ();
1194
1198
if (FContext.toString ().find (FunctionSamples::UniqSuffix) !=
@@ -1199,9 +1203,9 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
1199
1203
return false ;
1200
1204
};
1201
1205
1202
- bool SampleProfileHasFUnique = CheckSampleProfileHasFUnique ();
1206
+ bool SampleProfileHasFUnique = checkSampleProfileHasFUnique ();
1203
1207
1204
- auto BuildStaticFuncMap = [&StaticFuncMap,
1208
+ auto buildStaticFuncMap = [&StaticFuncMap,
1205
1209
SampleProfileHasFUnique](const StringRef Name) {
1206
1210
std::string FilePrefixes[] = {" .cpp" , " cc" , " .c" , " .hpp" , " .h" };
1207
1211
size_t PrefixPos = StringRef::npos;
@@ -1361,7 +1365,7 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
1361
1365
InstrProfRecord *R = &PD.getValue ().begin ()->second ;
1362
1366
StringRef FullName = PD.getKey ();
1363
1367
InstrProfileMap[FullName] = InstrProfileEntry (R);
1364
- BuildStaticFuncMap (FullName);
1368
+ buildStaticFuncMap (FullName);
1365
1369
}
1366
1370
1367
1371
for (auto &PD : Reader->getProfiles ()) {
@@ -1492,8 +1496,8 @@ remapSamples(const sampleprof::FunctionSamples &Samples,
1492
1496
BodySample.second .getSamples ());
1493
1497
for (const auto &Target : BodySample.second .getCallTargets ()) {
1494
1498
Result.addCalledTargetSamples (BodySample.first .LineOffset ,
1495
- MaskedDiscriminator, Remapper (Target. first ),
1496
- Target.second );
1499
+ MaskedDiscriminator,
1500
+ Remapper (Target. first ), Target.second );
1497
1501
}
1498
1502
}
1499
1503
for (const auto &CallsiteSamples : Samples.getCallsiteSamples ()) {
@@ -1754,7 +1758,7 @@ static void parseInputFilenamesFile(MemoryBuffer *Buffer,
1754
1758
if (SanitizedEntry.starts_with (" #" ))
1755
1759
continue ;
1756
1760
// If there's no comma, it's an unweighted profile.
1757
- if (!SanitizedEntry.contains (' ,' ))
1761
+ else if (!SanitizedEntry.contains (' ,' ))
1758
1762
addWeightedInput (WFV, {std::string (SanitizedEntry), 1 });
1759
1763
else
1760
1764
addWeightedInput (WFV, parseWeightedFile (SanitizedEntry));
@@ -2735,11 +2739,10 @@ std::error_code SampleOverlapAggregator::loadProfiles() {
2735
2739
return std::error_code ();
2736
2740
}
2737
2741
2738
- static void overlapSampleProfile (const std::string &BaseFilename,
2739
- const std::string &TestFilename,
2740
- const OverlapFuncFilters &FuncFilter,
2741
- uint64_t SimilarityCutoff,
2742
- raw_fd_ostream &OS) {
2742
+ void overlapSampleProfile (const std::string &BaseFilename,
2743
+ const std::string &TestFilename,
2744
+ const OverlapFuncFilters &FuncFilter,
2745
+ uint64_t SimilarityCutoff, raw_fd_ostream &OS) {
2743
2746
using namespace sampleprof ;
2744
2747
2745
2748
// We use 0.000005 to initialize OverlapAggr.Epsilon because the final metrics
@@ -2870,15 +2873,17 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
2870
2873
OS << " :ir\n " ;
2871
2874
2872
2875
for (const auto &Func : *Reader) {
2873
- if (IsIRInstr ) {
2876
+ if (Reader-> isIRLevelProfile () ) {
2874
2877
bool FuncIsCS = NamedInstrProfRecord::hasCSFlagInHash (Func.Hash );
2875
2878
if (FuncIsCS != ShowCS)
2876
2879
continue ;
2877
2880
}
2878
2881
bool Show = ShowAllFunctions ||
2879
2882
(!FuncNameFilter.empty () && Func.Name .contains (FuncNameFilter));
2880
2883
2881
- if (Show && TextFormat) {
2884
+ bool doTextFormatDump = (Show && TextFormat);
2885
+
2886
+ if (doTextFormatDump) {
2882
2887
InstrProfSymtab &Symtab = Reader->getSymtab ();
2883
2888
InstrProfWriter::writeRecordInText (Func.Name , Func.Hash , Func, Symtab,
2884
2889
OS);
@@ -2916,9 +2921,9 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
2916
2921
continue ;
2917
2922
}
2918
2923
2919
- for (const auto &Count : Func.Counts ) {
2920
- FuncMax = std::max (FuncMax, Count );
2921
- FuncSum += Count ;
2924
+ for (size_t I = 0 , E = Func.Counts . size (); I < E; ++I ) {
2925
+ FuncMax = std::max (FuncMax, Func. Counts [I] );
2926
+ FuncSum += Func. Counts [I] ;
2922
2927
}
2923
2928
2924
2929
if (FuncMax < ShowValueCutoff) {
@@ -2928,8 +2933,7 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
2928
2933
<< " Sum = " << FuncSum << " )\n " ;
2929
2934
}
2930
2935
continue ;
2931
- }
2932
- if (OnlyListBelow)
2936
+ } else if (OnlyListBelow)
2933
2937
continue ;
2934
2938
2935
2939
if (TopNFunctions || ShowHotFuncList)
@@ -2996,8 +3000,9 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
2996
3000
if (TextFormat || ShowCovered)
2997
3001
return 0 ;
2998
3002
std::unique_ptr<ProfileSummary> PS (Builder.getSummary ());
2999
- OS << " Instrumentation level: " << (IsIRInstr ? " IR" : " Front-end" );
3000
- if (IsIRInstr) {
3003
+ bool IsIR = Reader->isIRLevelProfile ();
3004
+ OS << " Instrumentation level: " << (IsIR ? " IR" : " Front-end" );
3005
+ if (IsIR) {
3001
3006
OS << " entry_first = " << Reader->instrEntryBBEnabled ();
3002
3007
OS << " instrument_loop_entries = " << Reader->instrLoopEntriesEnabled ();
3003
3008
}
@@ -3065,10 +3070,10 @@ static int showInstrProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
3065
3070
auto &Traces = Reader->getTemporalProfTraces ();
3066
3071
OS << " Temporal Profile Traces (samples=" << Traces.size ()
3067
3072
<< " seen=" << Reader->getTemporalProfTraceStreamSize () << " ):\n " ;
3068
- for (auto [Index, Trace] : llvm::enumerate ( Traces) ) {
3069
- OS << " Temporal Profile Trace " << Index << " (weight=" << Trace .Weight
3070
- << " count=" << Trace .FunctionNameRefs .size () << " ):\n " ;
3071
- for (auto &NameRef : Trace .FunctionNameRefs )
3073
+ for (unsigned i = 0 ; i < Traces. size (); i++ ) {
3074
+ OS << " Temporal Profile Trace " << i << " (weight=" << Traces[i] .Weight
3075
+ << " count=" << Traces[i] .FunctionNameRefs .size () << " ):\n " ;
3076
+ for (auto &NameRef : Traces[i] .FunctionNameRefs )
3072
3077
OS << " " << Reader->getSymtab ().getFuncOrVarName (NameRef) << " \n " ;
3073
3078
}
3074
3079
}
@@ -3381,8 +3386,7 @@ static int show_main(StringRef ProgName) {
3381
3386
exitWithErrorCode (EC, OutputFilename);
3382
3387
3383
3388
if (ShowAllFunctions && !FuncNameFilter.empty ())
3384
- WithColor::warning ()
3385
- << " -function argument ignored: showing all functions\n " ;
3389
+ WithColor::warning () << " -function argument ignored: showing all functions\n " ;
3386
3390
3387
3391
if (!DebugInfoFilename.empty ())
3388
3392
return showDebugInfoCorrelation (DebugInfoFilename, SFormat, OS);
0 commit comments