Skip to content

Commit 6280681

Browse files
authored
[BOLT] Output basic YAML profile in BAT mode
Relax assumptions that YAML output is not supported in BAT mode. Set up basic infrastructure for emitting YAML for functions not covered by BAT, such as from `.bolt.org.text` section (code identical to input binary sans external refs), or non-rewritten functions in non-relocation mode (where the function stays in the same section but BAT mapping is not emitted). This diff only produces YAML profile for non-BAT functions (skipped, non-simple). YAML profile for BAT functions is added in follow-up diffs: - #76911 emits YAML profile with internal control flow information only (branch profile), - #76896 adds cross-function profile (calls profile). Test Plan: Added bolt/test/X86/bolt-address-translation-yaml.test Reviewers: ayermolo, dcci, maksfb, rafaelauler Reviewed By: rafaelauler Pull Request: #76910
1 parent 70a9c52 commit 6280681

10 files changed

+1936
-21
lines changed

bolt/docs/BAT.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ binary onto the original binary.
1414
# Usage
1515
`--enable-bat` flag controls the generation of BAT section. Sampled profile
1616
needs to be passed along with the optimized binary containing BAT section to
17-
`perf2bolt` which reads BAT section and produces fdata profile for the original
18-
binary. Note that YAML profile generation is not supported since BAT doesn't
19-
contain the metadata for input functions.
17+
`perf2bolt` which reads BAT section and produces profile for the original
18+
binary.
2019

2120
# Internals
2221
## Section contents

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ class BoltAddressTranslation {
122122
/// Returns BF hash by function output address (after BOLT).
123123
size_t getBFHash(uint64_t OutputAddress) const;
124124

125+
/// True if a given \p Address is a function with translation table entry.
126+
bool isBATFunction(uint64_t Address) const { return Maps.count(Address); }
127+
125128
private:
126129
/// Helper to update \p Map by inserting one or more BAT entries reflecting
127130
/// \p BB for function located at \p FuncAddress. At least one entry will be

bolt/include/bolt/Profile/DataAggregator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ class DataAggregator : public DataReader {
463463
/// Dump data structures into a file readable by llvm-bolt
464464
std::error_code writeAggregatedFile(StringRef OutputFilename) const;
465465

466+
/// Dump translated data structures into YAML
467+
std::error_code writeBATYAML(BinaryContext &BC,
468+
StringRef OutputFilename) const;
469+
466470
/// Filter out binaries based on PID
467471
void filterBinaryMMapInfo();
468472

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "bolt/Core/BinaryFunction.h"
1717
#include "bolt/Profile/BoltAddressTranslation.h"
1818
#include "bolt/Profile/Heatmap.h"
19+
#include "bolt/Profile/YAMLProfileWriter.h"
1920
#include "bolt/Utils/CommandLineOpts.h"
2021
#include "bolt/Utils/Utils.h"
2122
#include "llvm/ADT/STLExtras.h"
@@ -85,6 +86,7 @@ MaxSamples("max-samples",
8586
cl::cat(AggregatorCategory));
8687

8788
extern cl::opt<opts::ProfileFormatKind> ProfileFormat;
89+
extern cl::opt<std::string> SaveProfile;
8890

8991
cl::opt<bool> ReadPreAggregated(
9092
"pa", cl::desc("skip perf and read data from a pre-aggregated file format"),
@@ -594,10 +596,21 @@ Error DataAggregator::readProfile(BinaryContext &BC) {
594596
convertBranchData(Function);
595597
}
596598

597-
if (opts::AggregateOnly &&
598-
opts::ProfileFormat == opts::ProfileFormatKind::PF_Fdata) {
599-
if (std::error_code EC = writeAggregatedFile(opts::OutputFilename))
600-
report_error("cannot create output data file", EC);
599+
if (opts::AggregateOnly) {
600+
if (opts::ProfileFormat == opts::ProfileFormatKind::PF_Fdata)
601+
if (std::error_code EC = writeAggregatedFile(opts::OutputFilename))
602+
report_error("cannot create output data file", EC);
603+
604+
// BAT YAML is handled by DataAggregator since normal YAML output requires
605+
// CFG which is not available in BAT mode.
606+
if (usesBAT()) {
607+
if (opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML)
608+
if (std::error_code EC = writeBATYAML(BC, opts::OutputFilename))
609+
report_error("cannot create output data file", EC);
610+
if (!opts::SaveProfile.empty())
611+
if (std::error_code EC = writeBATYAML(BC, opts::SaveProfile))
612+
report_error("cannot create output data file", EC);
613+
}
601614
}
602615

603616
return Error::success();
@@ -2258,6 +2271,53 @@ DataAggregator::writeAggregatedFile(StringRef OutputFilename) const {
22582271
return std::error_code();
22592272
}
22602273

2274+
std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
2275+
StringRef OutputFilename) const {
2276+
std::error_code EC;
2277+
raw_fd_ostream OutFile(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
2278+
if (EC)
2279+
return EC;
2280+
2281+
yaml::bolt::BinaryProfile BP;
2282+
2283+
// Fill out the header info.
2284+
BP.Header.Version = 1;
2285+
BP.Header.FileName = std::string(BC.getFilename());
2286+
std::optional<StringRef> BuildID = BC.getFileBuildID();
2287+
BP.Header.Id = BuildID ? std::string(*BuildID) : "<unknown>";
2288+
BP.Header.Origin = std::string(getReaderName());
2289+
// Only the input binary layout order is supported.
2290+
BP.Header.IsDFSOrder = false;
2291+
// FIXME: Need to match hash function used to produce BAT hashes.
2292+
BP.Header.HashFunction = HashFunction::Default;
2293+
2294+
ListSeparator LS(",");
2295+
raw_string_ostream EventNamesOS(BP.Header.EventNames);
2296+
for (const StringMapEntry<std::nullopt_t> &EventEntry : EventNames)
2297+
EventNamesOS << LS << EventEntry.first().str();
2298+
2299+
BP.Header.Flags = opts::BasicAggregation ? BinaryFunction::PF_SAMPLE
2300+
: BinaryFunction::PF_LBR;
2301+
2302+
if (!opts::BasicAggregation) {
2303+
// Convert profile for functions not covered by BAT
2304+
for (auto &BFI : BC.getBinaryFunctions()) {
2305+
BinaryFunction &Function = BFI.second;
2306+
if (!Function.hasProfile())
2307+
continue;
2308+
if (BAT->isBATFunction(Function.getAddress()))
2309+
continue;
2310+
BP.Functions.emplace_back(
2311+
YAMLProfileWriter::convert(Function, /*UseDFS=*/false));
2312+
}
2313+
}
2314+
2315+
// Write the profile.
2316+
yaml::Output Out(OutFile, nullptr, 0);
2317+
Out << BP;
2318+
return std::error_code();
2319+
}
2320+
22612321
void DataAggregator::dump() const { DataReader::dump(); }
22622322

22632323
void DataAggregator::dump(const LBREntry &LBR) const {

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,7 @@ static cl::opt<cl::boolOrDefault> RelocationMode(
199199
"relocs", cl::desc("use relocations in the binary (default=autodetect)"),
200200
cl::cat(BoltCategory));
201201

202-
static cl::opt<std::string>
203-
SaveProfile("w",
204-
cl::desc("save recorded profile to a file"),
205-
cl::cat(BoltOutputCategory));
202+
extern cl::opt<std::string> SaveProfile;
206203

207204
static cl::list<std::string>
208205
SkipFunctionNames("skip-funcs",
@@ -732,6 +729,13 @@ Error RewriteInstance::run() {
732729
// Skip disassembling if we have a translation table and we are running an
733730
// aggregation job.
734731
if (opts::AggregateOnly && BAT->enabledFor(InputFile)) {
732+
// YAML profile in BAT mode requires CFG for .bolt.org.text functions
733+
if (!opts::SaveProfile.empty() ||
734+
opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML) {
735+
selectFunctionsToProcess();
736+
disassembleFunctions();
737+
buildFunctionsCFG();
738+
}
735739
processProfileData();
736740
return Error::success();
737741
}
@@ -2027,14 +2031,6 @@ void RewriteInstance::adjustCommandLineOptions() {
20272031

20282032
if (opts::Lite)
20292033
BC->outs() << "BOLT-INFO: enabling lite mode\n";
2030-
2031-
if (!opts::SaveProfile.empty() && BAT->enabledFor(InputFile)) {
2032-
BC->errs()
2033-
<< "BOLT-ERROR: unable to save profile in YAML format for input "
2034-
"file processed by BOLT. Please remove -w option and use branch "
2035-
"profile.\n";
2036-
exit(1);
2037-
}
20382034
}
20392035

20402036
namespace {
@@ -3126,12 +3122,13 @@ void RewriteInstance::processProfileData() {
31263122
}
31273123
}
31283124

3129-
if (!opts::SaveProfile.empty()) {
3125+
if (!opts::SaveProfile.empty() && !BAT->enabledFor(InputFile)) {
31303126
YAMLProfileWriter PW(opts::SaveProfile);
31313127
PW.writeProfile(*this);
31323128
}
31333129
if (opts::AggregateOnly &&
3134-
opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML) {
3130+
opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML &&
3131+
!BAT->enabledFor(InputFile)) {
31353132
YAMLProfileWriter PW(opts::OutputFilename);
31363133
PW.writeProfile(*this);
31373134
}

bolt/lib/Utils/CommandLineOpts.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ cl::opt<ProfileFormatKind> ProfileFormat(
162162
clEnumValN(PF_YAML, "yaml", "dense YAML representation")),
163163
cl::ZeroOrMore, cl::Hidden, cl::cat(BoltCategory));
164164

165+
cl::opt<std::string> SaveProfile("w",
166+
cl::desc("save recorded profile to a file"),
167+
cl::cat(BoltOutputCategory));
168+
165169
cl::opt<bool> SplitEH("split-eh", cl::desc("split C++ exception handling code"),
166170
cl::Hidden, cl::cat(BoltOptCategory));
167171

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
B 40164b 401608 109 0
2+
B 401611 4017e0 115 0
3+
B 4017f0 401616 117 0
4+
B 401ba2 4015da 6 0
5+
B 4015d5 401b60 1 0
6+
B 40159a 401b60 5 0
7+
B 401b9d 401b70 615 2
8+
B 401b90 401b99 344 37
9+
B 401ba2 40159f 8 0
10+
B 4015b0 401070 9 0
11+
B 401544 4014a0 6 0
12+
B 40188a 401928 5 0
13+
B 40152a 4014b0 21 0
14+
B 40169e 40165b 2 0
15+
B 4014dd 401070 12 1
16+
B 401509 4014ec 2 2
17+
B 401510 401030 673 0
18+
B 4019de 401080 1 0
19+
B 401500 401070 22 0
20+
B 401921 4014d6 9 0
21+
B 4019b3 401080 3 0
22+
B 40162d 401070 113 0
23+
B 4014d1 401800 27 0
24+
B 401a3f 401080 1 0
25+
B 4018d2 401050 17 0
26+
B 401664 4017c0 2 0
27+
B 401680 401070 2 0
28+
B 4017d0 401669 2 0
29+
B 4018f7 40190d 9 0
30+
B 4015bc 401592 6 0
31+
B 401964 401090 5 0
32+
B 4015f8 4015cd 1 0
33+
B 4015ec 401070 6 0
34+
F 40165b 401664 2
35+
F 4017c0 4017d0 2
36+
F 401669 401680 2
37+
F 40190d 401921 9
38+
F 4014d6 4014dd 9
39+
F 401800 4018d2 17
40+
F 4018d7 4018f7 9
41+
F 40159f 4015b0 8
42+
F 401515 401544 6
43+
F 401070 401500 1
44+
F 401070 401070 157
45+
F 4014a0 4014d1 6
46+
F 401616 40162d 112
47+
F 4019e3 401a3f 1
48+
F 4014e2 401500 19
49+
F 401090 401090 5
50+
F 401030 401030 673
51+
F 401505 401510 668
52+
F 401616 4017f0 2
53+
F 401070 4015b0 1
54+
F 4015da 4015ec 6
55+
F 401b60 401b90 6
56+
F 4019b8 4019de 1
57+
F 401969 4019b3 3
58+
F 401505 401509 2
59+
F 401515 40152a 21
60+
F 401592 40159a 4
61+
F 401050 401050 17
62+
F 4015cd 4015d5 1
63+
F 401070 4014dd 1
64+
F 401b99 401ba2 8
65+
F 401b70 401b90 326
66+
F 401b99 401b9d 324
67+
F 401592 4015bc 1
68+
F 401608 401611 109
69+
F 401b70 401b9d 268
70+
F 4015b5 4015bc 5
71+
F 401b99 401b90 1
72+
F 401b70 401ba2 5
73+
F 401632 40164b 108
74+
F 401080 401080 5
75+
F 4014b0 4014d1 21
76+
F 4017e0 4017f0 115
77+
F 4015f1 4015f8 1
78+
F 401685 40169e 2
79+
F 401928 401964 5
80+
F 401800 40188a 5
81+
F 4014ec 401500 2

0 commit comments

Comments
 (0)