Skip to content

Commit 0a2a94a

Browse files
committed
switch to full heatmap mode
Created using spr 1.3.4
2 parents 2f82cc9 + e65259b commit 0a2a94a

File tree

13 files changed

+71
-72
lines changed

13 files changed

+71
-72
lines changed

bolt/include/bolt/Utils/CommandLineOpts.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717

1818
namespace opts {
1919

20-
extern bool HeatmapMode;
20+
enum HeatmapModeKind {
21+
HM_None = 0,
22+
HM_Exclusive, // llvm-bolt-heatmap
23+
HM_Optional // perf2bolt --heatmap
24+
};
25+
26+
extern HeatmapModeKind HeatmapMode;
2127
extern bool BinaryAnalysisMode;
2228

2329
extern llvm::cl::OptionCategory BoltCategory;
@@ -45,7 +51,7 @@ extern llvm::cl::opt<unsigned> HeatmapBlock;
4551
extern llvm::cl::opt<unsigned long long> HeatmapMaxAddress;
4652
extern llvm::cl::opt<unsigned long long> HeatmapMinAddress;
4753
extern llvm::cl::opt<bool> HeatmapPrintMappings;
48-
extern llvm::cl::opt<bool> HeatmapStats;
54+
extern llvm::cl::opt<std::string> HeatmapOutput;
4955
extern llvm::cl::opt<bool> HotData;
5056
extern llvm::cl::opt<bool> HotFunctionsAtEnd;
5157
extern llvm::cl::opt<bool> HotText;

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extern cl::opt<bool> UpdateDebugSections;
6666
extern cl::opt<unsigned> Verbosity;
6767

6868
extern bool BinaryAnalysisMode;
69-
extern bool HeatmapMode;
69+
extern HeatmapModeKind HeatmapMode;
7070
extern bool processAllFunctions();
7171

7272
static cl::opt<bool> CheckEncoding(

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ void DataAggregator::findPerfExecutable() {
164164
void DataAggregator::start() {
165165
outs() << "PERF2BOLT: Starting data aggregation job for " << Filename << "\n";
166166

167-
// Turn on heatmap building if requested by --print-heatmap-stats flag.
168-
if (opts::HeatmapStats)
169-
opts::HeatmapMode = true;
167+
// Turn on heatmap building if requested by --heatmap flag.
168+
if (!opts::HeatmapMode && opts::HeatmapOutput.getNumOccurrences())
169+
opts::HeatmapMode = opts::HeatmapModeKind::HM_Optional;
170170

171171
// Don't launch perf for pre-aggregated files or when perf input is specified
172172
// by the user.
@@ -520,9 +520,10 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
520520
if (std::error_code EC = printLBRHeatMap())
521521
return errorCodeToError(EC);
522522

523-
if (opts::HeatmapStats)
523+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Optional)
524524
return Error::success();
525525

526+
assert(opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive);
526527
exit(0);
527528
}
528529

@@ -1216,8 +1217,8 @@ std::error_code DataAggregator::parseAggregatedLBREntry() {
12161217
ErrorOr<StringRef> TypeOrErr = parseString(FieldSeparator);
12171218
if (std::error_code EC = TypeOrErr.getError())
12181219
return EC;
1219-
enum TType { TRACE, BRANCH, FT, FT_EXTERNAL_ORIGIN, INVALID };
1220-
auto Type = StringSwitch<TType>(TypeOrErr.get())
1220+
enum AggregatedLBREntry { TRACE, BRANCH, FT, FT_EXTERNAL_ORIGIN, INVALID };
1221+
auto Type = StringSwitch<AggregatedLBREntry>(TypeOrErr.get())
12211222
.Case("T", TRACE)
12221223
.Case("B", BRANCH)
12231224
.Case("F", FT)
@@ -1241,7 +1242,7 @@ std::error_code DataAggregator::parseAggregatedLBREntry() {
12411242
return EC;
12421243

12431244
ErrorOr<Location> TraceFtEnd = std::error_code();
1244-
if (Type == TRACE) {
1245+
if (Type == AggregatedLBREntry::TRACE) {
12451246
while (checkAndConsumeFS()) {
12461247
}
12471248
TraceFtEnd = parseLocationOrOffset();
@@ -1251,12 +1252,13 @@ std::error_code DataAggregator::parseAggregatedLBREntry() {
12511252

12521253
while (checkAndConsumeFS()) {
12531254
}
1254-
ErrorOr<int64_t> Frequency = parseNumberField(FieldSeparator, Type != BRANCH);
1255+
ErrorOr<int64_t> Frequency =
1256+
parseNumberField(FieldSeparator, Type != AggregatedLBREntry::BRANCH);
12551257
if (std::error_code EC = Frequency.getError())
12561258
return EC;
12571259

12581260
uint64_t Mispreds = 0;
1259-
if (Type == BRANCH) {
1261+
if (Type == AggregatedLBREntry::BRANCH) {
12601262
while (checkAndConsumeFS()) {
12611263
}
12621264
ErrorOr<int64_t> MispredsOrErr = parseNumberField(FieldSeparator, true);
@@ -1354,19 +1356,14 @@ std::error_code DataAggregator::printLBRHeatMap() {
13541356
exit(1);
13551357
}
13561358

1357-
if (opts::HeatmapStats) {
1358-
HM.printSectionHotness(outs());
1359-
return std::error_code();
1359+
HM.print(opts::HeatmapOutput);
1360+
if (opts::HeatmapOutput == "-") {
1361+
HM.printCDF(opts::HeatmapOutput);
1362+
HM.printSectionHotness(opts::HeatmapOutput);
1363+
} else {
1364+
HM.printCDF(opts::HeatmapOutput + ".csv");
1365+
HM.printSectionHotness(opts::HeatmapOutput + "-section-hotness.csv");
13601366
}
1361-
HM.print(opts::OutputFilename);
1362-
if (opts::OutputFilename == "-")
1363-
HM.printCDF(opts::OutputFilename);
1364-
else
1365-
HM.printCDF(opts::OutputFilename + ".csv");
1366-
if (opts::OutputFilename == "-")
1367-
HM.printSectionHotness(opts::OutputFilename);
1368-
else
1369-
HM.printSectionHotness(opts::OutputFilename + "-section-hotness.csv");
13701367

13711368
return std::error_code();
13721369
}
@@ -1393,7 +1390,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
13931390
const uint64_t TraceTo = NextLBR->From;
13941391
const BinaryFunction *TraceBF =
13951392
getBinaryFunctionContainingAddress(TraceFrom);
1396-
if (opts::HeatmapMode) {
1393+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
13971394
FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)];
13981395
++Info.InternCount;
13991396
} else if (TraceBF && TraceBF->containsAddress(TraceTo)) {
@@ -1431,7 +1428,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14311428
NextLBR = &LBR;
14321429

14331430
// Record branches outside binary functions for heatmap.
1434-
if (opts::HeatmapMode) {
1431+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
14351432
TakenBranchInfo &Info = BranchLBRs[Trace(LBR.From, LBR.To)];
14361433
++Info.TakenCount;
14371434
continue;
@@ -1446,7 +1443,8 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14461443
}
14471444
// Record LBR addresses not covered by fallthroughs (bottom-of-stack source
14481445
// and top-of-stack target) as basic samples for heatmap.
1449-
if (opts::HeatmapMode && !Sample.LBR.empty()) {
1446+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive &&
1447+
!Sample.LBR.empty()) {
14501448
++BasicSamples[Sample.LBR.front().To];
14511449
++BasicSamples[Sample.LBR.back().From];
14521450
}

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,8 @@ void RewriteInstance::updateRtFiniReloc() {
14531453
}
14541454

14551455
void RewriteInstance::registerFragments() {
1456-
if (!BC->HasSplitFunctions || opts::HeatmapMode)
1456+
if (!BC->HasSplitFunctions ||
1457+
opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive)
14571458
return;
14581459

14591460
// Process fragments with ambiguous parents separately as they are typically a
@@ -1997,10 +1998,13 @@ Error RewriteInstance::readSpecialSections() {
19971998
if (ErrorOr<BinarySection &> BATSec =
19981999
BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) {
19992000
BC->HasBATSection = true;
2000-
if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) {
2001-
BC->errs() << "BOLT-ERROR: failed to parse BOLT address translation "
2002-
"table.\n";
2003-
exit(1);
2001+
// Do not read BAT when plotting a heatmap
2002+
if (opts::HeatmapMode != opts::HeatmapModeKind::HM_Exclusive) {
2003+
if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) {
2004+
BC->errs() << "BOLT-ERROR: failed to parse BOLT address translation "
2005+
"table.\n";
2006+
exit(1);
2007+
}
20042008
}
20052009
}
20062010

@@ -2034,7 +2038,7 @@ Error RewriteInstance::readSpecialSections() {
20342038
}
20352039

20362040
// Force non-relocation mode for heatmap generation
2037-
if (opts::HeatmapMode)
2041+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive)
20382042
BC->HasRelocations = false;
20392043

20402044
if (BC->HasRelocations)

bolt/lib/Utils/CommandLineOpts.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const char *BoltRevision =
2828

2929
namespace opts {
3030

31-
bool HeatmapMode = false;
31+
HeatmapModeKind HeatmapMode = HM_None;
3232
bool BinaryAnalysisMode = false;
3333

3434
cl::OptionCategory BoltCategory("BOLT generic options");
@@ -124,10 +124,9 @@ cl::opt<bool> HeatmapPrintMappings(
124124
"sections (default false)"),
125125
cl::Optional, cl::cat(HeatmapCategory));
126126

127-
cl::opt<bool> HeatmapStats(
128-
"print-heatmap-stats",
129-
cl::desc("print heatmap statistics without producing the heatmap"),
130-
cl::Optional, cl::cat(HeatmapCategory));
127+
cl::opt<std::string> HeatmapOutput("heatmap",
128+
cl::desc("print heatmap to a given file"),
129+
cl::Optional, cl::cat(HeatmapCategory));
131130

132131
cl::opt<bool> HotData("hot-data",
133132
cl::desc("hot data symbols support (relocation mode)"),

bolt/test/X86/bolt-address-translation-yaml.test

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ ORDER-YAML-CHECK-NEXT: calls: [ { off: 0x26, fid: [[#]], cnt: 20 } ]
2828
ORDER-YAML-CHECK-NEXT: succ: [ { bid: 5, cnt: 7 }
2929
## Large profile test
3030
RUN: perf2bolt %t.out --pa -p %p/Inputs/blarge_new_bat.preagg.txt -w %t.yaml -o %t.fdata \
31-
RUN: --print-heatmap-stats 2>&1 | FileCheck --check-prefix READ-BAT-CHECK %s
31+
RUN: --heatmap %t.hm 2>&1 | FileCheck --check-prefix READ-BAT-CHECK %s
3232
RUN: FileCheck --input-file %t.yaml --check-prefix YAML-BAT-CHECK %s
33+
RUN: FileCheck --input-file %t.hm-section-hotness.csv --check-prefix CHECK-HM %s
3334
## Check that YAML converted from fdata matches YAML created directly with BAT.
3435
RUN: llvm-bolt %t.exe -data %t.fdata -w %t.yaml-fdata -o /dev/null \
3536
RUN: 2>&1 | FileCheck --check-prefix READ-BAT-FDATA-CHECK %s
@@ -47,9 +48,9 @@ READ-BAT-CHECK-NOT: BOLT-ERROR: unable to save profile in YAML format for input
4748
READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries
4849
READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries
4950
READ-BAT-CHECK: HEATMAP: building heat map
50-
READ-BAT-CHECK: .text, 0x800000, 0x8002cc, 38.7595, 91.6667, 0.3553
5151
READ-BAT-CHECK: BOLT-INFO: 5 out of 21 functions in the binary (23.8%) have non-empty execution profile
5252
READ-BAT-FDATA-CHECK: BOLT-INFO: 5 out of 16 functions in the binary (31.2%) have non-empty execution profile
53+
CHECK-HM: .text, 0x800000, 0x8002cc, 38.7595, 91.6667, 0.3553
5354

5455
YAML-BAT-CHECK: functions:
5556
# Function not covered by BAT - has insns in basic block

bolt/test/X86/pre-aggregated-perf.test

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ REQUIRES: system-linux
1111

1212
RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe
1313
RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \
14-
RUN: --show-density --print-heatmap-stats \
14+
RUN: --show-density --heatmap %t.hm \
1515
RUN: --profile-density-threshold=9 --profile-density-cutoff-hot=970000 \
1616
RUN: --profile-use-dfs | FileCheck %s --check-prefix=CHECK-P2B
17+
RUN: FileCheck --input-file %t.hm-section-hotness.csv --check-prefix=CHECK-HM %s
1718

1819
CHECK-P2B: HEATMAP: building heat map
19-
CHECK-P2B: .text, 0x400680, 0x401232, 100.0000, 4.2553, 0.0426
2020
CHECK-P2B: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile
2121
CHECK-P2B: BOLT-INFO: Functions with density >= 21.7 account for 97.00% total sample counts.
22+
CHECK-HM: .text, 0x400680, 0x401232, 100.0000, 4.2553, 0.0426
2223

2324
RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \
2425
RUN: --show-density \

bolt/test/perf2bolt/perf_test.test

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@ REQUIRES: system-linux, perf
44

55
RUN: %clang %S/Inputs/perf_test.c -fuse-ld=lld -Wl,--script=%S/Inputs/perf_test.lds -o %t
66
RUN: perf record -Fmax -e cycles:u -o %t2 -- %t
7-
RUN: perf2bolt %t -p=%t2 -o %t3 -nl -ignore-build-id --print-heatmap-stats \
7+
RUN: perf2bolt %t -p=%t2 -o %t3 -nl -ignore-build-id --heatmap %t.hm \
88
RUN: 2>&1 | FileCheck %s
9+
RUN: FileCheck %s --input-file %t.hm-section-hotness.csv --check-prefix=CHECK-HM
910

1011
CHECK-NOT: PERF2BOLT-ERROR
1112
CHECK-NOT: !! WARNING !! This high mismatch ratio indicates the input binary is probably not the same binary used during profiling collection.
1213
CHECK: HEATMAP: building heat map
13-
CHECK-NEXT: Section Name, Begin Address, End Address, Percentage Hotness, Utilization Pct, Partition Score
1414
CHECK: BOLT-INFO: Functions with density >= {{.*}} account for 99.00% total sample counts.
1515

1616
RUN: %clang %S/Inputs/perf_test.c -no-pie -fuse-ld=lld -o %t4
1717
RUN: perf record -Fmax -e cycles:u -o %t5 -- %t4
18-
RUN: perf2bolt %t4 -p=%t5 -o %t6 -nl -ignore-build-id --print-heatmap-stats \
18+
RUN: perf2bolt %t4 -p=%t5 -o %t6 -nl -ignore-build-id --heatmap %t.hm2 \
1919
RUN: 2>&1 | FileCheck %s
20+
RUN: FileCheck %s --input-file %t.hm2-section-hotness.csv --check-prefix=CHECK-HM
21+
22+
CHECK-HM: .text

bolt/tools/heatmap/heatmap.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ int main(int argc, char **argv) {
6666
exit(1);
6767
}
6868

69-
opts::HeatmapMode = true;
69+
opts::HeatmapMode = opts::HM_Exclusive;
7070
opts::AggregateOnly = true;
7171
if (!sys::fs::exists(opts::InputFilename))
7272
report_error(opts::InputFilename, errc::no_such_file_or_directory);
7373

7474
// Output to stdout by default
7575
if (opts::OutputFilename.empty())
7676
opts::OutputFilename = "-";
77+
opts::HeatmapOutput.assign(opts::OutputFilename);
7778

7879
// Initialize targets and assembly printers/parsers.
7980
#define BOLT_TARGET(target) \

clang-tools-extra/modularize/Modularize.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,8 @@ struct Location {
406406
}
407407

408408
friend bool operator<(const Location &X, const Location &Y) {
409-
if (X.File != Y.File)
410-
return X.File < Y.File;
411-
if (X.Line != Y.Line)
412-
return X.Line < Y.Line;
413-
return X.Column < Y.Column;
409+
return std::tie(X.File, X.Line, X.Column) <
410+
std::tie(Y.File, Y.Line, Y.Column);
414411
}
415412
friend bool operator>(const Location &X, const Location &Y) { return Y < X; }
416413
friend bool operator<=(const Location &X, const Location &Y) {

0 commit comments

Comments
 (0)