This PR re-submits the previously reverted PR(https://github.com/llvm/llvm-project/pull/165868) and fixes the return type mismatch error. Co-authored-by: lifengxiang1025 <lifengxiang@kuaishou.com> Co-authored-by: zcfh <wuminghui03@kuaishou.com>
117 lines
4.1 KiB
C++
117 lines
4.1 KiB
C++
//===- llvm/CodeGen/MachineBlockHashInfo.h ----------------------*- C++ -*-===//
|
||
//
|
||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
// See https://llvm.org/LICENSE.txt for license information.
|
||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
//
|
||
// Compute the hashes of basic blocks.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
#ifndef LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H
|
||
#define LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H
|
||
|
||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||
|
||
namespace llvm {
|
||
|
||
/// An object wrapping several components of a basic block hash. The combined
|
||
/// (blended) hash is represented and stored as one uint64_t, while individual
|
||
/// components are of smaller size (e.g., uint16_t or uint8_t).
|
||
struct BlendedBlockHash {
|
||
public:
|
||
explicit BlendedBlockHash(uint16_t Offset, uint16_t OpcodeHash,
|
||
uint16_t InstrHash, uint16_t NeighborHash)
|
||
: Offset(Offset), OpcodeHash(OpcodeHash), InstrHash(InstrHash),
|
||
NeighborHash(NeighborHash) {}
|
||
|
||
explicit BlendedBlockHash(uint64_t CombinedHash) {
|
||
Offset = CombinedHash & 0xffff;
|
||
CombinedHash >>= 16;
|
||
OpcodeHash = CombinedHash & 0xffff;
|
||
CombinedHash >>= 16;
|
||
InstrHash = CombinedHash & 0xffff;
|
||
CombinedHash >>= 16;
|
||
NeighborHash = CombinedHash & 0xffff;
|
||
}
|
||
|
||
/// Combine the blended hash into uint64_t.
|
||
uint64_t combine() const {
|
||
uint64_t Hash = 0;
|
||
Hash |= uint64_t(NeighborHash);
|
||
Hash <<= 16;
|
||
Hash |= uint64_t(InstrHash);
|
||
Hash <<= 16;
|
||
Hash |= uint64_t(OpcodeHash);
|
||
Hash <<= 16;
|
||
Hash |= uint64_t(Offset);
|
||
return Hash;
|
||
}
|
||
|
||
/// Compute a distance between two given blended hashes. The smaller the
|
||
/// distance, the more similar two blocks are. For identical basic blocks,
|
||
/// the distance is zero.
|
||
/// Since OpcodeHash is highly stable, we consider a match good only if
|
||
/// the OpcodeHashes are identical. Mismatched OpcodeHashes lead to low
|
||
/// matching accuracy, and poor matches undermine the quality of final
|
||
/// inference. Notably, during inference, we also consider the matching
|
||
/// ratio of basic blocks. For MachineFunctions with a low matching
|
||
/// ratio, we directly skip optimization to reduce the impact of
|
||
/// mismatches. This ensures even very poor profiles won’t cause negative
|
||
/// optimization.
|
||
/// In the context of matching, we consider NeighborHash to be more
|
||
/// important. This is especially true when accounting for inlining
|
||
/// scenarios, where the position of a basic block in the control
|
||
/// flow graph is more critical.
|
||
uint64_t distance(const BlendedBlockHash &BBH) const {
|
||
assert(OpcodeHash == BBH.OpcodeHash &&
|
||
"incorrect blended hash distance computation");
|
||
uint64_t Dist = 0;
|
||
// Account for NeighborHash
|
||
Dist += NeighborHash == BBH.NeighborHash ? 0 : 1;
|
||
Dist <<= 16;
|
||
// Account for InstrHash
|
||
Dist += InstrHash == BBH.InstrHash ? 0 : 1;
|
||
Dist <<= 16;
|
||
// Account for Offset
|
||
Dist += (Offset >= BBH.Offset ? Offset - BBH.Offset : BBH.Offset - Offset);
|
||
return Dist;
|
||
}
|
||
|
||
uint16_t getOpcodeHash() const { return OpcodeHash; }
|
||
|
||
private:
|
||
/// The offset of the basic block from the function start.
|
||
uint16_t Offset{0};
|
||
/// Hash of the basic block instructions, excluding operands.
|
||
uint16_t OpcodeHash{0};
|
||
/// Hash of the basic block instructions, including opcodes and
|
||
/// operands.
|
||
uint16_t InstrHash{0};
|
||
/// OpcodeHash of the basic block together with OpcodeHashes of its
|
||
/// successors and predecessors.
|
||
uint16_t NeighborHash{0};
|
||
};
|
||
|
||
class MachineBlockHashInfo : public MachineFunctionPass {
|
||
DenseMap<const MachineBasicBlock *, uint64_t> MBBHashInfo;
|
||
|
||
public:
|
||
static char ID;
|
||
MachineBlockHashInfo();
|
||
|
||
StringRef getPassName() const override { return "Basic Block Hash Compute"; }
|
||
|
||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||
|
||
bool runOnMachineFunction(MachineFunction &F) override;
|
||
|
||
uint64_t getMBBHash(const MachineBasicBlock &MBB);
|
||
};
|
||
|
||
} // end namespace llvm
|
||
|
||
#endif // LLVM_CODEGEN_MACHINEBLOCKHASHINFO_H
|