10b57cec5SDimitry Andric //===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Loops should be simplified before this analysis. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 140b57cec5SDimitry Andric #define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 170b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h" 180b57cec5SDimitry Andric #include <cstdint> 190b57cec5SDimitry Andric #include <memory> 20bdd1243dSDimitry Andric #include <optional> 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace llvm { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric template <class BlockT> class BlockFrequencyInfoImpl; 250b57cec5SDimitry Andric class MachineBasicBlock; 260b57cec5SDimitry Andric class MachineBranchProbabilityInfo; 270b57cec5SDimitry Andric class MachineFunction; 280b57cec5SDimitry Andric class MachineLoopInfo; 290b57cec5SDimitry Andric class raw_ostream; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric /// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation 320b57cec5SDimitry Andric /// to estimate machine basic block frequencies. 330b57cec5SDimitry Andric class MachineBlockFrequencyInfo : public MachineFunctionPass { 340b57cec5SDimitry Andric using ImplType = BlockFrequencyInfoImpl<MachineBasicBlock>; 350b57cec5SDimitry Andric std::unique_ptr<ImplType> MBFI; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric public: 380b57cec5SDimitry Andric static char ID; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric MachineBlockFrequencyInfo(); 41480093f4SDimitry Andric explicit MachineBlockFrequencyInfo(MachineFunction &F, 42480093f4SDimitry Andric MachineBranchProbabilityInfo &MBPI, 43480093f4SDimitry Andric MachineLoopInfo &MLI); 440b57cec5SDimitry Andric ~MachineBlockFrequencyInfo() override; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &F) override; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// calculate - compute block frequency info for the given function. 510b57cec5SDimitry Andric void calculate(const MachineFunction &F, 520b57cec5SDimitry Andric const MachineBranchProbabilityInfo &MBPI, 530b57cec5SDimitry Andric const MachineLoopInfo &MLI); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric void releaseMemory() override; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// getblockFreq - Return block frequency. Return 0 if we don't have the 580b57cec5SDimitry Andric /// information. Please note that initial frequency is equal to 1024. It means 590b57cec5SDimitry Andric /// that we should not rely on the value itself, but only on the comparison to 600b57cec5SDimitry Andric /// the other block frequencies. We do this to avoid using of floating points. 61e8d8bef9SDimitry Andric /// For example, to get the frequency of a block relative to the entry block, 62e8d8bef9SDimitry Andric /// divide the integral value returned by this function (the 63e8d8bef9SDimitry Andric /// BlockFrequency::getFrequency() value) by getEntryFreq(). 640b57cec5SDimitry Andric BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const; 650b57cec5SDimitry Andric 66e8d8bef9SDimitry Andric /// Compute the frequency of the block, relative to the entry block. 67e8d8bef9SDimitry Andric /// This API assumes getEntryFreq() is non-zero. getBlockFreqRelativeToEntryBlock(const MachineBasicBlock * MBB)68*c9157d92SDimitry Andric double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const { 69*c9157d92SDimitry Andric assert(getEntryFreq() != BlockFrequency(0) && 70*c9157d92SDimitry Andric "getEntryFreq() should not return 0 here!"); 71*c9157d92SDimitry Andric return static_cast<double>(getBlockFreq(MBB).getFrequency()) / 72*c9157d92SDimitry Andric static_cast<double>(getEntryFreq().getFrequency()); 73e8d8bef9SDimitry Andric } 74e8d8bef9SDimitry Andric 75bdd1243dSDimitry Andric std::optional<uint64_t> 76bdd1243dSDimitry Andric getBlockProfileCount(const MachineBasicBlock *MBB) const; 77*c9157d92SDimitry Andric std::optional<uint64_t> getProfileCountFromFreq(BlockFrequency Freq) const; 780b57cec5SDimitry Andric 79e8d8bef9SDimitry Andric bool isIrrLoopHeader(const MachineBasicBlock *MBB) const; 800b57cec5SDimitry Andric 81e8d8bef9SDimitry Andric /// incrementally calculate block frequencies when we split edges, to avoid 82e8d8bef9SDimitry Andric /// full CFG traversal. 83e8d8bef9SDimitry Andric void onEdgeSplit(const MachineBasicBlock &NewPredecessor, 84e8d8bef9SDimitry Andric const MachineBasicBlock &NewSuccessor, 85e8d8bef9SDimitry Andric const MachineBranchProbabilityInfo &MBPI); 865ffd83dbSDimitry Andric 870b57cec5SDimitry Andric const MachineFunction *getFunction() const; 880b57cec5SDimitry Andric const MachineBranchProbabilityInfo *getMBPI() const; 89e8d8bef9SDimitry Andric 90e8d8bef9SDimitry Andric /// Pop up a ghostview window with the current block frequency propagation 91e8d8bef9SDimitry Andric /// rendered using dot. 920b57cec5SDimitry Andric void view(const Twine &Name, bool isSimple = true) const; 930b57cec5SDimitry Andric 94e8d8bef9SDimitry Andric /// Divide a block's BlockFrequency::getFrequency() value by this value to 95e8d8bef9SDimitry Andric /// obtain the entry block - relative frequency of said block. 96*c9157d92SDimitry Andric BlockFrequency getEntryFreq() const; 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric 99*c9157d92SDimitry Andric /// Print the block frequency @p Freq relative to the current functions entry 100*c9157d92SDimitry Andric /// frequency. Returns a Printable object that can be piped via `<<` to a 101*c9157d92SDimitry Andric /// `raw_ostream`. 102*c9157d92SDimitry Andric Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI, 103*c9157d92SDimitry Andric BlockFrequency Freq); 104*c9157d92SDimitry Andric 105*c9157d92SDimitry Andric /// Convenience function equivalent to calling 106*c9157d92SDimitry Andric /// `printBlockFreq(MBFI, MBFI.getBlockFreq(&MBB))`. 107*c9157d92SDimitry Andric Printable printBlockFreq(const MachineBlockFrequencyInfo &MBFI, 108*c9157d92SDimitry Andric const MachineBasicBlock &MBB); 109*c9157d92SDimitry Andric 1100b57cec5SDimitry Andric } // end namespace llvm 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric #endif // LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H 113