1 //===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -----*- 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 // Loops should be simplified before this analysis. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 14 #define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 15 16 #include "llvm/CodeGen/MachineFunctionPass.h" 17 #include "llvm/CodeGen/MachinePassManager.h" 18 #include "llvm/Support/BlockFrequency.h" 19 #include <cstdint> 20 #include <memory> 21 #include <optional> 22 23 namespace llvm { 24 25 template <class BlockT> class BlockFrequencyInfoImpl; 26 class MachineBasicBlock; 27 class MachineBranchProbabilityInfo; 28 class MachineFunction; 29 class MachineLoopInfo; 30 class raw_ostream; 31 32 /// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation 33 /// to estimate machine basic block frequencies. 34 class MachineBlockFrequencyInfo { 35 using ImplType = BlockFrequencyInfoImpl<MachineBasicBlock>; 36 std::unique_ptr<ImplType> MBFI; 37 38 public: 39 MachineBlockFrequencyInfo(); // Legacy pass manager only. 40 explicit MachineBlockFrequencyInfo(MachineFunction &F, 41 MachineBranchProbabilityInfo &MBPI, 42 MachineLoopInfo &MLI); 43 MachineBlockFrequencyInfo(MachineBlockFrequencyInfo &&); 44 ~MachineBlockFrequencyInfo(); 45 46 /// Handle invalidation explicitly. 47 bool invalidate(MachineFunction &F, const PreservedAnalyses &PA, 48 MachineFunctionAnalysisManager::Invalidator &); 49 50 /// calculate - compute block frequency info for the given function. 51 void calculate(const MachineFunction &F, 52 const MachineBranchProbabilityInfo &MBPI, 53 const MachineLoopInfo &MLI); 54 55 void print(raw_ostream &OS); 56 57 void releaseMemory(); 58 59 /// getblockFreq - Return block frequency. Return 0 if we don't have the 60 /// information. Please note that initial frequency is equal to 1024. It means 61 /// that we should not rely on the value itself, but only on the comparison to 62 /// the other block frequencies. We do this to avoid using of floating points. 63 /// For example, to get the frequency of a block relative to the entry block, 64 /// divide the integral value returned by this function (the 65 /// BlockFrequency::getFrequency() value) by getEntryFreq(). 66 BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const; 67 68 /// Compute the frequency of the block, relative to the entry block. 69 /// This API assumes getEntryFreq() is non-zero. getBlockFreqRelativeToEntryBlock(const MachineBasicBlock * MBB)70 double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const { 71 assert(getEntryFreq() != BlockFrequency(0) && 72 "getEntryFreq() should not return 0 here!"); 73 return static_cast<double>(getBlockFreq(MBB).getFrequency()) / 74 static_cast<double>(getEntryFreq().getFrequency()); 75 } 76 77 std::optional<uint64_t> 78 getBlockProfileCount(const MachineBasicBlock *MBB) const; 79 std::optional<uint64_t> getProfileCountFromFreq(BlockFrequency Freq) const; 80 81 bool isIrrLoopHeader(const MachineBasicBlock *MBB) const; 82 83 /// incrementally calculate block frequencies when we split edges, to avoid 84 /// full CFG traversal. 85 void onEdgeSplit(const MachineBasicBlock &NewPredecessor, 86 const MachineBasicBlock &NewSuccessor, 87 const MachineBranchProbabilityInfo &MBPI); 88 89 const MachineFunction *getFunction() const; 90 const MachineBranchProbabilityInfo *getMBPI() const; 91 92 /// Pop up a ghostview window with the current block frequency propagation 93 /// rendered using dot. 94 void view(const Twine &Name, bool isSimple = true) const; 95 96 /// Divide a block's BlockFrequency::getFrequency() value by this value to 97 /// obtain the entry block - relative frequency of said block. 98 BlockFrequency getEntryFreq() const; 99 }; 100 101 /// Print the block frequency @p Freq relative to the current functions entry 102 /// frequency. Returns a Printable object that can be piped via `<<` to a 103 /// `raw_ostream`. 104 Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI, 105 BlockFrequency Freq); 106 107 /// Convenience function equivalent to calling 108 /// `printBlockFreq(MBFI, MBFI.getBlockFreq(&MBB))`. 109 Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI, 110 const MachineBasicBlock &MBB); 111 112 class MachineBlockFrequencyAnalysis 113 : public AnalysisInfoMixin<MachineBlockFrequencyAnalysis> { 114 friend AnalysisInfoMixin<MachineBlockFrequencyAnalysis>; 115 static AnalysisKey Key; 116 117 public: 118 using Result = MachineBlockFrequencyInfo; 119 120 Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM); 121 }; 122 123 /// Printer pass for the \c MachineBlockFrequencyInfo results. 124 class MachineBlockFrequencyPrinterPass 125 : public PassInfoMixin<MachineBlockFrequencyPrinterPass> { 126 raw_ostream &OS; 127 128 public: MachineBlockFrequencyPrinterPass(raw_ostream & OS)129 explicit MachineBlockFrequencyPrinterPass(raw_ostream &OS) : OS(OS) {} 130 131 PreservedAnalyses run(MachineFunction &MF, 132 MachineFunctionAnalysisManager &MFAM); 133 isRequired()134 static bool isRequired() { return true; } 135 }; 136 137 class MachineBlockFrequencyInfoWrapperPass : public MachineFunctionPass { 138 MachineBlockFrequencyInfo MBFI; 139 140 public: 141 static char ID; 142 143 MachineBlockFrequencyInfoWrapperPass(); 144 145 void getAnalysisUsage(AnalysisUsage &AU) const override; 146 147 bool runOnMachineFunction(MachineFunction &F) override; 148 releaseMemory()149 void releaseMemory() override { MBFI.releaseMemory(); } 150 getMBFI()151 MachineBlockFrequencyInfo &getMBFI() { return MBFI; } 152 getMBFI()153 const MachineBlockFrequencyInfo &getMBFI() const { return MBFI; } 154 }; 155 } // end namespace llvm 156 157 #endif // LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 158