diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp new file mode 100644 index 000000000000..53a35b7e89c2 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -0,0 +1,264 @@ +//===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Loops should be simplified before this analysis. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Analysis/BlockFrequencyInfoImpl.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/GraphWriter.h" +#include <string> + +using namespace llvm; + +#define DEBUG_TYPE "machine-block-freq" + +static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG( + "view-machine-block-freq-propagation-dags", cl::Hidden, + cl::desc("Pop up a window to show a dag displaying how machine block " + "frequencies propagate through the CFG."), + cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."), + clEnumValN(GVDT_Fraction, "fraction", + "display a graph using the " + "fractional block frequency representation."), + clEnumValN(GVDT_Integer, "integer", + "display a graph using the raw " + "integer fractional block frequency representation."), + clEnumValN(GVDT_Count, "count", "display a graph using the real " + "profile count if available."))); + +// Similar option above, but used to control BFI display only after MBP pass +cl::opt<GVDAGType> ViewBlockLayoutWithBFI( + "view-block-layout-with-bfi", cl::Hidden, + cl::desc( + "Pop up a window to show a dag displaying MBP layout and associated " + "block frequencies of the CFG."), + cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."), + clEnumValN(GVDT_Fraction, "fraction", + "display a graph using the " + "fractional block frequency representation."), + clEnumValN(GVDT_Integer, "integer", + "display a graph using the raw " + "integer fractional block frequency representation."), + clEnumValN(GVDT_Count, "count", + "display a graph using the real " + "profile count if available."))); + +// Command line option to specify the name of the function for CFG dump +// Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name= +extern cl::opt<std::string> ViewBlockFreqFuncName; + +// Command line option to specify hot frequency threshold. +// Defined in Analysis/BlockFrequencyInfo.cpp: -view-hot-freq-perc= +extern cl::opt<unsigned> ViewHotFreqPercent; + +static cl::opt<bool> PrintMachineBlockFreq( + "print-machine-bfi", cl::init(false), cl::Hidden, + cl::desc("Print the machine block frequency info.")); + +// Command line option to specify the name of the function for block frequency +// dump. Defined in Analysis/BlockFrequencyInfo.cpp. +extern cl::opt<std::string> PrintBlockFreqFuncName; + +static GVDAGType getGVDT() { + if (ViewBlockLayoutWithBFI != GVDT_None) + return ViewBlockLayoutWithBFI; + + return ViewMachineBlockFreqPropagationDAG; +} + +namespace llvm { + +template <> struct GraphTraits<MachineBlockFrequencyInfo *> { + using NodeRef = const MachineBasicBlock *; + using ChildIteratorType = MachineBasicBlock::const_succ_iterator; + using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>; + + static NodeRef getEntryNode(const MachineBlockFrequencyInfo *G) { + return &G->getFunction()->front(); + } + + static ChildIteratorType child_begin(const NodeRef N) { + return N->succ_begin(); + } + + static ChildIteratorType child_end(const NodeRef N) { return N->succ_end(); } + + static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) { + return nodes_iterator(G->getFunction()->begin()); + } + + static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) { + return nodes_iterator(G->getFunction()->end()); + } +}; + +using MBFIDOTGraphTraitsBase = + BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo, + MachineBranchProbabilityInfo>; + +template <> +struct DOTGraphTraits<MachineBlockFrequencyInfo *> + : public MBFIDOTGraphTraitsBase { + const MachineFunction *CurFunc = nullptr; + DenseMap<const MachineBasicBlock *, int> LayoutOrderMap; + + explicit DOTGraphTraits(bool isSimple = false) + : MBFIDOTGraphTraitsBase(isSimple) {} + + std::string getNodeLabel(const MachineBasicBlock *Node, + const MachineBlockFrequencyInfo *Graph) { + int layout_order = -1; + // Attach additional ordering information if 'isSimple' is false. + if (!isSimple()) { + const MachineFunction *F = Node->getParent(); + if (!CurFunc || F != CurFunc) { + if (CurFunc) + LayoutOrderMap.clear(); + + CurFunc = F; + int O = 0; + for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) { + LayoutOrderMap[&*MBI] = O; + } + } + layout_order = LayoutOrderMap[Node]; + } + return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(), + layout_order); + } + + std::string getNodeAttributes(const MachineBasicBlock *Node, + const MachineBlockFrequencyInfo *Graph) { + return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph, + ViewHotFreqPercent); + } + + std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI, + const MachineBlockFrequencyInfo *MBFI) { + return MBFIDOTGraphTraitsBase::getEdgeAttributes( + Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent); + } +}; + +} // end namespace llvm + +INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, DEBUG_TYPE, + "Machine Block Frequency Analysis", true, true) +INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_END(MachineBlockFrequencyInfo, DEBUG_TYPE, + "Machine Block Frequency Analysis", true, true) + +char MachineBlockFrequencyInfo::ID = 0; + +MachineBlockFrequencyInfo::MachineBlockFrequencyInfo() + : MachineFunctionPass(ID) { + initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry()); +} + +MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default; + +void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<MachineBranchProbabilityInfo>(); + AU.addRequired<MachineLoopInfo>(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +void MachineBlockFrequencyInfo::calculate( + const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI, + const MachineLoopInfo &MLI) { + if (!MBFI) + MBFI.reset(new ImplType); + MBFI->calculate(F, MBPI, MLI); + if (ViewMachineBlockFreqPropagationDAG != GVDT_None && + (ViewBlockFreqFuncName.empty() || + F.getName().equals(ViewBlockFreqFuncName))) { + view("MachineBlockFrequencyDAGS." + F.getName()); + } + if (PrintMachineBlockFreq && + (PrintBlockFreqFuncName.empty() || + F.getName().equals(PrintBlockFreqFuncName))) { + MBFI->print(dbgs()); + } +} + +bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { + MachineBranchProbabilityInfo &MBPI = + getAnalysis<MachineBranchProbabilityInfo>(); + MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); + calculate(F, MBPI, MLI); + return false; +} + +void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); } + +/// Pop up a ghostview window with the current block frequency propagation +/// rendered using dot. +void MachineBlockFrequencyInfo::view(const Twine &Name, bool isSimple) const { + // This code is only for debugging. + ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this), Name, isSimple); +} + +BlockFrequency +MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const { + return MBFI ? MBFI->getBlockFreq(MBB) : 0; +} + +Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount( + const MachineBasicBlock *MBB) const { + const Function &F = MBFI->getFunction()->getFunction(); + return MBFI ? MBFI->getBlockProfileCount(F, MBB) : None; +} + +Optional<uint64_t> +MachineBlockFrequencyInfo::getProfileCountFromFreq(uint64_t Freq) const { + const Function &F = MBFI->getFunction()->getFunction(); + return MBFI ? MBFI->getProfileCountFromFreq(F, Freq) : None; +} + +bool +MachineBlockFrequencyInfo::isIrrLoopHeader(const MachineBasicBlock *MBB) { + assert(MBFI && "Expected analysis to be available"); + return MBFI->isIrrLoopHeader(MBB); +} + +const MachineFunction *MachineBlockFrequencyInfo::getFunction() const { + return MBFI ? MBFI->getFunction() : nullptr; +} + +const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const { + return MBFI ? &MBFI->getBPI() : nullptr; +} + +raw_ostream & +MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS, + const BlockFrequency Freq) const { + return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS; +} + +raw_ostream & +MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS, + const MachineBasicBlock *MBB) const { + return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS; +} + +uint64_t MachineBlockFrequencyInfo::getEntryFreq() const { + return MBFI ? MBFI->getEntryFreq() : 0; +} |