Skip to content

Commit d7d2f7c

Browse files
authored
[BOLT] Emit intra-function control flow in YAMLBAT
Attach branch counters to YAML profile, covering intra-function control flow. Depends on: #86353 Test Plan: Updated bolt/test/X86/bolt-address-translation-yaml.test Reviewers: rafaelauler, dcci, ayermolo, maksfb Reviewed By: rafaelauler Pull Request: #76911
1 parent 8e698a1 commit d7d2f7c

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

bolt/include/bolt/Profile/BoltAddressTranslation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ class BoltAddressTranslation {
257257
std::as_const(*this).getBBHashMap(FuncOutputAddress));
258258
}
259259

260+
/// Returns the number of basic blocks in a function.
261+
size_t getNumBasicBlocks(uint64_t OutputAddress) const {
262+
return NumBasicBlocksMap.at(OutputAddress);
263+
}
264+
260265
private:
261266
FuncHashesTy FuncHashes;
262267
};

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,52 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
23102310
BP.Functions.emplace_back(
23112311
YAMLProfileWriter::convert(Function, /*UseDFS=*/false));
23122312
}
2313+
2314+
for (const auto &KV : NamesToBranches) {
2315+
const StringRef FuncName = KV.first;
2316+
const FuncBranchData &Branches = KV.second;
2317+
yaml::bolt::BinaryFunctionProfile YamlBF;
2318+
BinaryData *BD = BC.getBinaryDataByName(FuncName);
2319+
assert(BD);
2320+
uint64_t FuncAddress = BD->getAddress();
2321+
if (!BAT->isBATFunction(FuncAddress))
2322+
continue;
2323+
// Filter out cold fragments
2324+
if (!BD->getSectionName().equals(BC.getMainCodeSectionName()))
2325+
continue;
2326+
BinaryFunction *BF = BC.getBinaryFunctionAtAddress(FuncAddress);
2327+
assert(BF);
2328+
YamlBF.Name = FuncName.str();
2329+
YamlBF.Id = BF->getFunctionNumber();
2330+
YamlBF.Hash = BAT->getBFHash(FuncAddress);
2331+
YamlBF.ExecCount = BF->getKnownExecutionCount();
2332+
YamlBF.NumBasicBlocks = BAT->getNumBasicBlocks(FuncAddress);
2333+
const BoltAddressTranslation::BBHashMapTy &BlockMap =
2334+
BAT->getBBHashMap(FuncAddress);
2335+
2336+
auto addSuccProfile = [&](yaml::bolt::BinaryBasicBlockProfile &YamlBB,
2337+
uint64_t SuccOffset, unsigned SuccDataIdx) {
2338+
const llvm::bolt::BranchInfo &BI = Branches.Data.at(SuccDataIdx);
2339+
yaml::bolt::SuccessorInfo SI;
2340+
SI.Index = BlockMap.getBBIndex(SuccOffset);
2341+
SI.Count = BI.Branches;
2342+
SI.Mispreds = BI.Mispreds;
2343+
YamlBB.Successors.emplace_back(SI);
2344+
};
2345+
2346+
for (const auto &[FromOffset, SuccKV] : Branches.IntraIndex) {
2347+
yaml::bolt::BinaryBasicBlockProfile YamlBB;
2348+
if (!BlockMap.isInputBlock(FromOffset))
2349+
continue;
2350+
YamlBB.Index = BlockMap.getBBIndex(FromOffset);
2351+
YamlBB.Hash = BlockMap.getBBHash(FromOffset);
2352+
for (const auto &[SuccOffset, SuccDataIdx] : SuccKV)
2353+
addSuccProfile(YamlBB, SuccOffset, SuccDataIdx);
2354+
if (YamlBB.ExecCount || !YamlBB.Successors.empty())
2355+
YamlBF.Blocks.emplace_back(YamlBB);
2356+
}
2357+
BP.Functions.emplace_back(YamlBF);
2358+
}
23132359
}
23142360

23152361
// Write the profile.

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ READ-BAT-CHECK: BOLT-INFO: Parsed 5 BAT entries
2525
READ-BAT-CHECK: PERF2BOLT: read 79 aggregated LBR entries
2626

2727
YAML-BAT-CHECK: functions:
28+
# Function not covered by BAT - has insns in basic block
2829
YAML-BAT-CHECK: - name: main
2930
YAML-BAT-CHECK-NEXT: fid: 2
3031
YAML-BAT-CHECK-NEXT: hash: 0x9895746D48B2C876
@@ -35,6 +36,17 @@ YAML-BAT-CHECK-NEXT: - bid: 0
3536
YAML-BAT-CHECK-NEXT: insns: 26
3637
YAML-BAT-CHECK-NEXT: hash: 0xA900AE79CFD40000
3738
YAML-BAT-CHECK-NEXT: succ: [ { bid: 3, cnt: 0 }, { bid: 1, cnt: 0 } ]
39+
# Function covered by BAT - doesn't have insns in basic block
40+
YAML-BAT-CHECK: - name: usqrt
41+
YAML-BAT-CHECK-NEXT: fid: [[#]]
42+
YAML-BAT-CHECK-NEXT: hash: 0x99E67ED32A203023
43+
YAML-BAT-CHECK-NEXT: exec: 21
44+
YAML-BAT-CHECK-NEXT: nblocks: 5
45+
YAML-BAT-CHECK-NEXT: blocks:
46+
YAML-BAT-CHECK: - bid: 1
47+
YAML-BAT-CHECK-NEXT: insns: [[#]]
48+
YAML-BAT-CHECK-NEXT: hash: 0xD70DC695320E0010
49+
YAML-BAT-CHECK-NEXT: succ: {{.*}} { bid: 2, cnt: [[#]] }
3850

3951
CHECK-BOLT-YAML: pre-processing profile using YAML profile reader
40-
CHECK-BOLT-YAML-NEXT: 1 out of 16 functions in the binary (6.2%) have non-empty execution profile
52+
CHECK-BOLT-YAML-NEXT: 5 out of 16 functions in the binary (31.2%) have non-empty execution profile

0 commit comments

Comments
 (0)