BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS);
const Function *getFunction() const;
+ const BranchProbabilityInfo *getBPI() const;
void view() const;
/// getblockFreq - Return block frequency. Return 0 if we don't have the
#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>
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;
+
+ static std::string getGraphName(const BlockFrequencyInfoT *G) {
+ return G->getFunction()->getName();
+ }
+
+ 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 BranchProbabilityInfoT *BPI) {
+ 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);
+ OS.flush();
+ return Str;
+ }
+};
+
} // end namespace llvm
#undef DEBUG_TYPE
#define DEBUG_TYPE "block-freq"
#ifndef NDEBUG
-enum GVDAGType {
- GVDT_None,
- GVDT_Fraction,
- GVDT_Integer
-};
-
static cl::opt<GVDAGType>
ViewBlockFreqPropagationDAG("view-block-freq-propagation-dags", cl::Hidden,
cl::desc("Pop up a window to show a dag displaying how block "
}
};
-template<>
-struct DOTGraphTraits<BlockFrequencyInfo*> : public DefaultDOTGraphTraits {
- explicit DOTGraphTraits(bool isSimple=false) :
- DefaultDOTGraphTraits(isSimple) {}
+typedef BFIDOTGraphTraitsBase<BlockFrequencyInfo, BranchProbabilityInfo>
+ BFIDOTGTraitsBase;
- static std::string getGraphName(const BlockFrequencyInfo *G) {
- return G->getFunction()->getName();
- }
+template <>
+struct DOTGraphTraits<BlockFrequencyInfo *> : public BFIDOTGTraitsBase {
+ explicit DOTGraphTraits(bool isSimple = false)
+ : BFIDOTGTraitsBase(isSimple) {}
std::string getNodeLabel(const BasicBlock *Node,
const BlockFrequencyInfo *Graph) {
- std::string Result;
- raw_string_ostream OS(Result);
-
- OS << Node->getName() << ":";
- switch (ViewBlockFreqPropagationDAG) {
- case GVDT_Fraction:
- Graph->printBlockFreq(OS, Node);
- break;
- case GVDT_Integer:
- OS << Graph->getBlockFreq(Node).getFrequency();
- break;
- case GVDT_None:
- llvm_unreachable("If we are not supposed to render a graph we should "
- "never reach this point.");
- }
-
- return Result;
+
+ return BFIDOTGTraitsBase::getNodeLabel(Node, Graph,
+ ViewBlockFreqPropagationDAG);
+ }
+
+ std::string getEdgeAttributes(const BasicBlock *Node, EdgeIter EI,
+ const BlockFrequencyInfo *BFI) {
+ return BFIDOTGTraitsBase::getEdgeAttributes(Node, EI, BFI->getBPI());
}
};
return BFI ? BFI->getFunction() : nullptr;
}
+const BranchProbabilityInfo *BlockFrequencyInfo::getBPI() const {
+ return BFI ? &BFI->getBPI() : nullptr;
+}
+
raw_ostream &BlockFrequencyInfo::
printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const {
return BFI ? BFI->printBlockFreq(OS, Freq) : OS;
#define DEBUG_TYPE "block-freq"
#ifndef NDEBUG
-enum GVDAGType { GVDT_None, GVDT_Fraction, GVDT_Integer, GVDT_Count };
static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
"view-machine-block-freq-propagation-dags", cl::Hidden,
}
};
+typedef BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
+ MachineBranchProbabilityInfo>
+ MBFIDOTGraphTraitsBase;
template <>
struct DOTGraphTraits<MachineBlockFrequencyInfo *>
- : public DefaultDOTGraphTraits {
+ : public MBFIDOTGraphTraitsBase {
explicit DOTGraphTraits(bool isSimple = false)
- : DefaultDOTGraphTraits(isSimple) {}
-
- typedef MachineBasicBlock::const_succ_iterator EdgeIter;
- static std::string getGraphName(const MachineBlockFrequencyInfo *G) {
- return G->getFunction()->getName();
- }
+ : MBFIDOTGraphTraitsBase(isSimple) {}
std::string getNodeLabel(const MachineBasicBlock *Node,
const MachineBlockFrequencyInfo *Graph) {
- std::string Result;
- raw_string_ostream OS(Result);
-
- OS << Node->getName().str() << " : ";
- switch (ViewMachineBlockFreqPropagationDAG) {
- 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;
+ return MBFIDOTGraphTraitsBase::getNodeLabel(
+ Node, Graph, ViewMachineBlockFreqPropagationDAG);
}
- static std::string getEdgeAttributes(const MachineBasicBlock *Node,
- EdgeIter EI,
- const MachineBlockFrequencyInfo *MBFI) {
- std::string Str;
- const MachineBranchProbabilityInfo *MBPI = MBFI->getMBPI();
- if (!MBPI)
- return Str;
- BranchProbability BP = MBPI->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);
- OS.flush();
- return Str;
+
+ std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
+ const MachineBlockFrequencyInfo *MBFI) {
+ return MBFIDOTGraphTraitsBase::getEdgeAttributes(Node, EI, MBFI->getMBPI());
}
};