Index: include/llvm/Analysis/BlockFrequencyInfoImpl.h =================================================================== --- include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -1291,11 +1291,14 @@ } std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfoT *Graph, - GVDAGType GType) { + GVDAGType GType, int layout_order = -1) { std::string Result; raw_string_ostream OS(Result); - OS << Node->getName().str() << " : "; + if (layout_order != -1) + OS << Node->getName() << "[" << layout_order << "] : "; + else + OS << Node->getName() << " : "; switch (GType) { case GVDT_Fraction: Graph->printBlockFreq(OS, Node); Index: include/llvm/CodeGen/MachineBlockFrequencyInfo.h =================================================================== --- include/llvm/CodeGen/MachineBlockFrequencyInfo.h +++ include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -56,7 +56,7 @@ const MachineFunction *getFunction() const; const MachineBranchProbabilityInfo *getMBPI() const; - void view() const; + void view(bool isSimple = true) const; // Print the block frequency Freq to OS using the current functions entry // frequency to convert freq into a relative decimal form. Index: lib/CodeGen/BranchFolding.h =================================================================== --- lib/CodeGen/BranchFolding.h +++ lib/CodeGen/BranchFolding.h @@ -122,6 +122,7 @@ const MachineBasicBlock *MBB) const; raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const; + void view(bool isSimple = true); private: const MachineBlockFrequencyInfo &MBFI; Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -498,6 +498,8 @@ return MBFI.printBlockFreq(OS, Freq); } +void BranchFolder::MBFIWrapper::view(bool isSimple) { MBFI.view(isSimple); } + /// CountTerminators - Count the number of terminators in the given /// block and set I to the position of the first non-terminator, if there /// is one, or MBB->end() otherwise. Index: lib/CodeGen/MachineBlockFrequencyInfo.cpp =================================================================== --- lib/CodeGen/MachineBlockFrequencyInfo.cpp +++ lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -43,10 +43,33 @@ "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 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."))); extern cl::opt ViewBlockFreqFuncName; extern cl::opt ViewHotFreqPercent; +static GVDAGType getGVDT() { + if (ViewBlockLayoutWithBFI != GVDT_None) + return ViewBlockLayoutWithBFI; + + return ViewMachineBlockFreqPropagationDAG; +} + namespace llvm { template <> struct GraphTraits { @@ -80,12 +103,32 @@ struct DOTGraphTraits : public MBFIDOTGraphTraitsBase { explicit DOTGraphTraits(bool isSimple = false) - : MBFIDOTGraphTraitsBase(isSimple) {} + : MBFIDOTGraphTraitsBase(isSimple), CurFunc(nullptr), LayoutOrderMap() {} + + const MachineFunction *CurFunc; + DenseMap LayoutOrderMap; std::string getNodeLabel(const MachineBasicBlock *Node, const MachineBlockFrequencyInfo *Graph) { - return MBFIDOTGraphTraitsBase::getNodeLabel( - Node, Graph, ViewMachineBlockFreqPropagationDAG); + + 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, @@ -148,11 +191,11 @@ /// Pop up a ghostview window with the current block frequency propagation /// rendered using dot. -void MachineBlockFrequencyInfo::view() const { +void MachineBlockFrequencyInfo::view(bool isSimple) const { // This code is only for debugging. #ifndef NDEBUG ViewGraph(const_cast(this), - "MachineBlockFrequencyDAGs"); + "MachineBlockFrequencyDAGs", isSimple); #else errs() << "MachineBlockFrequencyInfo::view is only available in debug builds " "on systems with Graphviz or gv!\n"; Index: lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- lib/CodeGen/MachineBlockPlacement.cpp +++ lib/CodeGen/MachineBlockPlacement.cpp @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/BlockFrequencyInfoImpl.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" @@ -146,6 +147,11 @@ extern cl::opt StaticLikelyProb; extern cl::opt ProfileLikelyProb; +#ifndef NDEBUG +extern cl::opt ViewBlockLayoutWithBFI; +extern cl::opt ViewBlockFreqFuncName; +#endif + namespace { class BlockChain; /// \brief Type for our function-wide basic block -> block chain mapping. @@ -2067,6 +2073,14 @@ MBI->setAlignment(AlignAllNonFallThruBlocks); } } +#ifndef NDEBUG + if (ViewBlockLayoutWithBFI != GVDT_None && + (ViewBlockFreqFuncName.empty() || + F->getFunction()->getName().equals(ViewBlockFreqFuncName))) { + MBFI->view(false); + } +#endif + // We always return true as we have no way to track whether the final order // differs from the original order.