diff options
Diffstat (limited to 'include/llvm/Analysis/BlockFrequencyInfoImpl.h')
-rw-r--r-- | include/llvm/Analysis/BlockFrequencyInfoImpl.h | 123 |
1 files changed, 121 insertions, 2 deletions
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 387e9a887d93c..7ed06b1bb68f3 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -16,12 +16,16 @@ #define LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/BasicBlock.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" +#include "llvm/Support/DOTGraphTraits.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/ScaledNumber.h" #include "llvm/Support/raw_ostream.h" #include <deque> @@ -476,6 +480,8 @@ public: Scaled64 getFloatingBlockFreq(const BlockNode &Node) const; BlockFrequency getBlockFreq(const BlockNode &Node) const; + Optional<uint64_t> getBlockProfileCount(const Function &F, + const BlockNode &Node) const; void setBlockFreq(const BlockNode &Node, uint64_t Freq); @@ -915,11 +921,17 @@ public: BlockFrequency getBlockFreq(const BlockT *BB) const { return BlockFrequencyInfoImplBase::getBlockFreq(getNode(BB)); } + Optional<uint64_t> getBlockProfileCount(const Function &F, + const BlockT *BB) const { + return BlockFrequencyInfoImplBase::getBlockProfileCount(F, getNode(BB)); + } void setBlockFreq(const BlockT *BB, uint64_t Freq); Scaled64 getFloatingBlockFreq(const BlockT *BB) const { return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB)); } + const BranchProbabilityInfoT &getBPI() const { return *BPI; } + /// \brief Print the frequencies for the current function. /// /// Prints the frequencies for the blocks in the current function. @@ -1173,12 +1185,10 @@ void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass( updateLoopWithIrreducible(*OuterLoop); } -namespace { // A helper function that converts a branch probability into weight. inline uint32_t getWeightFromBranchProb(const BranchProbability Prob) { return Prob.getNumerator(); } -} // namespace template <class BT> bool @@ -1224,6 +1234,115 @@ raw_ostream &BlockFrequencyInfoImpl<BT>::print(raw_ostream &OS) const { return OS; } +// Graph trait base class for block frequency information graph +// viewer. + +enum GVDAGType { GVDT_None, GVDT_Fraction, GVDT_Integer, GVDT_Count }; + +template <class BlockFrequencyInfoT, class BranchProbabilityInfoT> +struct BFIDOTGraphTraitsBase : public DefaultDOTGraphTraits { + explicit BFIDOTGraphTraitsBase(bool isSimple = false) + : DefaultDOTGraphTraits(isSimple) {} + + typedef GraphTraits<BlockFrequencyInfoT *> GTraits; + typedef typename GTraits::NodeType NodeType; + typedef typename GTraits::ChildIteratorType EdgeIter; + typedef typename GTraits::nodes_iterator NodeIter; + + uint64_t MaxFrequency = 0; + static std::string getGraphName(const BlockFrequencyInfoT *G) { + return G->getFunction()->getName(); + } + + std::string getNodeAttributes(const NodeType *Node, + const BlockFrequencyInfoT *Graph, + unsigned HotPercentThreshold = 0) { + std::string Result; + if (!HotPercentThreshold) + return Result; + + // Compute MaxFrequency on the fly: + if (!MaxFrequency) { + for (NodeIter I = GTraits::nodes_begin(Graph), + E = GTraits::nodes_end(Graph); + I != E; ++I) { + NodeType &N = *I; + MaxFrequency = + std::max(MaxFrequency, Graph->getBlockFreq(&N).getFrequency()); + } + } + BlockFrequency Freq = Graph->getBlockFreq(Node); + BlockFrequency HotFreq = + (BlockFrequency(MaxFrequency) * + BranchProbability::getBranchProbability(HotPercentThreshold, 100)); + + if (Freq < HotFreq) + return Result; + + raw_string_ostream OS(Result); + OS << "color=\"red\""; + OS.flush(); + return Result; + } + + std::string getNodeLabel(const NodeType *Node, + const BlockFrequencyInfoT *Graph, GVDAGType GType) { + std::string Result; + raw_string_ostream OS(Result); + + OS << Node->getName().str() << " : "; + switch (GType) { + case GVDT_Fraction: + Graph->printBlockFreq(OS, Node); + break; + case GVDT_Integer: + OS << Graph->getBlockFreq(Node).getFrequency(); + break; + case GVDT_Count: { + auto Count = Graph->getBlockProfileCount(Node); + if (Count) + OS << Count.getValue(); + else + OS << "Unknown"; + break; + } + case GVDT_None: + llvm_unreachable("If we are not supposed to render a graph we should " + "never reach this point."); + } + return Result; + } + + std::string getEdgeAttributes(const NodeType *Node, EdgeIter EI, + const BlockFrequencyInfoT *BFI, + const BranchProbabilityInfoT *BPI, + unsigned HotPercentThreshold = 0) { + std::string Str; + if (!BPI) + return Str; + + BranchProbability BP = BPI->getEdgeProbability(Node, EI); + uint32_t N = BP.getNumerator(); + uint32_t D = BP.getDenominator(); + double Percent = 100.0 * N / D; + raw_string_ostream OS(Str); + OS << format("label=\"%.1f%%\"", Percent); + + if (HotPercentThreshold) { + BlockFrequency EFreq = BFI->getBlockFreq(Node) * BP; + BlockFrequency HotFreq = BlockFrequency(MaxFrequency) * + BranchProbability(HotPercentThreshold, 100); + + if (EFreq >= HotFreq) { + OS << ",color=\"red\""; + } + } + + OS.flush(); + return Str; + } +}; + } // end namespace llvm #undef DEBUG_TYPE |