Skip to content

Commit 0c7685b

Browse files
openeuler-ci-botgitee-org
authored andcommitted
!163 [Propeller] Match the hash value of BB to adapt to source drift
From: @xiajingze Reviewed-by: @liyunfei33 Signed-off-by: @liyunfei33
2 parents 3f4883e + 52388ca commit 0c7685b

29 files changed

+323
-59
lines changed

llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@
2828
#include "llvm/Support/LineIterator.h"
2929
#include "llvm/Support/MemoryBuffer.h"
3030
#include "llvm/Target/TargetMachine.h"
31+
#include "llvm/Support/CommandLine.h"
3132

3233
using namespace llvm;
3334

3435
namespace llvm {
3536

37+
extern cl::opt<bool> BBSectionsMatchHash;
38+
3639
// This struct represents the cluster information for a machine basic block,
3740
// which is specifed by a unique ID (`MachineBasicBlock::BBID`).
3841
struct BBClusterInfo {
@@ -65,13 +68,22 @@ template <> struct DenseMapInfo<UniqueBBID> {
6568
return UniqueBBID{TombstoneKey, TombstoneKey};
6669
}
6770
static unsigned getHashValue(const UniqueBBID &Val) {
71+
if (BBSectionsMatchHash) {
72+
std::pair<uint64_t, unsigned> PairVal =
73+
std::make_pair(Val.Hash, Val.CloneID);
74+
return DenseMapInfo<std::pair<uint64_t, unsigned>>::getHashValue(PairVal);
75+
}
6876
std::pair<unsigned, unsigned> PairVal =
6977
std::make_pair(Val.BaseID, Val.CloneID);
7078
return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal);
7179
}
7280
static bool isEqual(const UniqueBBID &LHS, const UniqueBBID &RHS) {
81+
if (BBSectionsMatchHash) {
82+
return DenseMapInfo<uint64_t>::isEqual(LHS.Hash, RHS.Hash) &&
83+
DenseMapInfo<unsigned>::isEqual(LHS.CloneID, RHS.CloneID);
84+
}
7385
return DenseMapInfo<unsigned>::isEqual(LHS.BaseID, RHS.BaseID) &&
74-
DenseMapInfo<unsigned>::isEqual(LHS.CloneID, RHS.CloneID);
86+
DenseMapInfo<unsigned>::isEqual(LHS.CloneID, RHS.CloneID);
7587
}
7688
};
7789

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ template <> struct DenseMapInfo<MBBSectionID> {
100100
// the basic block sections profile.
101101
struct UniqueBBID {
102102
unsigned BaseID;
103+
uint64_t Hash;
103104
unsigned CloneID;
104105
};
105106

@@ -677,9 +678,13 @@ class MachineBasicBlock
677678

678679
std::optional<UniqueBBID> getBBID() const { return BBID; }
679680

681+
uint64_t getHash() const { return BBID->Hash; }
682+
680683
/// Returns the section ID of this basic block.
681684
MBBSectionID getSectionID() const { return SectionID; }
682685

686+
void setHash(uint64_t Hash) { BBID->Hash = Hash; }
687+
683688
/// Sets the fixed BBID of this basic block.
684689
void setBBID(const UniqueBBID &V) {
685690
assert(!BBID.has_value() && "Cannot change BBID.");

llvm/include/llvm/Object/ELFTypes.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -910,9 +910,11 @@ struct BBAddrMap {
910910
uint32_t Size = 0; // Size of the basic block.
911911
Metadata MD = {false, false, false, false,
912912
false}; // Metdata for this basic block.
913+
uint64_t Hash = 0; // Hash value of the basic block.
913914

914-
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
915-
: ID(ID), Offset(Offset), Size(Size), MD(MD){};
915+
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD,
916+
uint64_t Hash)
917+
: ID(ID), Offset(Offset), Size(Size), MD(MD), Hash(Hash){};
916918

917919
bool operator==(const BBEntry &Other) const {
918920
return ID == Other.ID && Offset == Other.Offset && Size == Other.Size &&

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct BBAddrMapEntry {
162162
llvm::yaml::Hex64 AddressOffset;
163163
llvm::yaml::Hex64 Size;
164164
llvm::yaml::Hex64 Metadata;
165+
llvm::yaml::Hex64 Hash;
165166
};
166167
uint8_t Version;
167168
llvm::yaml::Hex8 Feature;

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,8 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
14251425
emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
14261426
// Emit the Metadata.
14271427
OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
1428+
OutStreamer->AddComment("hash value");
1429+
OutStreamer->emitULEB128IntValue(MBB.getHash());
14281430
PrevMBBEndSymbol = MBB.getEndSymbol();
14291431
}
14301432

llvm/lib/CodeGen/BasicBlockPathCloning.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ MachineBasicBlock *CloneMachineBasicBlock(MachineBasicBlock &OrigBB,
5656
auto TII = MF.getSubtarget().getInstrInfo();
5757
// Create the clone block and set its BBID based on the original block.
5858
MachineBasicBlock *CloneBB = MF.CreateMachineBasicBlock(
59-
OrigBB.getBasicBlock(), UniqueBBID{OrigBB.getBBID()->BaseID, CloneID});
59+
OrigBB.getBasicBlock(), UniqueBBID{OrigBB.getBBID()->BaseID,
60+
OrigBB.getBBID()->Hash, CloneID});
6061
MF.push_back(CloneBB);
6162

6263
// Copy the instructions.

llvm/lib/CodeGen/BasicBlockSections.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,15 @@
7070

7171
#include "llvm/ADT/SmallVector.h"
7272
#include "llvm/ADT/StringRef.h"
73+
#include "llvm/ADT/Hashing.h"
7374
#include "llvm/CodeGen/BasicBlockSectionUtils.h"
7475
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
7576
#include "llvm/CodeGen/MachineFunction.h"
7677
#include "llvm/CodeGen/MachineFunctionPass.h"
7778
#include "llvm/CodeGen/Passes.h"
7879
#include "llvm/CodeGen/TargetInstrInfo.h"
7980
#include "llvm/InitializePasses.h"
81+
#include "llvm/IR/Constants.h"
8082
#include "llvm/Target/TargetMachine.h"
8183
#include <optional>
8284

@@ -289,12 +291,43 @@ bool llvm::hasInstrProfHashMismatch(MachineFunction &MF) {
289291
return false;
290292
}
291293

294+
void computeBBHash(MachineFunction &MF) {
295+
for (auto &MBB : MF) {
296+
llvm::hash_code Hash = llvm::hash_value(0);
297+
for (const MachineInstr &MI : MBB) {
298+
if (MI.isPseudo() || MI.isDebugOrPseudoInstr())
299+
continue;
300+
if (MI.isUnconditionalBranch())
301+
continue;
302+
Hash = llvm::hash_combine(Hash, MI.getOpcode());
303+
304+
for (const MachineOperand &MO : MI.operands()) {
305+
if (MO.isReg()) {
306+
Hash = llvm::hash_combine(Hash, MO.getReg());
307+
} else if (MO.isImm()) {
308+
Hash = llvm::hash_combine(Hash, MO.getImm());
309+
} else if (MO.isCImm()) {
310+
Hash = llvm::hash_combine(Hash, MO.getCImm()->getZExtValue());
311+
} else if (MO.isFPImm()) {
312+
Hash = llvm::hash_combine(Hash, MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
313+
} else if (MO.isGlobal()) {
314+
Hash = llvm::hash_combine(Hash, MO.getGlobal()->getName());
315+
} else if (MO.isSymbol()) {
316+
Hash = llvm::hash_combine(Hash, MO.getSymbolName());
317+
}
318+
}
319+
}
320+
MBB.setHash(Hash);
321+
}
322+
}
323+
292324
// Identify, arrange, and modify basic blocks which need separate sections
293325
// according to the specification provided by the -fbasic-block-sections flag.
294326
bool BasicBlockSections::handleBBSections(MachineFunction &MF) {
295327
auto BBSectionsType = MF.getTarget().getBBSectionsType();
296328
if (BBSectionsType == BasicBlockSection::None)
297329
return false;
330+
computeBBHash(MF);
298331

299332
// Check for source drift. If the source has changed since the profiles
300333
// were obtained, optimizing basic blocks might be sub-optimal.
@@ -384,6 +417,7 @@ bool BasicBlockSections::handleBBAddrMap(MachineFunction &MF) {
384417
return false;
385418
if (!MF.getTarget().Options.BBAddrMap)
386419
return false;
420+
computeBBHash(MF);
387421
MF.RenumberBlocks();
388422
return true;
389423
}

llvm/lib/CodeGen/BasicBlockSectionsProfileReader.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030

3131
using namespace llvm;
3232

33+
namespace llvm {
34+
cl::opt<bool> BBSectionsMatchHash(
35+
"bbsections-match-hash",
36+
cl::desc("This matches basic blocks by hash to fit source drift"),
37+
cl::init(false), cl::Hidden);
38+
}
39+
3340
char BasicBlockSectionsProfileReaderWrapperPass::ID = 0;
3441
INITIALIZE_PASS(BasicBlockSectionsProfileReaderWrapperPass,
3542
"bbsections-profile-reader",
@@ -41,18 +48,29 @@ BasicBlockSectionsProfileReader::parseUniqueBBID(StringRef S) const {
4148
SmallVector<StringRef, 2> Parts;
4249
S.split(Parts, '.');
4350
if (Parts.size() > 2)
44-
return createProfileParseError(Twine("unable to parse basic block id: '") +
51+
return createProfileParseError(Twine("unable to parse unique basic block id: '") +
4552
S + "'");
46-
unsigned long long BaseBBID;
47-
if (getAsUnsignedInteger(Parts[0], 10, BaseBBID))
53+
SmallVector<StringRef, 2> IdAndHash;
54+
Parts[0].split(IdAndHash, '-');
55+
if (IdAndHash.size() > 2)
56+
return createProfileParseError(Twine("unable to parse basic block id and hash: '") +
57+
Parts[0] + "'");
58+
unsigned long long BaseBBID = 0;
59+
if (getAsUnsignedInteger(IdAndHash[0], 10, BaseBBID))
4860
return createProfileParseError(
49-
Twine("unable to parse BB id: '" + Parts[0]) +
61+
Twine("unable to parse BB id: '" + IdAndHash[0]) +
5062
"': unsigned integer expected");
63+
unsigned long long BBHash = 0;
64+
if (IdAndHash.size() > 1 && getAsUnsignedInteger(IdAndHash[1], 16, BBHash))
65+
return createProfileParseError(
66+
Twine("unable to parse BB hash: '" + IdAndHash[1]) +
67+
"': hex unsigned integer expected");
5168
unsigned long long CloneID = 0;
5269
if (Parts.size() > 1 && getAsUnsignedInteger(Parts[1], 10, CloneID))
5370
return createProfileParseError(Twine("unable to parse clone id: '") +
5471
Parts[1] + "': unsigned integer expected");
5572
return UniqueBBID{static_cast<unsigned>(BaseBBID),
73+
static_cast<uint64_t>(BBHash),
5674
static_cast<unsigned>(CloneID)};
5775
}
5876

llvm/lib/Object/ELF.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
858858
uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
859859
uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
860860
uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
861+
uint64_t Hash = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);
861862
if (Version >= 1) {
862863
// Offset is calculated relative to the end of the previous BB.
863864
Offset += PrevBBEndOffset;
@@ -869,7 +870,7 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
869870
MetadataDecodeErr = MetadataOrErr.takeError();
870871
break;
871872
}
872-
BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
873+
BBEntries.push_back({ID, Offset, Size, *MetadataOrErr, Hash});
873874
}
874875
TotalNumBlocks += BBEntries.size();
875876
BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,7 @@ void ELFState<ELFT>::writeSectionContent(
15091509
SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);
15101510
SHeader.sh_size += CBA.writeULEB128(BBE.Size);
15111511
SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);
1512+
SHeader.sh_size += CBA.writeULEB128(BBE.Hash);
15121513
}
15131514
}
15141515
if (!PGOAnalyses)

0 commit comments

Comments
 (0)