[llvm] 3f995ce - [CFGPrinter][CallPrinter][polly] Adding distinct structure for CFGDOTInfo
Kirill Naumov via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 6 10:43:34 PDT 2020
Author: Kirill Naumov
Date: 2020-04-06T17:42:54Z
New Revision: 3f995ce8b54ca6094fd47a5f1090ef6ce367ded2
URL: https://github.com/llvm/llvm-project/commit/3f995ce8b54ca6094fd47a5f1090ef6ce367ded2
DIFF: https://github.com/llvm/llvm-project/commit/3f995ce8b54ca6094fd47a5f1090ef6ce367ded2.diff
LOG: [CFGPrinter][CallPrinter][polly] Adding distinct structure for CFGDOTInfo
The patch introduces the system to distinctively store the information
needed for the Control Flow Graph as well as the instrumentary needed for
the follow-up changes: BlockFrequencyInfo and BranchProbabilityInfo.
The patch is a part of sequence of three patches, related to graphs Heat Coloring.
Reviewers: rcorcs, apilipenko, davidxl, sfertile, fedor.sergeev, eraman, bollu
Differential Revision: https://reviews.llvm.org/D76820
Added:
Modified:
llvm/include/llvm/Analysis/CFGPrinter.h
llvm/lib/Analysis/CFGPrinter.cpp
llvm/lib/Analysis/DomPrinter.cpp
llvm/lib/Analysis/RegionPrinter.cpp
llvm/lib/Transforms/Scalar/NewGVN.cpp
polly/lib/Analysis/ScopGraphPrinter.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/CFGPrinter.h b/llvm/include/llvm/Analysis/CFGPrinter.h
index b0c88f296250..80a26cd733fd 100644
--- a/llvm/include/llvm/Analysis/CFGPrinter.h
+++ b/llvm/include/llvm/Analysis/CFGPrinter.h
@@ -18,11 +18,14 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/GraphWriter.h"
namespace llvm {
@@ -50,20 +53,61 @@ class CFGOnlyPrinterPass
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-template<>
-struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
+class DOTFuncInfo {
+private:
+ const Function *F;
+ const BlockFrequencyInfo *BFI;
+ const BranchProbabilityInfo *BPI;
+
+public:
+ DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr) {}
+
+ DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI)
+ : F(F), BFI(BFI), BPI(BPI) {
+ }
+
+ const BlockFrequencyInfo *getBFI() { return BFI; }
+
+ const BranchProbabilityInfo *getBPI() { return BPI; }
+
+ const Function *getFunction() { return this->F; }
+};
+
+template <>
+struct GraphTraits<DOTFuncInfo *> : public GraphTraits<const BasicBlock *> {
+ static NodeRef getEntryNode(DOTFuncInfo *CFGInfo) {
+ return &(CFGInfo->getFunction()->getEntryBlock());
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ using nodes_iterator = pointer_iterator<Function::const_iterator>;
+
+ static nodes_iterator nodes_begin(DOTFuncInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->begin());
+ }
+
+ static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->end());
+ }
+
+ static size_t size(DOTFuncInfo *CFGInfo) {
+ return CFGInfo->getFunction()->size();
+ }
+};
+
+template <> struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
// Cache for is hidden property
llvm::DenseMap <const BasicBlock *, bool> isHiddenBasicBlock;
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
- static std::string getGraphName(const Function *F) {
- return "CFG for '" + F->getName().str() + "' function";
+ static std::string getGraphName(DOTFuncInfo *CFGInfo) {
+ return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
}
- static std::string getSimpleNodeLabel(const BasicBlock *Node,
- const Function *) {
+ static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
if (!Node->getName().empty())
return Node->getName().str();
@@ -75,7 +119,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
static std::string getCompleteNodeLabel(const BasicBlock *Node,
- const Function *) {
+ DOTFuncInfo *) {
enum { MaxColumns = 80 };
std::string Str;
raw_string_ostream OS(Str);
@@ -120,11 +164,12 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
std::string getNodeLabel(const BasicBlock *Node,
- const Function *Graph) {
+ DOTFuncInfo *CFGInfo) {
+
if (isSimple())
- return getSimpleNodeLabel(Node, Graph);
+ return getSimpleNodeLabel(Node, CFGInfo);
else
- return getCompleteNodeLabel(Node, Graph);
+ return getCompleteNodeLabel(Node, CFGInfo);
}
static std::string getEdgeSourceLabel(const BasicBlock *Node,
@@ -151,11 +196,10 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
/// Display the raw branch weights from PGO.
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I,
- const Function *F) {
+ DOTFuncInfo *CFGInfo) {
const Instruction *TI = Node->getTerminator();
if (TI->getNumSuccessors() == 1)
return "";
-
MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
if (!WeightsNode)
return "";
@@ -163,7 +207,6 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
MDString *MDName = cast<MDString>(WeightsNode->getOperand(0));
if (MDName->getString() != "branch_weights")
return "";
-
unsigned OpNo = I.getSuccessorIndex() + 1;
if (OpNo >= WeightsNode->getNumOperands())
return "";
diff --git a/llvm/lib/Analysis/CFGPrinter.cpp b/llvm/lib/Analysis/CFGPrinter.cpp
index 4a708b4981ae..295d936c026e 100644
--- a/llvm/lib/Analysis/CFGPrinter.cpp
+++ b/llvm/lib/Analysis/CFGPrinter.cpp
@@ -42,6 +42,31 @@ static cl::opt<bool> HideUnreachablePaths("cfg-hide-unreachable-paths",
static cl::opt<bool> HideDeoptimizePaths("cfg-hide-deoptimize-paths",
cl::init(false));
+static void writeCFGToDotFile(Function &F, BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI,
+ bool isSimple) {
+ std::string Filename =
+ (CFGDotFilenamePrefix + "." + F.getName() + ".dot").str();
+ errs() << "Writing '" << Filename << "'...";
+
+ std::error_code EC;
+ raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
+
+ DOTFuncInfo CFGInfo(&F, BFI, BPI);
+ if (!EC)
+ WriteGraph(File, &CFGInfo, isSimple);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+}
+
+static void viewCFG(Function &F, BlockFrequencyInfo *BFI,
+ BranchProbabilityInfo *BPI,
+ bool isSimple) {
+ DOTFuncInfo CFGInfo(&F, BFI, BPI);
+ ViewGraph(&CFGInfo, "cfg." + F.getName(), isSimple);
+}
+
namespace {
struct CFGViewerLegacyPass : public FunctionPass {
static char ID; // Pass identifcation, replacement for typeid
@@ -50,13 +75,18 @@ namespace {
}
bool runOnFunction(Function &F) override {
- F.viewCFG();
+ auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+ auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
+ viewCFG(F, BFI, BPI, /*isSimple=*/false);
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ FunctionPass::getAnalysisUsage(AU); // Maybe Change to FunctionPass::...
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.setPreservesAll();
}
};
@@ -67,7 +97,9 @@ INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false,
PreservedAnalyses CFGViewerPass::run(Function &F,
FunctionAnalysisManager &AM) {
- F.viewCFG();
+ auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
+ auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
+ viewCFG(F, BFI, BPI, /*isSimple=*/false);
return PreservedAnalyses::all();
}
@@ -80,13 +112,18 @@ namespace {
}
bool runOnFunction(Function &F) override {
- F.viewCFGOnly();
+ auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+ auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
+ viewCFG(F, BFI, BPI, /*isSimple=*/false);
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ FunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.setPreservesAll();
}
};
@@ -98,27 +135,12 @@ INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
PreservedAnalyses CFGOnlyViewerPass::run(Function &F,
FunctionAnalysisManager &AM) {
- F.viewCFGOnly();
+ auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
+ auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
+ viewCFG(F, BFI, BPI, /*isSimple=*/false);
return PreservedAnalyses::all();
}
-static void writeCFGToDotFile(Function &F, bool CFGOnly = false) {
- if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
- return;
- std::string Filename =
- (CFGDotFilenamePrefix + "." + F.getName() + ".dot").str();
- errs() << "Writing '" << Filename << "'...";
-
- std::error_code EC;
- raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
-
- if (!EC)
- WriteGraph(File, (const Function*)&F, CFGOnly);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
-}
-
namespace {
struct CFGPrinterLegacyPass : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
@@ -127,13 +149,18 @@ namespace {
}
bool runOnFunction(Function &F) override {
- writeCFGToDotFile(F);
+ auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+ auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
+ writeCFGToDotFile(F, BFI, BPI, /*isSimple=*/false);
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ FunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.setPreservesAll();
}
};
@@ -145,7 +172,9 @@ INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot'
PreservedAnalyses CFGPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
- writeCFGToDotFile(F);
+ auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
+ auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
+ writeCFGToDotFile(F, BFI, BPI, /*isSimple=*/false);
return PreservedAnalyses::all();
}
@@ -157,12 +186,17 @@ namespace {
}
bool runOnFunction(Function &F) override {
- writeCFGToDotFile(F, /*CFGOnly=*/true);
+ auto *BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+ auto *BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>().getBFI();
+ writeCFGToDotFile(F, BFI, BPI, /*isSimple=*/false);
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ FunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.setPreservesAll();
}
};
@@ -175,7 +209,9 @@ INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
- writeCFGToDotFile(F, /*CFGOnly=*/true);
+ auto *BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
+ auto *BPI = &AM.getResult<BranchProbabilityAnalysis>(F);
+ writeCFGToDotFile(F, BFI, BPI, /*isSimple=*/false);
return PreservedAnalyses::all();
}
@@ -187,7 +223,8 @@ PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
void Function::viewCFG() const {
if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
return;
- ViewGraph(this, "cfg" + getName());
+ DOTFuncInfo CFGInfo(this);
+ ViewGraph(&CFGInfo, "cfg" + getName());
}
/// viewCFGOnly - This function is meant for use from the debugger. It works
@@ -198,7 +235,8 @@ void Function::viewCFG() const {
void Function::viewCFGOnly() const {
if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
return;
- ViewGraph(this, "cfg" + getName(), true);
+ DOTFuncInfo CFGInfo(this);
+ ViewGraph(&CFGInfo, "cfg" + getName(), true);
}
FunctionPass *llvm::createCFGPrinterLegacyPassPass () {
@@ -209,7 +247,7 @@ FunctionPass *llvm::createCFGOnlyPrinterLegacyPassPass () {
return new CFGOnlyPrinterLegacyPass();
}
-void DOTGraphTraits<const Function *>::computeHiddenNodes(const Function *F) {
+void DOTGraphTraits<DOTFuncInfo *>::computeHiddenNodes(const Function *F) {
auto evaluateBB = [&](const BasicBlock *Node) {
if (succ_begin(Node) == succ_end(Node)) {
const Instruction *TI = Node->getTerminator();
@@ -228,7 +266,7 @@ void DOTGraphTraits<const Function *>::computeHiddenNodes(const Function *F) {
evaluateBB);
}
-bool DOTGraphTraits<const Function *>::isNodeHidden(const BasicBlock *Node) {
+bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node) {
// If both restricting flags are false, all nodes are displayed.
if (!HideUnreachablePaths && !HideDeoptimizePaths)
return false;
diff --git a/llvm/lib/Analysis/DomPrinter.cpp b/llvm/lib/Analysis/DomPrinter.cpp
index 024a0fb49950..ebbe0d3e2c5f 100644
--- a/llvm/lib/Analysis/DomPrinter.cpp
+++ b/llvm/lib/Analysis/DomPrinter.cpp
@@ -40,11 +40,11 @@ struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
if (isSimple())
- return DOTGraphTraits<const Function*>
- ::getSimpleNodeLabel(BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>
+ ::getSimpleNodeLabel(BB, nullptr);
else
- return DOTGraphTraits<const Function*>
- ::getCompleteNodeLabel(BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>
+ ::getCompleteNodeLabel(BB, nullptr);
}
};
diff --git a/llvm/lib/Analysis/RegionPrinter.cpp b/llvm/lib/Analysis/RegionPrinter.cpp
index 020ff85d1b98..1fb5faaa6a71 100644
--- a/llvm/lib/Analysis/RegionPrinter.cpp
+++ b/llvm/lib/Analysis/RegionPrinter.cpp
@@ -47,11 +47,11 @@ struct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
BasicBlock *BB = Node->getNodeAs<BasicBlock>();
if (isSimple())
- return DOTGraphTraits<const Function*>
- ::getSimpleNodeLabel(BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>
+ ::getSimpleNodeLabel(BB, nullptr);
else
- return DOTGraphTraits<const Function*>
- ::getCompleteNodeLabel(BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>
+ ::getCompleteNodeLabel(BB, nullptr);
}
return "Not implemented";
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index b93a8bfeaa46..98c3304bf7b3 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -898,7 +898,7 @@ bool NewGVN::isBackedge(BasicBlock *From, BasicBlock *To) const {
#ifndef NDEBUG
static std::string getBlockName(const BasicBlock *B) {
- return DOTGraphTraits<const Function *>::getSimpleNodeLabel(B, nullptr);
+ return DOTGraphTraits<DOTFuncInfo *>::getSimpleNodeLabel(B, nullptr);
}
#endif
diff --git a/polly/lib/Analysis/ScopGraphPrinter.cpp b/polly/lib/Analysis/ScopGraphPrinter.cpp
index 53affb15d6a0..21fc7e3408d3 100644
--- a/polly/lib/Analysis/ScopGraphPrinter.cpp
+++ b/polly/lib/Analysis/ScopGraphPrinter.cpp
@@ -68,11 +68,10 @@ template <> struct DOTGraphTraits<RegionNode *> : public DefaultDOTGraphTraits {
BasicBlock *BB = Node->getNodeAs<BasicBlock>();
if (isSimple())
- return DOTGraphTraits<const Function *>::getSimpleNodeLabel(
- BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>::getSimpleNodeLabel(BB, nullptr);
+
else
- return DOTGraphTraits<const Function *>::getCompleteNodeLabel(
- BB, BB->getParent());
+ return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(BB, nullptr);
}
return "Not implemented";
More information about the llvm-commits
mailing list