33#define DEBUG_TYPE "machine-block-match-infer"
37 cl::desc(
"Threshold for infer stale profile"),
42 cl::desc(
"Match basic blocks using BBIDs instead of "
43 "hashes for Propeller inference"),
50 void init(
const std::vector<MachineBasicBlock *> &Blocks,
51 const std::vector<BlendedBlockHash> &Hashes) {
52 assert(Blocks.size() == Hashes.size() &&
53 "incorrect matcher initialization");
54 for (
size_t I = 0;
I < Blocks.size();
I++) {
56 uint16_t OpHash = Hashes[
I].getOpcodeHash();
57 OpHashToBlocks[OpHash].push_back(std::make_pair(Hashes[
I],
Block));
63 auto BlockIt = OpHashToBlocks.find(BlendedHash.
getOpcodeHash());
64 if (BlockIt == OpHashToBlocks.end()) {
68 uint64_t BestDist = std::numeric_limits<uint64_t>::max();
69 for (
auto It : BlockIt->second) {
72 uint64_t Dist = Hash.
distance(BlendedHash);
73 if (BestBlock ==
nullptr || Dist < BestDist) {
82 using HashBlockPairType = std::pair<BlendedBlockHash, MachineBasicBlock *>;
87 "machine-block-match-infer",
88 "Machine Block Matching and Inference Analysis",
true,
93 "Machine Block Matching and Inference Analysis",
true,
true)
107std::optional<BasicBlockMatchingAndInference::WeightInfo>
109 auto It = ProgramWeightInfo.find(FuncName);
110 if (It == ProgramWeightInfo.end()) {
116BasicBlockMatchingAndInference::WeightInfo
117BasicBlockMatchingAndInference::initWeightInfoByMatching(
MachineFunction &MF) {
118 std::vector<MachineBasicBlock *> Blocks;
119 std::vector<BlendedBlockHash> Hashes;
122 for (
auto &
Block : MF) {
123 Blocks.push_back(&
Block);
127 Matcher.
init(Blocks, Hashes);
128 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
129 const CFGProfile *
CFG = BSPR->getFunctionCFGProfile(MF.getName());
132 for (
auto &BlockCount :
CFG->NodeCounts) {
133 if (
CFG->BBHashes.count(BlockCount.first.BaseID)) {
134 auto Hash =
CFG->BBHashes.lookup(BlockCount.first.BaseID);
137 if (
Block !=
nullptr)
138 MatchWeight.BlockWeights[
Block] += BlockCount.second;
141 for (
auto &PredItem :
CFG->EdgeCounts) {
142 auto PredID = PredItem.first.BaseID;
143 if (!
CFG->BBHashes.count(PredID))
145 auto PredHash =
CFG->BBHashes.lookup(PredID);
146 MachineBasicBlock *PredBlock =
147 Matcher.
matchBlock(BlendedBlockHash(PredHash));
148 if (PredBlock ==
nullptr)
150 for (
auto &SuccItem : PredItem.second) {
151 auto SuccID = SuccItem.first.BaseID;
152 auto EdgeWeight = SuccItem.second;
153 if (
CFG->BBHashes.count(SuccID)) {
154 auto SuccHash =
CFG->BBHashes.lookup(SuccID);
155 MachineBasicBlock *SuccBlock =
156 Matcher.
matchBlock(BlendedBlockHash(SuccHash));
158 if (SuccBlock !=
nullptr)
159 MatchWeight.EdgeWeights[std::make_pair(PredBlock, SuccBlock)] +=
167BasicBlockMatchingAndInference::WeightInfo
168BasicBlockMatchingAndInference::initWeightInfoByBBID(
MachineFunction &MF,
173 DenseMap<unsigned, MachineBasicBlock *> BaseIDToMBB;
174 for (
auto &
MBB : MF) {
177 BaseIDToMBB[BaseID] = &
MBB;
179 auto FindMBB = [&](
const UniqueBBID &BBID) {
180 return BaseIDToMBB.
lookup(BBID.BaseID);
187 DenseSet<const MachineBasicBlock *> MismatchedMBBs;
188 for (
const auto &[PredID, Succs] :
CFG.EdgeCounts) {
189 MachineBasicBlock *PredMBB = FindMBB(PredID);
190 for (
const auto &[SuccID, EdgeCount] : Succs) {
191 MachineBasicBlock *SuccMBB = FindMBB(SuccID);
192 if (PredMBB && SuccMBB && PredMBB->
isSuccessor(SuccMBB))
195 MismatchedMBBs.
insert(PredMBB);
197 MismatchedMBBs.
insert(SuccMBB);
200 DenseSet<const MachineBasicBlock *> ProfiledMBBs;
201 for (
const auto &[BBID, BlockCount] :
CFG.NodeCounts)
202 if (MachineBasicBlock *
MBB = FindMBB(BBID))
204 DenseSet<const MachineBasicBlock *> MatchedMBBs;
205 for (
auto &
MBB : MF) {
210 <<
" has profile edges that are not in the CFG\n");
215 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
216 for (
const auto &[BBID, BlockCount] :
CFG.NodeCounts) {
217 MachineBasicBlock *
MBB = FindMBB(BBID);
219 MatchWeight.BlockWeights[
MBB] += BlockCount;
221 for (
const auto &[PredID, Succs] :
CFG.EdgeCounts) {
222 MachineBasicBlock *PredMBB = FindMBB(PredID);
223 if (!PredMBB || !MatchedMBBs.
count(PredMBB))
225 for (
const auto &[SuccID, EdgeCount] : Succs) {
226 MachineBasicBlock *SuccMBB = FindMBB(SuccID);
227 if (!SuccMBB || !MatchedMBBs.
count(SuccMBB))
229 MatchWeight.EdgeWeights[std::make_pair(PredMBB, SuccMBB)] += EdgeCount;
235void BasicBlockMatchingAndInference::generateWeightInfoByInference(
237 BasicBlockMatchingAndInference::WeightInfo &MatchWeight) {
238 BlockEdgeMap Successors;
239 for (
auto &
Block : MF) {
240 for (
auto *Succ :
Block.successors())
241 Successors[&
Block].push_back(Succ);
243 SampleProfileInference<MachineFunction> SPI(
244 MF, Successors, MatchWeight.BlockWeights, MatchWeight.EdgeWeights);
245 BlockWeightMap BlockWeights;
246 EdgeWeightMap EdgeWeights;
247 SPI.apply(BlockWeights, EdgeWeights);
248 ProgramWeightInfo.try_emplace(
249 MF.getName(), BasicBlockMatchingAndInference::WeightInfo{
250 std::move(BlockWeights), std::move(EdgeWeights)});
258 if (
CFG ==
nullptr || (
CFG->NodeCounts.empty() &&
CFG->EdgeCounts.empty()))
261 BasicBlockMatchingAndInference::WeightInfo MatchWeight;
263 MatchWeight = initWeightInfoByBBID(MF, *
CFG);
265 MatchWeight = initWeightInfoByMatching(MF);
269 if (
static_cast<float>(MatchWeight.BlockWeights.
size()) / MF.
size() <
274 generateWeightInfoByInference(MF, MatchWeight);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< float > PropellerInferThreshold("propeller-infer-threshold", cl::desc("Threshold for infer stale profile"), cl::init(0.6))
static cl::opt< bool > PropellerMatchBBID("propeller-match-bbid", cl::desc("Match basic blocks using BBIDs instead of " "hashes for Propeller inference"), cl::init(false), cl::Optional)
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.
initializer< Ty > init(const Ty &Val)
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...
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.