Skip to content

Commit e4dba98

Browse files
authored
Merge branch 'main' into fix-up-for-vop3p-gisel
2 parents be9ac55 + c533127 commit e4dba98

File tree

631 files changed

+671886
-202904
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

631 files changed

+671886
-202904
lines changed

.github/workflows/containers/github-action-ci-windows/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ RUN choco install -y handle
108108
109109
RUN pip3 install pywin32 buildbot-worker==2.8.4
110110
111-
ARG RUNNER_VERSION=2.323.0
111+
ARG RUNNER_VERSION=2.324.0
112112
ENV RUNNER_VERSION=$RUNNER_VERSION
113113
114114
RUN powershell -Command \

.github/workflows/containers/github-action-ci/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM docker.io/library/ubuntu:24.04 as base
22
ENV LLVM_SYSROOT=/opt/llvm
33

44
FROM base as stage1-toolchain
5-
ENV LLVM_VERSION=20.1.1
5+
ENV LLVM_VERSION=20.1.4
66

77
RUN apt-get update && \
88
apt-get install -y \
@@ -86,7 +86,7 @@ WORKDIR /home/gha
8686

8787
FROM ci-container as ci-container-agent
8888

89-
ENV GITHUB_RUNNER_VERSION=2.323.0
89+
ENV GITHUB_RUNNER_VERSION=2.324.0
9090

9191
RUN mkdir actions-runner && \
9292
cd actions-runner && \

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,6 @@ class DataAggregator : public DataReader {
212212
uint64_t NumTraces{0};
213213
uint64_t NumInvalidTraces{0};
214214
uint64_t NumLongRangeTraces{0};
215-
/// Specifies how many samples were recorded in cold areas if we are dealing
216-
/// with profiling data collected in a bolted binary. For LBRs, incremented
217-
/// for the source of the branch to avoid counting cold activity twice (one
218-
/// for source and another for destination).
219-
uint64_t NumColdSamples{0};
220215
uint64_t NumTotalSamples{0};
221216

222217
/// Looks into system PATH for Linux Perf and set up the aggregator to use it
@@ -473,7 +468,6 @@ class DataAggregator : public DataReader {
473468
void dump(const PerfMemSample &Sample) const;
474469

475470
/// Profile diagnostics print methods
476-
void printColdSamplesDiagnostic() const;
477471
void printLongRangeTracesDiagnostic() const;
478472
void printBranchSamplesDiagnostics() const;
479473
void printBasicSamplesDiagnostics(uint64_t OutOfRangeSamples) const;

bolt/include/bolt/Utils/CommandLineOpts.h

Lines changed: 8 additions & 1 deletion
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,6 +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;
54+
extern llvm::cl::opt<std::string> HeatmapOutput;
4855
extern llvm::cl::opt<bool> HotData;
4956
extern llvm::cl::opt<bool> HotFunctionsAtEnd;
5057
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: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ 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 --heatmap flag.
168+
if (!opts::HeatmapMode && opts::HeatmapOutput.getNumOccurrences())
169+
opts::HeatmapMode = opts::HeatmapModeKind::HM_Optional;
170+
167171
// Don't launch perf for pre-aggregated files or when perf input is specified
168172
// by the user.
169173
if (opts::ReadPreAggregated || !opts::ReadPerfEvents.empty())
@@ -502,24 +506,25 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
502506
errs() << "PERF2BOLT: failed to parse samples\n";
503507

504508
// Special handling for memory events
505-
if (prepareToParse("mem events", MemEventsPPI, MemEventsErrorCallback))
506-
return Error::success();
507-
508-
if (const std::error_code EC = parseMemEvents())
509-
errs() << "PERF2BOLT: failed to parse memory events: " << EC.message()
510-
<< '\n';
509+
if (!prepareToParse("mem events", MemEventsPPI, MemEventsErrorCallback))
510+
if (const std::error_code EC = parseMemEvents())
511+
errs() << "PERF2BOLT: failed to parse memory events: " << EC.message()
512+
<< '\n';
511513

512514
deleteTempFiles();
513515

514516
heatmap:
515-
if (opts::HeatmapMode) {
516-
if (std::error_code EC = printLBRHeatMap()) {
517-
errs() << "ERROR: failed to print heat map: " << EC.message() << '\n';
518-
exit(1);
519-
}
520-
exit(0);
521-
}
522-
return Error::success();
517+
if (!opts::HeatmapMode)
518+
return Error::success();
519+
520+
if (std::error_code EC = printLBRHeatMap())
521+
return errorCodeToError(EC);
522+
523+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Optional)
524+
return Error::success();
525+
526+
assert(opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive);
527+
exit(0);
523528
}
524529

525530
Error DataAggregator::readProfile(BinaryContext &BC) {
@@ -635,8 +640,6 @@ bool DataAggregator::doBasicSample(BinaryFunction &OrigFunc, uint64_t Address,
635640

636641
BinaryFunction *ParentFunc = getBATParentFunction(OrigFunc);
637642
BinaryFunction &Func = ParentFunc ? *ParentFunc : OrigFunc;
638-
if (ParentFunc || (BAT && !BAT->isBATFunction(Func.getAddress())))
639-
NumColdSamples += Count;
640643
// Attach executed bytes to parent function in case of cold fragment.
641644
Func.SampleCountInBytes += Count * BlockSize;
642645

@@ -740,15 +743,10 @@ bool DataAggregator::doBranch(uint64_t From, uint64_t To, uint64_t Count,
740743
if (BAT)
741744
Addr = BAT->translate(Func->getAddress(), Addr, IsFrom);
742745

743-
BinaryFunction *ParentFunc = getBATParentFunction(*Func);
744-
if (IsFrom &&
745-
(ParentFunc || (BAT && !BAT->isBATFunction(Func->getAddress()))))
746-
NumColdSamples += Count;
747-
748-
if (!ParentFunc)
749-
return std::pair{Func, IsRet};
746+
if (BinaryFunction *ParentFunc = getBATParentFunction(*Func))
747+
Func = ParentFunc;
750748

751-
return std::pair{ParentFunc, IsRet};
749+
return std::pair{Func, IsRet};
752750
};
753751

754752
auto [FromFunc, IsReturn] = handleAddress(From, /*IsFrom*/ true);
@@ -1351,15 +1349,14 @@ std::error_code DataAggregator::printLBRHeatMap() {
13511349
exit(1);
13521350
}
13531351

1354-
HM.print(opts::OutputFilename);
1355-
if (opts::OutputFilename == "-")
1356-
HM.printCDF(opts::OutputFilename);
1357-
else
1358-
HM.printCDF(opts::OutputFilename + ".csv");
1359-
if (opts::OutputFilename == "-")
1360-
HM.printSectionHotness(opts::OutputFilename);
1361-
else
1362-
HM.printSectionHotness(opts::OutputFilename + "-section-hotness.csv");
1352+
HM.print(opts::HeatmapOutput);
1353+
if (opts::HeatmapOutput == "-") {
1354+
HM.printCDF(opts::HeatmapOutput);
1355+
HM.printSectionHotness(opts::HeatmapOutput);
1356+
} else {
1357+
HM.printCDF(opts::HeatmapOutput + ".csv");
1358+
HM.printSectionHotness(opts::HeatmapOutput + "-section-hotness.csv");
1359+
}
13631360

13641361
return std::error_code();
13651362
}
@@ -1386,7 +1383,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
13861383
const uint64_t TraceTo = NextLBR->From;
13871384
const BinaryFunction *TraceBF =
13881385
getBinaryFunctionContainingAddress(TraceFrom);
1389-
if (opts::HeatmapMode) {
1386+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
13901387
FTInfo &Info = FallthroughLBRs[Trace(TraceFrom, TraceTo)];
13911388
++Info.InternCount;
13921389
} else if (TraceBF && TraceBF->containsAddress(TraceTo)) {
@@ -1424,7 +1421,7 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14241421
NextLBR = &LBR;
14251422

14261423
// Record branches outside binary functions for heatmap.
1427-
if (opts::HeatmapMode) {
1424+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive) {
14281425
TakenBranchInfo &Info = BranchLBRs[Trace(LBR.From, LBR.To)];
14291426
++Info.TakenCount;
14301427
continue;
@@ -1439,26 +1436,13 @@ void DataAggregator::parseLBRSample(const PerfBranchSample &Sample,
14391436
}
14401437
// Record LBR addresses not covered by fallthroughs (bottom-of-stack source
14411438
// and top-of-stack target) as basic samples for heatmap.
1442-
if (opts::HeatmapMode && !Sample.LBR.empty()) {
1439+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive &&
1440+
!Sample.LBR.empty()) {
14431441
++BasicSamples[Sample.LBR.front().To];
14441442
++BasicSamples[Sample.LBR.back().From];
14451443
}
14461444
}
14471445

1448-
void DataAggregator::printColdSamplesDiagnostic() const {
1449-
if (NumColdSamples > 0) {
1450-
const float ColdSamples = NumColdSamples * 100.0f / NumTotalSamples;
1451-
outs() << "PERF2BOLT: " << NumColdSamples
1452-
<< format(" (%.1f%%)", ColdSamples)
1453-
<< " samples recorded in cold regions of split functions.\n";
1454-
if (ColdSamples > 5.0f)
1455-
outs()
1456-
<< "WARNING: The BOLT-processed binary where samples were collected "
1457-
"likely used bad data or your service observed a large shift in "
1458-
"profile. You may want to audit this\n";
1459-
}
1460-
}
1461-
14621446
void DataAggregator::printLongRangeTracesDiagnostic() const {
14631447
outs() << "PERF2BOLT: out of range traces involving unknown regions: "
14641448
<< NumLongRangeTraces;
@@ -1499,7 +1483,6 @@ void DataAggregator::printBranchSamplesDiagnostics() const {
14991483
"collection. The generated data may be ineffective for improving "
15001484
"performance\n\n";
15011485
printLongRangeTracesDiagnostic();
1502-
printColdSamplesDiagnostic();
15031486
}
15041487

15051488
void DataAggregator::printBasicSamplesDiagnostics(
@@ -1511,7 +1494,6 @@ void DataAggregator::printBasicSamplesDiagnostics(
15111494
"binary is probably not the same binary used during profiling "
15121495
"collection. The generated data may be ineffective for improving "
15131496
"performance\n\n";
1514-
printColdSamplesDiagnostic();
15151497
}
15161498

15171499
void DataAggregator::printBranchStacksDiagnostics(

bolt/lib/Profile/Heatmap.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -297,17 +297,19 @@ void Heatmap::printSectionHotness(StringRef FileName) const {
297297
void Heatmap::printSectionHotness(raw_ostream &OS) const {
298298
uint64_t NumTotalCounts = 0;
299299
StringMap<uint64_t> SectionHotness;
300+
StringMap<uint64_t> BucketUtilization;
300301
unsigned TextSectionIndex = 0;
301302

302303
if (TextSections.empty())
303304
return;
304305

305306
uint64_t UnmappedHotness = 0;
306307
auto RecordUnmappedBucket = [&](uint64_t Address, uint64_t Frequency) {
307-
errs() << "Couldn't map the address bucket [0x" << Twine::utohexstr(Address)
308-
<< ", 0x" << Twine::utohexstr(Address + BucketSize)
309-
<< "] containing " << Frequency
310-
<< " samples to a text section in the binary.";
308+
if (opts::Verbosity >= 1)
309+
errs() << "Couldn't map the address bucket [0x"
310+
<< Twine::utohexstr(Address) << ", 0x"
311+
<< Twine::utohexstr(Address + BucketSize) << "] containing "
312+
<< Frequency << " samples to a text section in the binary.";
311313
UnmappedHotness += Frequency;
312314
};
313315

@@ -325,23 +327,29 @@ void Heatmap::printSectionHotness(raw_ostream &OS) const {
325327
continue;
326328
}
327329
SectionHotness[TextSections[TextSectionIndex].Name] += KV.second;
330+
++BucketUtilization[TextSections[TextSectionIndex].Name];
328331
}
329332

330333
assert(NumTotalCounts > 0 &&
331334
"total number of heatmap buckets should be greater than 0");
332335

333-
OS << "Section Name, Begin Address, End Address, Percentage Hotness\n";
334-
for (auto &TextSection : TextSections) {
335-
OS << TextSection.Name << ", 0x"
336-
<< Twine::utohexstr(TextSection.BeginAddress) << ", 0x"
337-
<< Twine::utohexstr(TextSection.EndAddress) << ", "
338-
<< format("%.4f",
339-
100.0 * SectionHotness[TextSection.Name] / NumTotalCounts)
340-
<< "\n";
336+
OS << "Section Name, Begin Address, End Address, Percentage Hotness, "
337+
<< "Utilization Pct, Partition Score\n";
338+
const uint64_t MappedCounts = NumTotalCounts - UnmappedHotness;
339+
for (const auto [Name, Begin, End] : TextSections) {
340+
const float Hotness = 1. * SectionHotness[Name] / NumTotalCounts;
341+
const float MappedHotness =
342+
MappedCounts ? 1. * SectionHotness[Name] / MappedCounts : 0;
343+
const uint64_t NumBuckets =
344+
End / BucketSize + !!(End % BucketSize) - Begin / BucketSize;
345+
const float Utilization = 1. * BucketUtilization[Name] / NumBuckets;
346+
const float PartitionScore = MappedHotness * Utilization;
347+
OS << formatv("{0}, {1:x}, {2:x}, {3:f4}, {4:f4}, {5:f4}\n", Name, Begin,
348+
End, 100. * Hotness, 100. * Utilization, PartitionScore);
341349
}
342350
if (UnmappedHotness > 0)
343-
OS << "[unmapped], 0x0, 0x0, "
344-
<< format("%.4f", 100.0 * UnmappedHotness / NumTotalCounts) << "\n";
351+
OS << formatv("[unmapped], 0x0, 0x0, {0:f4}, 0, 0\n",
352+
100.0 * UnmappedHotness / NumTotalCounts);
345353
}
346354
} // namespace bolt
347355
} // namespace llvm

bolt/lib/Profile/YAMLProfileReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ Error YAMLProfileReader::readProfile(BinaryContext &BC) {
887887
}
888888

889889
bool YAMLProfileReader::usesEvent(StringRef Name) const {
890-
return YamlBP.Header.EventNames.find(std::string(Name)) != StringRef::npos;
890+
return StringRef(YamlBP.Header.EventNames).contains(Name);
891891
}
892892

893893
} // end namespace bolt

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 4 additions & 3 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)
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
@@ -1998,7 +1999,7 @@ Error RewriteInstance::readSpecialSections() {
19981999
BC->getUniqueSectionByName(BoltAddressTranslation::SECTION_NAME)) {
19992000
BC->HasBATSection = true;
20002001
// Do not read BAT when plotting a heatmap
2001-
if (!opts::HeatmapMode) {
2002+
if (opts::HeatmapMode != opts::HeatmapModeKind::HM_Exclusive) {
20022003
if (std::error_code EC = BAT->parse(BC->outs(), BATSec->getContents())) {
20032004
BC->errs() << "BOLT-ERROR: failed to parse BOLT address translation "
20042005
"table.\n";
@@ -2037,7 +2038,7 @@ Error RewriteInstance::readSpecialSections() {
20372038
}
20382039

20392040
// Force non-relocation mode for heatmap generation
2040-
if (opts::HeatmapMode)
2041+
if (opts::HeatmapMode == opts::HeatmapModeKind::HM_Exclusive)
20412042
BC->HasRelocations = false;
20422043

20432044
if (BC->HasRelocations)

bolt/lib/Utils/CommandLineOpts.cpp

Lines changed: 5 additions & 1 deletion
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,6 +124,10 @@ cl::opt<bool> HeatmapPrintMappings(
124124
"sections (default false)"),
125125
cl::Optional, cl::cat(HeatmapCategory));
126126

127+
cl::opt<std::string> HeatmapOutput("heatmap",
128+
cl::desc("print heatmap to a given file"),
129+
cl::Optional, cl::cat(HeatmapCategory));
130+
127131
cl::opt<bool> HotData("hot-data",
128132
cl::desc("hot data symbols support (relocation mode)"),
129133
cl::cat(BoltCategory));

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

Lines changed: 4 additions & 1 deletion
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: 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
@@ -46,8 +47,10 @@ WRITE-BAT-CHECK: BOLT-INFO: BAT section size (bytes): 404
4647
READ-BAT-CHECK-NOT: BOLT-ERROR: unable to save profile in YAML format for input file processed by BOLT
4748
READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries
4849
READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries
50+
READ-BAT-CHECK: HEATMAP: building heat map
4951
READ-BAT-CHECK: BOLT-INFO: 5 out of 21 functions in the binary (23.8%) have non-empty execution profile
5052
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
5154

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

0 commit comments

Comments
 (0)