Skip to content

Commit effb574

Browse files
wdx727lifengxiang1025zcfh
committed
Adding Matching and Inference Functionality to Propeller-PR2: Compute basic block hash and emit to ELF.
Co-authored-by: lifengxiang1025 <[email protected]> Co-authored-by: zcfh <[email protected]>
1 parent 89eef94 commit effb574

File tree

8 files changed

+361
-1
lines changed

8 files changed

+361
-1
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//===- llvm/CodeGen/MachineBlockHashInfo.h ----------------------*- 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+
// Compute the hashes of basic blocks.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H
14+
#define LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H
15+
16+
#include "llvm/CodeGen/MachineFunctionPass.h"
17+
18+
namespace llvm {
19+
20+
/// An object wrapping several components of a basic block hash. The combined
21+
/// (blended) hash is represented and stored as one uint64_t, while individual
22+
/// components are of smaller size (e.g., uint16_t or uint8_t).
23+
struct BlendedBlockHash {
24+
private:
25+
static uint64_t combineHashes(uint16_t Hash1, uint16_t Hash2, uint16_t Hash3,
26+
uint16_t Hash4) {
27+
uint64_t Hash = 0;
28+
29+
Hash |= uint64_t(Hash4);
30+
Hash <<= 16;
31+
32+
Hash |= uint64_t(Hash3);
33+
Hash <<= 16;
34+
35+
Hash |= uint64_t(Hash2);
36+
Hash <<= 16;
37+
38+
Hash |= uint64_t(Hash1);
39+
40+
return Hash;
41+
}
42+
43+
static void parseHashes(uint64_t Hash, uint16_t &Hash1, uint16_t &Hash2,
44+
uint16_t &Hash3, uint16_t &Hash4) {
45+
Hash1 = Hash & 0xffff;
46+
Hash >>= 16;
47+
48+
Hash2 = Hash & 0xffff;
49+
Hash >>= 16;
50+
51+
Hash3 = Hash & 0xffff;
52+
Hash >>= 16;
53+
54+
Hash4 = Hash & 0xffff;
55+
Hash >>= 16;
56+
}
57+
58+
public:
59+
explicit BlendedBlockHash() {}
60+
61+
explicit BlendedBlockHash(uint64_t CombinedHash) {
62+
parseHashes(CombinedHash, Offset, OpcodeHash, InstrHash, NeighborHash);
63+
}
64+
65+
/// Combine the blended hash into uint64_t.
66+
uint64_t combine() const {
67+
return combineHashes(Offset, OpcodeHash, InstrHash, NeighborHash);
68+
}
69+
70+
/// Compute a distance between two given blended hashes. The smaller the
71+
/// distance, the more similar two blocks are. For identical basic blocks,
72+
/// the distance is zero.
73+
uint64_t distance(const BlendedBlockHash &BBH) const {
74+
assert(OpcodeHash == BBH.OpcodeHash &&
75+
"incorrect blended hash distance computation");
76+
uint64_t Dist = 0;
77+
// Account for NeighborHash
78+
Dist += NeighborHash == BBH.NeighborHash ? 0 : 1;
79+
Dist <<= 16;
80+
// Account for InstrHash
81+
Dist += InstrHash == BBH.InstrHash ? 0 : 1;
82+
Dist <<= 16;
83+
// Account for Offset
84+
Dist += (Offset >= BBH.Offset ? Offset - BBH.Offset : BBH.Offset - Offset);
85+
return Dist;
86+
}
87+
88+
/// The offset of the basic block from the function start.
89+
uint16_t Offset{0};
90+
/// (Loose) Hash of the basic block instructions, excluding operands.
91+
uint16_t OpcodeHash{0};
92+
/// (Strong) Hash of the basic block instructions, including opcodes and
93+
/// operands.
94+
uint16_t InstrHash{0};
95+
/// Hash of the (loose) basic block together with (loose) hashes of its
96+
/// successors and predecessors.
97+
uint16_t NeighborHash{0};
98+
};
99+
100+
class MachineBlockHashInfo : public MachineFunctionPass {
101+
DenseMap<unsigned, uint64_t> MBBHashInfo;
102+
103+
public:
104+
static char ID;
105+
MachineBlockHashInfo();
106+
107+
StringRef getPassName() const override { return "Basic Block Hash Compute"; }
108+
109+
void getAnalysisUsage(AnalysisUsage &AU) const override;
110+
111+
bool runOnMachineFunction(MachineFunction &F) override;
112+
113+
uint64_t getMBBHash(const MachineBasicBlock &MBB);
114+
};
115+
116+
} // end namespace llvm
117+
118+
#endif // LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ LLVM_ABI MachineFunctionPass *createBasicBlockSectionsPass();
6969

7070
LLVM_ABI MachineFunctionPass *createBasicBlockPathCloningPass();
7171

72+
/// createMachineBlockHashInfoPass - This pass computes basic block hashes.
73+
LLVM_ABI MachineFunctionPass *createMachineBlockHashInfoPass();
74+
7275
/// createMachineFunctionSplitterPass - This pass splits machine functions
7376
/// using profile information.
7477
LLVM_ABI MachineFunctionPass *createMachineFunctionSplitterPass();

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ LLVM_ABI void initializeBasicBlockSectionsPass(PassRegistry &);
6262
LLVM_ABI void initializeBarrierNoopPass(PassRegistry &);
6363
LLVM_ABI void initializeBasicAAWrapperPassPass(PassRegistry &);
6464
LLVM_ABI void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry &);
65+
LLVM_ABI void initializeMachineBlockHashInfoPass(PassRegistry &);
6566
LLVM_ABI void initializeBranchFolderLegacyPass(PassRegistry &);
6667
LLVM_ABI void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry &);
6768
LLVM_ABI void initializeBranchRelaxationLegacyPass(PassRegistry &);

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/CodeGen/GCMetadataPrinter.h"
4242
#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
4343
#include "llvm/CodeGen/MachineBasicBlock.h"
44+
#include "llvm/CodeGen/MachineBlockHashInfo.h"
4445
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
4546
#include "llvm/CodeGen/MachineConstantPool.h"
4647
#include "llvm/CodeGen/MachineDominators.h"
@@ -184,6 +185,8 @@ static cl::opt<bool> PrintLatency(
184185
cl::desc("Print instruction latencies as verbose asm comments"), cl::Hidden,
185186
cl::init(false));
186187

188+
extern cl::opt<bool> EmitBBHash;
189+
187190
STATISTIC(EmittedInsts, "Number of machine instrs printed");
188191

189192
char AsmPrinter::ID = 0;
@@ -474,6 +477,8 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
474477
AU.addRequired<GCModuleInfo>();
475478
AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
476479
AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
480+
if (EmitBBHash)
481+
AU.addRequired<MachineBlockHashInfo>();
477482
}
478483

479484
bool AsmPrinter::doInitialization(Module &M) {
@@ -1440,7 +1445,7 @@ getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,
14401445
MF.hasBBSections() && NumMBBSectionRanges > 1,
14411446
static_cast<bool>(BBAddrMapSkipEmitBBEntries),
14421447
HasCalls,
1443-
false};
1448+
static_cast<bool>(EmitBBHash)};
14441449
}
14451450

14461451
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
@@ -1499,6 +1504,9 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
14991504
PrevMBBEndSymbol = MBBSymbol;
15001505
}
15011506

1507+
auto MBHI =
1508+
Features.BBHash ? &getAnalysis<MachineBlockHashInfo>() : nullptr;
1509+
15021510
if (!Features.OmitBBEntries) {
15031511
OutStreamer->AddComment("BB id");
15041512
// Emit the BB ID for this basic block.
@@ -1526,6 +1534,10 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
15261534
emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), CurrentLabel);
15271535
// Emit the Metadata.
15281536
OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
1537+
// Emit the Hash.
1538+
if (MBHI) {
1539+
OutStreamer->emitInt64(MBHI->getMBBHash(MBB));
1540+
}
15291541
}
15301542
PrevMBBEndSymbol = MBB.getEndSymbol();
15311543
}

llvm/lib/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ add_llvm_component_library(LLVMCodeGen
108108
LowerEmuTLS.cpp
109109
MachineBasicBlock.cpp
110110
MachineBlockFrequencyInfo.cpp
111+
MachineBlockHashInfo.cpp
111112
MachineBlockPlacement.cpp
112113
MachineBranchProbabilityInfo.cpp
113114
MachineCFGPrinter.cpp
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//===- llvm/CodeGen/MachineBlockHashInfo.cpp---------------------*- 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+
// Compute the hashes of basic blocks.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/CodeGen/MachineBlockHashInfo.h"
14+
#include "llvm/CodeGen/Passes.h"
15+
#include "llvm/InitializePasses.h"
16+
#include "llvm/Target/TargetMachine.h"
17+
18+
using namespace llvm;
19+
20+
using OperandHashFuncTy =
21+
function_ref<uint64_t(uint64_t &, const MachineOperand &)>;
22+
23+
uint64_t hashBlock(const MachineBasicBlock &MBB,
24+
OperandHashFuncTy OperandHashFunc) {
25+
uint64_t Hash = 0;
26+
for (const MachineInstr &MI : MBB) {
27+
if (MI.isMetaInstruction())
28+
continue;
29+
// Ignore terminator instruction
30+
if (MI.isTerminator())
31+
continue;
32+
Hash = hashing::detail::hash_16_bytes(Hash, MI.getOpcode());
33+
for (unsigned i = 0; i < MI.getNumOperands(); i++) {
34+
Hash = OperandHashFunc(Hash, MI.getOperand(i));
35+
}
36+
}
37+
return Hash;
38+
}
39+
40+
/// Hashing a 64-bit integer to a 16-bit one.
41+
uint16_t hash_64_to_16(const uint64_t Hash) {
42+
uint16_t Res = (uint16_t)(Hash & 0xFFFF);
43+
Res ^= (uint16_t)((Hash >> 16) & 0xFFFF);
44+
Res ^= (uint16_t)((Hash >> 32) & 0xFFFF);
45+
Res ^= (uint16_t)((Hash >> 48) & 0xFFFF);
46+
return Res;
47+
}
48+
49+
uint64_t hashInstOperand(uint64_t &Hash, const MachineOperand &Operand) {
50+
return hashing::detail::hash_16_bytes(Hash, hash_value(Operand));
51+
}
52+
53+
INITIALIZE_PASS(MachineBlockHashInfo, "machine-block-hash",
54+
"Machine Block Hash Analysis", true, true)
55+
56+
char MachineBlockHashInfo::ID = 0;
57+
58+
MachineBlockHashInfo::MachineBlockHashInfo() : MachineFunctionPass(ID) {
59+
initializeMachineBlockHashInfoPass(*PassRegistry::getPassRegistry());
60+
}
61+
62+
void MachineBlockHashInfo::getAnalysisUsage(AnalysisUsage &AU) const {
63+
AU.setPreservesAll();
64+
MachineFunctionPass::getAnalysisUsage(AU);
65+
}
66+
67+
bool MachineBlockHashInfo::runOnMachineFunction(MachineFunction &F) {
68+
DenseMap<MachineBasicBlock *, BlendedBlockHash> BlendedHashes;
69+
DenseMap<MachineBasicBlock *, uint64_t> OpcodeHashes;
70+
uint16_t Offset = 0;
71+
// Initialize hash components
72+
for (MachineBasicBlock &MBB : F) {
73+
BlendedBlockHash BlendedHash;
74+
// offset of the machine basic block
75+
BlendedHash.Offset = Offset;
76+
Offset += MBB.size();
77+
// Hashing opcodes
78+
uint64_t OpcodeHash = hashBlock(
79+
MBB, [](uint64_t &Hash, const MachineOperand &Op) { return Hash; });
80+
OpcodeHashes[&MBB] = OpcodeHash;
81+
BlendedHash.OpcodeHash = hash_64_to_16(OpcodeHash);
82+
// Hash complete instructions
83+
uint64_t InstrHash = hashBlock(MBB, hashInstOperand);
84+
BlendedHash.InstrHash = hash_64_to_16(InstrHash);
85+
BlendedHashes[&MBB] = BlendedHash;
86+
}
87+
88+
// Initialize neighbor hash
89+
for (MachineBasicBlock &MBB : F) {
90+
uint64_t Hash = OpcodeHashes[&MBB];
91+
// Append hashes of successors
92+
for (MachineBasicBlock *SuccMBB : MBB.successors()) {
93+
uint64_t SuccHash = OpcodeHashes[SuccMBB];
94+
Hash = hashing::detail::hash_16_bytes(Hash, SuccHash);
95+
}
96+
// Append hashes of predecessors
97+
for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
98+
uint64_t PredHash = OpcodeHashes[PredMBB];
99+
Hash = hashing::detail::hash_16_bytes(Hash, PredHash);
100+
}
101+
BlendedHashes[&MBB].NeighborHash = hash_64_to_16(Hash);
102+
}
103+
104+
// Assign hashes
105+
for (MachineBasicBlock &MBB : F) {
106+
if (MBB.getBBID()) {
107+
MBBHashInfo[MBB.getBBID()->BaseID] = BlendedHashes[&MBB].combine();
108+
}
109+
}
110+
111+
return false;
112+
}
113+
114+
uint64_t MachineBlockHashInfo::getMBBHash(const MachineBasicBlock &MBB) {
115+
if (MBB.getBBID()) {
116+
return MBBHashInfo[MBB.getBBID()->BaseID];
117+
}
118+
return 0;
119+
}
120+
121+
MachineFunctionPass *llvm::createMachineBlockHashInfoPass() {
122+
return new MachineBlockHashInfo();
123+
}

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ static cl::opt<bool>
272272
cl::desc("Split static data sections into hot and cold "
273273
"sections using profile information"));
274274

275+
cl::opt<bool> EmitBBHash(
276+
"emit-bb-hash",
277+
cl::desc(
278+
"Emit the hash of basic block in the SHT_LLVM_BB_ADDR_MAP section."),
279+
cl::init(false), cl::Optional);
280+
275281
/// Allow standard passes to be disabled by command line options. This supports
276282
/// simple binary flags that either suppress the pass or do nothing.
277283
/// i.e. -disable-mypass=false has no effect.
@@ -1281,6 +1287,8 @@ void TargetPassConfig::addMachinePasses() {
12811287
// address map (or both).
12821288
if (TM->getBBSectionsType() != llvm::BasicBlockSection::None ||
12831289
TM->Options.BBAddrMap) {
1290+
if (EmitBBHash)
1291+
addPass(llvm::createMachineBlockHashInfoPass());
12841292
if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
12851293
addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
12861294
TM->getBBSectionsFuncListBuf()));

0 commit comments

Comments
 (0)