33#define DEBUG_TYPE "machine-block-match-infer"
39 void init(
const std::vector<MachineBasicBlock *> &Blocks,
40 const std::vector<BlendedBlockHash> &Hashes) {
41 assert(Blocks.size() == Hashes.size() &&
42 "incorrect matcher initialization");
43 for (
size_t I = 0;
I < Blocks.size();
I++) {
45 uint16_t OpHash = Hashes[
I].getOpcodeHash();
46 OpHashToBlocks[OpHash].push_back(std::make_pair(Hashes[
I],
Block));
52 auto BlockIt = OpHashToBlocks.find(BlendedHash.
getOpcodeHash());
53 if (BlockIt == OpHashToBlocks.end()) {
57 uint64_t BestDist = std::numeric_limits<uint64_t>::max();
58 for (
auto It : BlockIt->second) {
61 uint64_t Dist = Hash.
distance(BlendedHash);
62 if (BestBlock ==
nullptr || Dist < BestDist) {
71 using HashBlockPairType = std::pair<BlendedBlockHash, MachineBasicBlock *>;
76 "machine-block-match-infer",
77 "Machine Block Matching and Inference Analysis",
true,
82 "Machine Block Matching and Inference Analysis",
true,
true)
96std::optional<BasicBlockMatchingAndInference::WeightInfo>
98 auto It = ProgramWeightInfo.find(FuncName);
99 if (It == ProgramWeightInfo.end()) {
105BasicBlockMatchingAndInference::WeightInfo
106BasicBlockMatchingAndInference::initWeightInfoByMatching(
MachineFunction &MF) {
107 std::vector<MachineBasicBlock *> Blocks;
108 std::vector<BlendedBlockHash> Hashes;
111 for (
auto &
Block : MF) {
112 Blocks.push_back(&
Block);
116 Matcher.
init(Blocks, Hashes);
117 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
118 const CFGProfile *
CFG = BSPR->getFunctionCFGProfile(MF.getName());
121 for (
auto &BlockCount :
CFG->NodeCounts) {
122 if (
CFG->BBHashes.count(BlockCount.first.BaseID)) {
123 auto Hash =
CFG->BBHashes.lookup(BlockCount.first.BaseID);
126 if (
Block !=
nullptr)
127 MatchWeight.BlockWeights[
Block] += BlockCount.second;
130 for (
auto &PredItem :
CFG->EdgeCounts) {
131 auto PredID = PredItem.first.BaseID;
132 if (!
CFG->BBHashes.count(PredID))
134 auto PredHash =
CFG->BBHashes.lookup(PredID);
135 MachineBasicBlock *PredBlock =
136 Matcher.
matchBlock(BlendedBlockHash(PredHash));
137 if (PredBlock ==
nullptr)
139 for (
auto &SuccItem : PredItem.second) {
140 auto SuccID = SuccItem.first.BaseID;
141 auto EdgeWeight = SuccItem.second;
142 if (
CFG->BBHashes.count(SuccID)) {
143 auto SuccHash =
CFG->BBHashes.lookup(SuccID);
144 MachineBasicBlock *SuccBlock =
145 Matcher.
matchBlock(BlendedBlockHash(SuccHash));
147 if (SuccBlock !=
nullptr)
148 MatchWeight.EdgeWeights[std::make_pair(PredBlock, SuccBlock)] +=
156BasicBlockMatchingAndInference::WeightInfo
157BasicBlockMatchingAndInference::initWeightInfoByBBID(
MachineFunction &MF,
163 DenseMap<UniqueBBID, MachineBasicBlock *> BBIDToMBB;
166 auto FindMBB = [&](
const UniqueBBID &BBID) {
167 if (MachineBasicBlock *
MBB = BBIDToMBB.
lookup(BBID))
169 return BBIDToMBB.
lookup(UniqueBBID{BBID.BaseID, 0});
176 DenseSet<const MachineBasicBlock *> MismatchedMBBs;
177 for (
const auto &[PredID, Succs] :
CFG.EdgeCounts) {
178 MachineBasicBlock *PredMBB = FindMBB(PredID);
179 for (
const auto &[SuccID, EdgeCount] : Succs) {
180 MachineBasicBlock *SuccMBB = FindMBB(SuccID);
181 if (PredMBB && SuccMBB && PredMBB->
isSuccessor(SuccMBB))
184 MismatchedMBBs.
insert(PredMBB);
186 MismatchedMBBs.
insert(SuccMBB);
189 DenseSet<const MachineBasicBlock *> ProfiledMBBs;
190 for (
const auto &[BBID, BlockCount] :
CFG.NodeCounts)
191 if (MachineBasicBlock *
MBB = FindMBB(BBID))
193 DenseSet<const MachineBasicBlock *> MatchedMBBs;
194 for (
auto &
MBB : MF) {
199 <<
" has profile edges that are not in the CFG\n");
204 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
205 for (
const auto &[BBID, BlockCount] :
CFG.NodeCounts) {
206 MachineBasicBlock *
MBB = FindMBB(BBID);
208 MatchWeight.BlockWeights[
MBB] += BlockCount;
210 for (
const auto &[PredID, Succs] :
CFG.EdgeCounts) {
211 MachineBasicBlock *PredMBB = FindMBB(PredID);
212 if (!PredMBB || !MatchedMBBs.
count(PredMBB))
214 for (
const auto &[SuccID, EdgeCount] : Succs) {
215 MachineBasicBlock *SuccMBB = FindMBB(SuccID);
216 if (!SuccMBB || !MatchedMBBs.
count(SuccMBB))
218 MatchWeight.EdgeWeights[std::make_pair(PredMBB, SuccMBB)] += EdgeCount;
224void BasicBlockMatchingAndInference::generateWeightInfoByInference(
226 BasicBlockMatchingAndInference::WeightInfo &MatchWeight) {
227 BlockEdgeMap Successors;
228 for (
auto &
Block : MF) {
229 for (
auto *Succ :
Block.successors())
230 Successors[&
Block].push_back(Succ);
232 SampleProfileInference<MachineFunction> SPI(
233 MF, Successors, MatchWeight.BlockWeights, MatchWeight.EdgeWeights);
234 BlockWeightMap BlockWeights;
235 EdgeWeightMap EdgeWeights;
236 SPI.apply(BlockWeights, EdgeWeights);
237 ProgramWeightInfo.try_emplace(
238 MF.getName(), BasicBlockMatchingAndInference::WeightInfo{
239 std::move(BlockWeights), std::move(EdgeWeights)});
247 if (
CFG ==
nullptr || (
CFG->NodeCounts.empty() &&
CFG->EdgeCounts.empty()))
251 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
252 if (Opts.propeller_match_bbid) {
253 MatchWeight = initWeightInfoByBBID(MF, *
CFG);
255 MatchWeight = initWeightInfoByMatching(MF);
259 if (
static_cast<float>(MatchWeight.BlockWeights.
size()) / MF.
size() <
260 Opts.propeller_infer_threshold) {
264 generateWeightInfoByInference(MF, MatchWeight);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
The object is used to identify and match basic blocks given their hashes.
void init(const std::vector< MachineBasicBlock * > &Blocks, const std::vector< BlendedBlockHash > &Hashes)
Initialize stale matcher.
MachineBasicBlock * matchBlock(BlendedBlockHash BlendedHash) const
Find the most similar block for a given hash.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
std::optional< WeightInfo > getWeightInfo(StringRef FuncName) const
bool runOnMachineFunction(MachineFunction &F) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
BasicBlockMatchingAndInference()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
std::optional< UniqueBBID > getBBID() const
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
Legacy MachineFunctionPass for MachineBlockHashInfo.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
Represent a constant reference to a string, i.e.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI MachineFunctionPass * createBasicBlockMatchingAndInferencePass()
createBasicBlockMatchingAndInferencePass - This pass enables matching and inference when using propel...
const CodeGenOptions & getCodeGenOptions(const LLVMContext &C)
An object wrapping several components of a basic block hash.
uint16_t getOpcodeHash() const
uint64_t distance(const BlendedBlockHash &BBH) const
Compute a distance between two given blended hashes.