mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-24 13:06:56 +00:00
7f2eff792a
can be used by both the new pass manager and the old. This removes it from any of the virtual mess of the pass interfaces and lets it derive cleanly from the DominatorTreeBase<> template. In turn, tons of boilerplate interface can be nuked and it turns into a very straightforward extension of the base DominatorTree interface. The old analysis pass is now a simple wrapper. The names and style of this split should match the split between CallGraph and CallGraphWrapperPass. All of the users of DominatorTree have been updated to match using many of the same tricks as with CallGraph. The goal is that the common type remains the resulting DominatorTree rather than the pass. This will make subsequent work toward the new pass manager significantly easier. Also in numerous places things became cleaner because I switched from re-running the pass (!!! mid way through some other passes run!!!) to directly recomputing the domtree. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199104 91177308-0d34-0410-b5e6-96231b3b80d8
255 lines
7.9 KiB
C++
255 lines
7.9 KiB
C++
//===- DomPrinter.cpp - DOT printer for the dominance trees ------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
|
|
// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
|
|
// program, with a graph of the dominance/postdominance tree of that
|
|
// function.
|
|
//
|
|
// There are also passes available to directly call dotty ('-view-dom' or
|
|
// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
|
|
// names of the bbs are printed, but the content is hidden.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/DomPrinter.h"
|
|
#include "llvm/Analysis/DOTGraphTraitsPass.h"
|
|
#include "llvm/Analysis/PostDominators.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace llvm {
|
|
template<>
|
|
struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
|
|
|
|
DOTGraphTraits (bool isSimple=false)
|
|
: DefaultDOTGraphTraits(isSimple) {}
|
|
|
|
std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
|
|
|
|
BasicBlock *BB = Node->getBlock();
|
|
|
|
if (!BB)
|
|
return "Post dominance root node";
|
|
|
|
|
|
if (isSimple())
|
|
return DOTGraphTraits<const Function*>
|
|
::getSimpleNodeLabel(BB, BB->getParent());
|
|
else
|
|
return DOTGraphTraits<const Function*>
|
|
::getCompleteNodeLabel(BB, BB->getParent());
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
|
|
|
|
DOTGraphTraits (bool isSimple=false)
|
|
: DOTGraphTraits<DomTreeNode*>(isSimple) {}
|
|
|
|
static std::string getGraphName(DominatorTree *DT) {
|
|
return "Dominator tree";
|
|
}
|
|
|
|
std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
|
|
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct DOTGraphTraits<PostDominatorTree*>
|
|
: public DOTGraphTraits<DomTreeNode*> {
|
|
|
|
DOTGraphTraits (bool isSimple=false)
|
|
: DOTGraphTraits<DomTreeNode*>(isSimple) {}
|
|
|
|
static std::string getGraphName(PostDominatorTree *DT) {
|
|
return "Post dominator tree";
|
|
}
|
|
|
|
std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
|
|
return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
|
|
}
|
|
};
|
|
}
|
|
|
|
namespace {
|
|
struct DominatorTreeWrapperPassAnalysisGraphTraits {
|
|
static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
|
|
return &DTWP->getDomTree();
|
|
}
|
|
};
|
|
|
|
struct DomViewer : public DOTGraphTraitsViewer<
|
|
DominatorTreeWrapperPass, false, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits> {
|
|
static char ID;
|
|
DomViewer()
|
|
: DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits>(
|
|
"dom", ID) {
|
|
initializeDomViewerPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct DomOnlyViewer : public DOTGraphTraitsViewer<
|
|
DominatorTreeWrapperPass, true, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits> {
|
|
static char ID;
|
|
DomOnlyViewer()
|
|
: DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits>(
|
|
"domonly", ID) {
|
|
initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct PostDomViewer
|
|
: public DOTGraphTraitsViewer<PostDominatorTree, false> {
|
|
static char ID;
|
|
PostDomViewer() :
|
|
DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){
|
|
initializePostDomViewerPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct PostDomOnlyViewer
|
|
: public DOTGraphTraitsViewer<PostDominatorTree, true> {
|
|
static char ID;
|
|
PostDomOnlyViewer() :
|
|
DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){
|
|
initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
char DomViewer::ID = 0;
|
|
INITIALIZE_PASS(DomViewer, "view-dom",
|
|
"View dominance tree of function", false, false)
|
|
|
|
char DomOnlyViewer::ID = 0;
|
|
INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
|
|
"View dominance tree of function (with no function bodies)",
|
|
false, false)
|
|
|
|
char PostDomViewer::ID = 0;
|
|
INITIALIZE_PASS(PostDomViewer, "view-postdom",
|
|
"View postdominance tree of function", false, false)
|
|
|
|
char PostDomOnlyViewer::ID = 0;
|
|
INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
|
|
"View postdominance tree of function "
|
|
"(with no function bodies)",
|
|
false, false)
|
|
|
|
namespace {
|
|
struct DomPrinter : public DOTGraphTraitsPrinter<
|
|
DominatorTreeWrapperPass, false, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits> {
|
|
static char ID;
|
|
DomPrinter()
|
|
: DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits>(
|
|
"dom", ID) {
|
|
initializeDomPrinterPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
|
|
DominatorTreeWrapperPass, true, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits> {
|
|
static char ID;
|
|
DomOnlyPrinter()
|
|
: DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
|
|
DominatorTreeWrapperPassAnalysisGraphTraits>(
|
|
"domonly", ID) {
|
|
initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct PostDomPrinter
|
|
: public DOTGraphTraitsPrinter<PostDominatorTree, false> {
|
|
static char ID;
|
|
PostDomPrinter() :
|
|
DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) {
|
|
initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
|
|
struct PostDomOnlyPrinter
|
|
: public DOTGraphTraitsPrinter<PostDominatorTree, true> {
|
|
static char ID;
|
|
PostDomOnlyPrinter() :
|
|
DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) {
|
|
initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
char DomPrinter::ID = 0;
|
|
INITIALIZE_PASS(DomPrinter, "dot-dom",
|
|
"Print dominance tree of function to 'dot' file",
|
|
false, false)
|
|
|
|
char DomOnlyPrinter::ID = 0;
|
|
INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
|
|
"Print dominance tree of function to 'dot' file "
|
|
"(with no function bodies)",
|
|
false, false)
|
|
|
|
char PostDomPrinter::ID = 0;
|
|
INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
|
|
"Print postdominance tree of function to 'dot' file",
|
|
false, false)
|
|
|
|
char PostDomOnlyPrinter::ID = 0;
|
|
INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
|
|
"Print postdominance tree of function to 'dot' file "
|
|
"(with no function bodies)",
|
|
false, false)
|
|
|
|
// Create methods available outside of this file, to use them
|
|
// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
|
|
// the link time optimization.
|
|
|
|
FunctionPass *llvm::createDomPrinterPass() {
|
|
return new DomPrinter();
|
|
}
|
|
|
|
FunctionPass *llvm::createDomOnlyPrinterPass() {
|
|
return new DomOnlyPrinter();
|
|
}
|
|
|
|
FunctionPass *llvm::createDomViewerPass() {
|
|
return new DomViewer();
|
|
}
|
|
|
|
FunctionPass *llvm::createDomOnlyViewerPass() {
|
|
return new DomOnlyViewer();
|
|
}
|
|
|
|
FunctionPass *llvm::createPostDomPrinterPass() {
|
|
return new PostDomPrinter();
|
|
}
|
|
|
|
FunctionPass *llvm::createPostDomOnlyPrinterPass() {
|
|
return new PostDomOnlyPrinter();
|
|
}
|
|
|
|
FunctionPass *llvm::createPostDomViewerPass() {
|
|
return new PostDomViewer();
|
|
}
|
|
|
|
FunctionPass *llvm::createPostDomOnlyViewerPass() {
|
|
return new PostDomOnlyViewer();
|
|
}
|