Skip to content

[BOLT][NFC] Unify Intra/InterIndex handling in writeBATYAML #91278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions bolt/include/bolt/Profile/DataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ struct FuncBranchData {
uint64_t getNumExecutedBranches() const;

/// Aggregation helpers
DenseMap<uint64_t, DenseMap<uint64_t, size_t>> IntraIndex;
DenseMap<uint64_t, DenseMap<Location, size_t>> InterIndex;
DenseMap<uint64_t, DenseMap<Location, size_t>> EntryIndex;
template <typename KeyT>
using IndexTy = DenseMap<uint64_t, DenseMap<KeyT, size_t>>;
IndexTy<uint64_t> IntraIndex;
IndexTy<Location> InterIndex;
IndexTy<Location> EntryIndex;

void bumpBranchCount(uint64_t OffsetFrom, uint64_t OffsetTo, uint64_t Count,
uint64_t Mispreds);
Expand Down
3 changes: 3 additions & 0 deletions bolt/include/bolt/Profile/ProfileYAMLMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ struct SuccessorInfo {
bool operator!=(const SuccessorInfo &Other) const {
return !(*this == Other);
}
bool operator<(const SuccessorInfo &Other) const {
return Index < Other.Index;
}
};
} // end namespace bolt

Expand Down
73 changes: 29 additions & 44 deletions bolt/lib/Profile/DataAggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,30 +2354,6 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
for (auto BI = BlockMap.begin(), BE = BlockMap.end(); BI != BE; ++BI)
YamlBF.Blocks[BI->second.getBBIndex()].Hash = BI->second.getBBHash();

auto getSuccessorInfo = [&](uint32_t SuccOffset, unsigned SuccDataIdx) {
const llvm::bolt::BranchInfo &BI = Branches.Data.at(SuccDataIdx);
yaml::bolt::SuccessorInfo SI;
SI.Index = BlockMap.getBBIndex(SuccOffset);
SI.Count = BI.Branches;
SI.Mispreds = BI.Mispreds;
return SI;
};

auto getCallSiteInfo = [&](Location CallToLoc, unsigned CallToIdx,
uint32_t Offset) {
const llvm::bolt::BranchInfo &BI = Branches.Data.at(CallToIdx);
yaml::bolt::CallSiteInfo CSI;
CSI.DestId = 0; // designated for unknown functions
CSI.EntryDiscriminator = 0;
CSI.Count = BI.Branches;
CSI.Mispreds = BI.Mispreds;
CSI.Offset = Offset;
if (BinaryData *BD = BC.getBinaryDataByName(CallToLoc.Name))
YAMLProfileWriter::setCSIDestination(BC, CSI, BD->getSymbol(), BAT,
CallToLoc.Offset);
return CSI;
};

// Lookup containing basic block offset and index
auto getBlock = [&BlockMap](uint32_t Offset) {
auto BlockIt = BlockMap.upper_bound(Offset);
Expand All @@ -2386,26 +2362,35 @@ std::error_code DataAggregator::writeBATYAML(BinaryContext &BC,
return std::pair(BlockIt->first, BlockIt->second.getBBIndex());
};

for (const auto &[FromOffset, SuccKV] : Branches.IntraIndex) {
const auto &[_, Index] = getBlock(FromOffset);
yaml::bolt::BinaryBasicBlockProfile &YamlBB = YamlBF.Blocks[Index];
for (const auto &[SuccOffset, SuccDataIdx] : SuccKV)
if (BlockMap.isInputBlock(SuccOffset))
YamlBB.Successors.emplace_back(
getSuccessorInfo(SuccOffset, SuccDataIdx));
}
for (const auto &[FromOffset, CallTo] : Branches.InterIndex) {
const auto &[BlockOffset, BlockIndex] = getBlock(FromOffset);
yaml::bolt::BinaryBasicBlockProfile &YamlBB = YamlBF.Blocks[BlockIndex];
const uint32_t Offset = FromOffset - BlockOffset;
for (const auto &[CallToLoc, CallToIdx] : CallTo)
YamlBB.CallSites.emplace_back(
getCallSiteInfo(CallToLoc, CallToIdx, Offset));
llvm::sort(YamlBB.CallSites, [](yaml::bolt::CallSiteInfo &A,
yaml::bolt::CallSiteInfo &B) {
return A.Offset < B.Offset;
});
}
auto addIndex = [&]<typename T>(const FuncBranchData::IndexTy<T> &Index) {
using namespace yaml::bolt;
constexpr bool Calls = std::is_same<T, Location>::value;
for (const auto &[FromOffset, To] : Index) {
const auto &[BlockOffset, BlockIndex] = getBlock(FromOffset);
yaml::bolt::BinaryBasicBlockProfile &BB = YamlBF.Blocks[BlockIndex];
for (const auto [Key, DataIdx] : To) {
const llvm::bolt::BranchInfo &BI = Branches.Data.at(DataIdx);
std::conditional_t<Calls, CallSiteInfo, SuccessorInfo> SI;
SI.Count = BI.Branches;
SI.Mispreds = BI.Mispreds;
if constexpr (Calls) {
SI.Offset = FromOffset - BlockOffset;
if (const BinaryData *BD = BC.getBinaryDataByName(Key.Name))
YAMLProfileWriter::setCSIDestination(BC, SI, BD->getSymbol(),
BAT, Key.Offset);
BB.CallSites.emplace_back(SI);
} else if (BlockMap.isInputBlock(Key)) {
SI.Index = BlockMap.getBBIndex(Key);
BB.Successors.emplace_back(SI);
}
}
Calls ? llvm::sort(BB.CallSites) : llvm::sort(BB.Successors);
}
};

addIndex(Branches.IntraIndex);
addIndex(Branches.InterIndex);

// Drop blocks without a hash, won't be useful for stale matching.
llvm::erase_if(YamlBF.Blocks,
[](const yaml::bolt::BinaryBasicBlockProfile &YamlBB) {
Expand Down