Skip to content

Commit 88d8cdf

Browse files
committed
Profile Quality Pass
1 parent ac9f06c commit 88d8cdf

File tree

4 files changed

+853
-90
lines changed

4 files changed

+853
-90
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===- bolt/Passes/ProfileStats.h - profile quality metrics ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Functions to print profile stats to quantify profile quality.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef BOLT_PASSES_PROFILESTATS_H
14+
#define BOLT_PASSES_PROFILESTATS_H
15+
16+
#include <vector>
17+
18+
namespace llvm {
19+
20+
class raw_ostream;
21+
22+
namespace bolt {
23+
class BinaryContext;
24+
namespace ProfileStats {
25+
26+
/// Calculate and print various metrics related to profile quality
27+
void printAll(raw_ostream &OS, BinaryContext &BC);
28+
29+
} // namespace ProfileStats
30+
} // namespace bolt
31+
} // namespace llvm
32+
33+
#endif // BOLT_PASSES_PROFILESTATS_H

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "bolt/Passes/BinaryPasses.h"
1414
#include "bolt/Core/FunctionLayout.h"
1515
#include "bolt/Core/ParallelUtilities.h"
16+
#include "bolt/Passes/ProfileStats.h"
1617
#include "bolt/Passes/ReorderAlgorithm.h"
1718
#include "bolt/Passes/ReorderFunctions.h"
1819
#include "llvm/Support/CommandLine.h"
@@ -1280,96 +1281,7 @@ Error AssignSections::runOnFunctions(BinaryContext &BC) {
12801281
}
12811282

12821283
Error PrintProfileStats::runOnFunctions(BinaryContext &BC) {
1283-
double FlowImbalanceMean = 0.0;
1284-
size_t NumBlocksConsidered = 0;
1285-
double WorstBias = 0.0;
1286-
const BinaryFunction *WorstBiasFunc = nullptr;
1287-
1288-
// For each function CFG, we fill an IncomingMap with the sum of the frequency
1289-
// of incoming edges for each BB. Likewise for each OutgoingMap and the sum
1290-
// of the frequency of outgoing edges.
1291-
using FlowMapTy = std::unordered_map<const BinaryBasicBlock *, uint64_t>;
1292-
std::unordered_map<const BinaryFunction *, FlowMapTy> TotalIncomingMaps;
1293-
std::unordered_map<const BinaryFunction *, FlowMapTy> TotalOutgoingMaps;
1294-
1295-
// Compute mean
1296-
for (const auto &BFI : BC.getBinaryFunctions()) {
1297-
const BinaryFunction &Function = BFI.second;
1298-
if (Function.empty() || !Function.isSimple())
1299-
continue;
1300-
FlowMapTy &IncomingMap = TotalIncomingMaps[&Function];
1301-
FlowMapTy &OutgoingMap = TotalOutgoingMaps[&Function];
1302-
for (const BinaryBasicBlock &BB : Function) {
1303-
uint64_t TotalOutgoing = 0ULL;
1304-
auto SuccBIIter = BB.branch_info_begin();
1305-
for (BinaryBasicBlock *Succ : BB.successors()) {
1306-
uint64_t Count = SuccBIIter->Count;
1307-
if (Count == BinaryBasicBlock::COUNT_NO_PROFILE || Count == 0) {
1308-
++SuccBIIter;
1309-
continue;
1310-
}
1311-
TotalOutgoing += Count;
1312-
IncomingMap[Succ] += Count;
1313-
++SuccBIIter;
1314-
}
1315-
OutgoingMap[&BB] = TotalOutgoing;
1316-
}
1317-
1318-
size_t NumBlocks = 0;
1319-
double Mean = 0.0;
1320-
for (const BinaryBasicBlock &BB : Function) {
1321-
// Do not compute score for low frequency blocks, entry or exit blocks
1322-
if (IncomingMap[&BB] < 100 || OutgoingMap[&BB] == 0 || BB.isEntryPoint())
1323-
continue;
1324-
++NumBlocks;
1325-
const double Difference = (double)OutgoingMap[&BB] - IncomingMap[&BB];
1326-
Mean += fabs(Difference / IncomingMap[&BB]);
1327-
}
1328-
1329-
FlowImbalanceMean += Mean;
1330-
NumBlocksConsidered += NumBlocks;
1331-
if (!NumBlocks)
1332-
continue;
1333-
double FuncMean = Mean / NumBlocks;
1334-
if (FuncMean > WorstBias) {
1335-
WorstBias = FuncMean;
1336-
WorstBiasFunc = &Function;
1337-
}
1338-
}
1339-
if (NumBlocksConsidered > 0)
1340-
FlowImbalanceMean /= NumBlocksConsidered;
1341-
1342-
// Compute standard deviation
1343-
NumBlocksConsidered = 0;
1344-
double FlowImbalanceVar = 0.0;
1345-
for (const auto &BFI : BC.getBinaryFunctions()) {
1346-
const BinaryFunction &Function = BFI.second;
1347-
if (Function.empty() || !Function.isSimple())
1348-
continue;
1349-
FlowMapTy &IncomingMap = TotalIncomingMaps[&Function];
1350-
FlowMapTy &OutgoingMap = TotalOutgoingMaps[&Function];
1351-
for (const BinaryBasicBlock &BB : Function) {
1352-
if (IncomingMap[&BB] < 100 || OutgoingMap[&BB] == 0)
1353-
continue;
1354-
++NumBlocksConsidered;
1355-
const double Difference = (double)OutgoingMap[&BB] - IncomingMap[&BB];
1356-
FlowImbalanceVar +=
1357-
pow(fabs(Difference / IncomingMap[&BB]) - FlowImbalanceMean, 2);
1358-
}
1359-
}
1360-
if (NumBlocksConsidered) {
1361-
FlowImbalanceVar /= NumBlocksConsidered;
1362-
FlowImbalanceVar = sqrt(FlowImbalanceVar);
1363-
}
1364-
1365-
// Report to user
1366-
BC.outs() << format("BOLT-INFO: Profile bias score: %.4lf%% StDev: %.4lf%%\n",
1367-
(100.0 * FlowImbalanceMean), (100.0 * FlowImbalanceVar));
1368-
if (WorstBiasFunc && opts::Verbosity >= 1) {
1369-
BC.outs() << "Worst average bias observed in "
1370-
<< WorstBiasFunc->getPrintName() << "\n";
1371-
LLVM_DEBUG(WorstBiasFunc->dump());
1372-
}
1284+
ProfileStats::printAll(BC.outs(), BC);
13731285
return Error::success();
13741286
}
13751287

bolt/lib/Passes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ add_llvm_library(LLVMBOLTPasses
2929
PatchEntries.cpp
3030
PettisAndHansen.cpp
3131
PLTCall.cpp
32+
ProfileStats.cpp
3233
RegAnalysis.cpp
3334
RegReAssign.cpp
3435
ReorderAlgorithm.cpp

0 commit comments

Comments
 (0)