Skip to content

Commit 6d1502c

Browse files
author
spupyrev
committed
[BOLT] (Minor) Changes in stale inference
1. Using ADT/Bitfields.h for hash computation; this is equivalent but shorter than the existing implementation 2. Getting rid of Layout indices for stale matching; using BB->getIndex for indexing Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D155748
1 parent f86c81b commit 6d1502c

File tree

2 files changed

+34
-53
lines changed

2 files changed

+34
-53
lines changed

bolt/lib/Profile/StaleProfileMatching.cpp

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@
2727

2828
#include "bolt/Core/HashUtilities.h"
2929
#include "bolt/Profile/YAMLProfileReader.h"
30+
#include "llvm/ADT/Bitfields.h"
3031
#include "llvm/ADT/Hashing.h"
3132
#include "llvm/Support/CommandLine.h"
3233
#include "llvm/Transforms/Utils/SampleProfileInference.h"
3334

3435
#include <queue>
3536

37+
using namespace llvm;
38+
3639
#undef DEBUG_TYPE
3740
#define DEBUG_TYPE "bolt-prof"
3841

39-
using namespace llvm;
40-
4142
namespace opts {
4243

4344
extern cl::OptionCategory BoltOptCategory;
@@ -141,49 +142,29 @@ namespace bolt {
141142
/// components are of smaller size (e.g., uint16_t or uint8_t).
142143
struct BlendedBlockHash {
143144
private:
144-
static uint64_t combineHashes(uint16_t Hash1, uint16_t Hash2, uint16_t Hash3,
145-
uint16_t Hash4) {
146-
uint64_t Hash = 0;
147-
148-
Hash |= uint64_t(Hash4);
149-
Hash <<= 16;
150-
151-
Hash |= uint64_t(Hash3);
152-
Hash <<= 16;
153-
154-
Hash |= uint64_t(Hash2);
155-
Hash <<= 16;
156-
157-
Hash |= uint64_t(Hash1);
158-
159-
return Hash;
160-
}
161-
162-
static void parseHashes(uint64_t Hash, uint16_t &Hash1, uint16_t &Hash2,
163-
uint16_t &Hash3, uint16_t &Hash4) {
164-
Hash1 = Hash & 0xffff;
165-
Hash >>= 16;
166-
167-
Hash2 = Hash & 0xffff;
168-
Hash >>= 16;
169-
170-
Hash3 = Hash & 0xffff;
171-
Hash >>= 16;
172-
173-
Hash4 = Hash & 0xffff;
174-
Hash >>= 16;
175-
}
145+
using ValueOffset = Bitfield::Element<uint16_t, 0, 16>;
146+
using ValueOpcode = Bitfield::Element<uint16_t, 16, 16>;
147+
using ValueInstr = Bitfield::Element<uint16_t, 32, 16>;
148+
using ValueNeighbor = Bitfield::Element<uint16_t, 48, 16>;
176149

177150
public:
178151
explicit BlendedBlockHash() {}
179152

180-
explicit BlendedBlockHash(uint64_t CombinedHash) {
181-
parseHashes(CombinedHash, Offset, OpcodeHash, InstrHash, NeighborHash);
153+
explicit BlendedBlockHash(uint64_t Hash) {
154+
Offset = Bitfield::get<ValueOffset>(Hash);
155+
OpcodeHash = Bitfield::get<ValueOpcode>(Hash);
156+
InstrHash = Bitfield::get<ValueInstr>(Hash);
157+
NeighborHash = Bitfield::get<ValueNeighbor>(Hash);
182158
}
183159

184160
/// Combine the blended hash into uint64_t.
185161
uint64_t combine() const {
186-
return combineHashes(Offset, OpcodeHash, InstrHash, NeighborHash);
162+
uint64_t Hash = 0;
163+
Bitfield::set<ValueOffset>(Hash, Offset);
164+
Bitfield::set<ValueOpcode>(Hash, OpcodeHash);
165+
Bitfield::set<ValueInstr>(Hash, InstrHash);
166+
Bitfield::set<ValueNeighbor>(Hash, NeighborHash);
167+
return Hash;
187168
}
188169

189170
/// Compute a distance between two given blended hashes. The smaller the
@@ -311,6 +292,7 @@ void BinaryFunction::computeBlockHashes() const {
311292
BB->setHash(BlendedHashes[I].combine());
312293
}
313294
}
295+
314296
/// Create a wrapper flow function to use with the profile inference algorithm,
315297
/// and initialize its jumps and metadata.
316298
FlowFunction
@@ -319,7 +301,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
319301

320302
// Add a special "dummy" source so that there is always a unique entry point.
321303
// Because of the extra source, for all other blocks in FlowFunction it holds
322-
// that Block.Index == BB->getLayoutIndex() + 1
304+
// that Block.Index == BB->getIndex() + 1
323305
FlowBlock EntryBlock;
324306
EntryBlock.Index = 0;
325307
Func.Blocks.push_back(EntryBlock);
@@ -330,7 +312,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
330312
FlowBlock &Block = Func.Blocks.back();
331313
Block.Index = Func.Blocks.size() - 1;
332314
(void)BB;
333-
assert(Block.Index == BB->getLayoutIndex() + 1 &&
315+
assert(Block.Index == BB->getIndex() + 1 &&
334316
"incorrectly assigned basic block index");
335317
}
336318

@@ -346,8 +328,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
346328

347329
Func.Jumps.emplace_back();
348330
FlowJump &Jump = Func.Jumps.back();
349-
Jump.Source = SrcBB->getLayoutIndex() + 1;
350-
Jump.Target = DstBB->getLayoutIndex() + 1;
331+
Jump.Source = SrcBB->getIndex() + 1;
332+
Jump.Target = DstBB->getIndex() + 1;
351333
InDegree[Jump.Target]++;
352334
UniqueSuccs.insert(DstBB);
353335
}
@@ -359,8 +341,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
359341

360342
Func.Jumps.emplace_back();
361343
FlowJump &Jump = Func.Jumps.back();
362-
Jump.Source = SrcBB->getLayoutIndex() + 1;
363-
Jump.Target = DstBB->getLayoutIndex() + 1;
344+
Jump.Source = SrcBB->getIndex() + 1;
345+
Jump.Target = DstBB->getIndex() + 1;
364346
InDegree[Jump.Target]++;
365347
UniqueSuccs.insert(DstBB);
366348
}
@@ -707,31 +689,33 @@ void assignProfile(BinaryFunction &BF,
707689

708690
bool YAMLProfileReader::inferStaleProfile(
709691
BinaryFunction &BF, const yaml::bolt::BinaryFunctionProfile &YamlBF) {
710-
// Make sure that block indices and hashes are up to date
711-
BF.getLayout().updateLayoutIndices();
692+
LLVM_DEBUG(dbgs() << "BOLT-INFO: applying profile inference for "
693+
<< "\"" << BF.getPrintName() << "\"\n");
694+
695+
// Make sure that block hashes are up to date.
712696
BF.computeBlockHashes();
713697

714698
const BinaryFunction::BasicBlockOrderType BlockOrder(
715699
BF.getLayout().block_begin(), BF.getLayout().block_end());
716700

717-
// Create a wrapper flow function to use with the profile inference algorithm
701+
// Create a wrapper flow function to use with the profile inference algorithm.
718702
FlowFunction Func = createFlowFunction(BlockOrder);
719703

720704
// Match as many block/jump counts from the stale profile as possible
721705
matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func);
722706

723707
// Adjust the flow function by marking unreachable blocks Unlikely so that
724-
// they don't get any counts assigned
708+
// they don't get any counts assigned.
725709
preprocessUnreachableBlocks(Func);
726710

727-
// Check if profile inference can be applied for the instance
711+
// Check if profile inference can be applied for the instance.
728712
if (!canApplyInference(Func))
729713
return false;
730714

731-
// Apply the profile inference algorithm
715+
// Apply the profile inference algorithm.
732716
applyInference(Func);
733717

734-
// Collect inferred counts and update function annotations
718+
// Collect inferred counts and update function annotations.
735719
assignProfile(BF, BlockOrder, Func);
736720

737721
// As of now, we always mark the binary function having "correct" profile.

bolt/lib/Profile/YAMLProfileReader.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,6 @@ bool YAMLProfileReader::parseFunctionProfile(
245245
<< " edges in profile did not match function " << BF << '\n';
246246

247247
if (!ProfileMatched && opts::InferStaleProfile) {
248-
if (opts::Verbosity >= 1)
249-
outs() << "BOLT-INFO: applying profile inference for "
250-
<< "\"" << BF.getPrintName() << "\"\n";
251248
if (inferStaleProfile(BF, YamlBF)) {
252249
ProfileMatched = true;
253250
BF.markProfiled(YamlBP.Header.Flags);

0 commit comments

Comments
 (0)