[PM] Port CFGViewer and CFGPrinter to the new Pass Manager

Differential Revision: https://reviews.llvm.org/D24592

llvm-svn: 281640
This commit is contained in:
Sriraman Tallam 2016-09-15 18:35:27 +00:00
parent ab7ccf0ecb
commit 06a67ba57d
7 changed files with 110 additions and 56 deletions

View File

@ -7,6 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines a 'dot-cfg' analysis pass, which emits the
// cfg.<fnname>.dot file for each function in the program, with a graph of the
// CFG for that function.
//
// This file defines external functions that can be called to explicitly
// instantiate the CFG printer.
//
@ -19,9 +23,34 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/GraphWriter.h"
namespace llvm {
class CFGViewerPass
: public PassInfoMixin<CFGViewerPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
class CFGOnlyViewerPass
: public PassInfoMixin<CFGOnlyViewerPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
class CFGPrinterPass
: public PassInfoMixin<CFGPrinterPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
class CFGOnlyPrinterPass
: public PassInfoMixin<CFGOnlyPrinterPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
template<>
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
@ -152,8 +181,8 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
namespace llvm {
class FunctionPass;
FunctionPass *createCFGPrinterPass ();
FunctionPass *createCFGOnlyPrinterPass ();
FunctionPass *createCFGPrinterLegacyPassPass ();
FunctionPass *createCFGOnlyPrinterLegacyPassPass ();
} // End llvm namespace
#endif

View File

@ -80,11 +80,11 @@ void initializeBoundsCheckingPass(PassRegistry&);
void initializeBranchFolderPassPass(PassRegistry&);
void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
void initializeCFGOnlyPrinterPass(PassRegistry&);
void initializeCFGOnlyViewerPass(PassRegistry&);
void initializeCFGPrinterPass(PassRegistry&);
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
void initializeCFGSimplifyPassPass(PassRegistry&);
void initializeCFGViewerPass(PassRegistry&);
void initializeCFGViewerLegacyPassPass(PassRegistry&);
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
void initializeCallGraphDOTPrinterPass(PassRegistry&);

View File

@ -30,10 +30,10 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeCallGraphPrinterLegacyPassPass(Registry);
initializeCallGraphViewerPass(Registry);
initializeCostModelAnalysisPass(Registry);
initializeCFGViewerPass(Registry);
initializeCFGPrinterPass(Registry);
initializeCFGOnlyViewerPass(Registry);
initializeCFGOnlyPrinterPass(Registry);
initializeCFGViewerLegacyPassPass(Registry);
initializeCFGPrinterLegacyPassPass(Registry);
initializeCFGOnlyViewerLegacyPassPass(Registry);
initializeCFGOnlyPrinterLegacyPassPass(Registry);
initializeCFLAndersAAWrapperPassPass(Registry);
initializeCFLSteensAAWrapperPassPass(Registry);
initializeDependenceAnalysisWrapperPassPass(Registry);

View File

@ -23,10 +23,10 @@
using namespace llvm;
namespace {
struct CFGViewer : public FunctionPass {
struct CFGViewerLegacyPass : public FunctionPass {
static char ID; // Pass identifcation, replacement for typeid
CFGViewer() : FunctionPass(ID) {
initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
CFGViewerLegacyPass() : FunctionPass(ID) {
initializeCFGViewerLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override {
@ -42,14 +42,21 @@ namespace {
};
}
char CFGViewer::ID = 0;
INITIALIZE_PASS(CFGViewer, "view-cfg", "View CFG of function", false, true)
char CFGViewerLegacyPass::ID = 0;
INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
PreservedAnalyses CFGViewerPass::run(Function &F,
FunctionAnalysisManager &AM) {
F.viewCFG();
return PreservedAnalyses::all();
}
namespace {
struct CFGOnlyViewer : public FunctionPass {
struct CFGOnlyViewerLegacyPass : public FunctionPass {
static char ID; // Pass identifcation, replacement for typeid
CFGOnlyViewer() : FunctionPass(ID) {
initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
initializeCFGOnlyViewerLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override {
@ -65,18 +72,17 @@ namespace {
};
}
char CFGOnlyViewer::ID = 0;
INITIALIZE_PASS(CFGOnlyViewer, "view-cfg-only",
char CFGOnlyViewerLegacyPass::ID = 0;
INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
"View CFG of function (with no function bodies)", false, true)
namespace {
struct CFGPrinter : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
CFGPrinter() : FunctionPass(ID) {
initializeCFGPrinterPass(*PassRegistry::getPassRegistry());
}
PreservedAnalyses CFGOnlyViewerPass::run(Function &F,
FunctionAnalysisManager &AM) {
F.viewCFGOnly();
return PreservedAnalyses::all();
}
bool runOnFunction(Function &F) override {
static void writeCFGToDotFile(Function &F) {
std::string Filename = ("cfg." + F.getName() + ".dot").str();
errs() << "Writing '" << Filename << "'...";
@ -88,40 +94,47 @@ namespace {
else
errs() << " error opening file for writing!";
errs() << "\n";
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
};
}
char CFGPrinter::ID = 0;
INITIALIZE_PASS(CFGPrinter, "dot-cfg", "Print CFG of function to 'dot' file",
false, true)
namespace {
struct CFGOnlyPrinter : public FunctionPass {
struct CFGPrinterLegacyPass : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
CFGOnlyPrinter() : FunctionPass(ID) {
initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
CFGPrinterLegacyPass() : FunctionPass(ID) {
initializeCFGPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override {
std::string Filename = ("cfg." + F.getName() + ".dot").str();
errs() << "Writing '" << Filename << "'...";
writeCFGToDotFile(F);
return false;
}
std::error_code EC;
raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
void print(raw_ostream &OS, const Module* = nullptr) const override {}
if (!EC)
WriteGraph(File, (const Function*)&F, true);
else
errs() << " error opening file for writing!";
errs() << "\n";
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
};
}
char CFGPrinterLegacyPass::ID = 0;
INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file",
false, true)
PreservedAnalyses CFGPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
writeCFGToDotFile(F);
return PreservedAnalyses::all();
}
namespace {
struct CFGOnlyPrinterLegacyPass : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
initializeCFGOnlyPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F) override {
writeCFGToDotFile(F);
return false;
}
void print(raw_ostream &OS, const Module* = nullptr) const override {}
@ -132,11 +145,17 @@ namespace {
};
}
char CFGOnlyPrinter::ID = 0;
INITIALIZE_PASS(CFGOnlyPrinter, "dot-cfg-only",
char CFGOnlyPrinterLegacyPass::ID = 0;
INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
"Print CFG of function to 'dot' file (with no function bodies)",
false, true)
PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) {
writeCFGToDotFile(F);
return PreservedAnalyses::all();
}
/// viewCFG - This function is meant for use from the debugger. You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function. This depends on there
@ -155,11 +174,11 @@ void Function::viewCFGOnly() const {
ViewGraph(this, "cfg" + getName(), true);
}
FunctionPass *llvm::createCFGPrinterPass () {
return new CFGPrinter();
FunctionPass *llvm::createCFGPrinterLegacyPassPass () {
return new CFGPrinterLegacyPass();
}
FunctionPass *llvm::createCFGOnlyPrinterPass () {
return new CFGOnlyPrinter();
FunctionPass *llvm::createCFGOnlyPrinterLegacyPassPass () {
return new CFGOnlyPrinterLegacyPass();
}

View File

@ -28,6 +28,7 @@
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/DominanceFrontier.h"

View File

@ -139,6 +139,8 @@ FUNCTION_PASS("consthoist", ConstantHoistingPass())
FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
FUNCTION_PASS("dce", DCEPass())
FUNCTION_PASS("dse", DSEPass())
FUNCTION_PASS("dot-cfg", CFGPrinterPass())
FUNCTION_PASS("dot-cfg-only", CFGOnlyPrinterPass())
FUNCTION_PASS("early-cse", EarlyCSEPass(/*UseMemorySSA=*/false))
FUNCTION_PASS("early-cse-memssa", EarlyCSEPass(/*UseMemorySSA=*/true))
FUNCTION_PASS("gvn-hoist", GVNHoistPass())
@ -190,6 +192,8 @@ FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
FUNCTION_PASS("verify<loops>", LoopVerifierPass())
FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())
FUNCTION_PASS("verify<regions>", RegionInfoVerifierPass())
FUNCTION_PASS("view-cfg", CFGViewerPass())
FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())
#undef FUNCTION_PASS
#ifndef LOOP_ANALYSIS

View File

@ -1,4 +1,5 @@
;RUN: opt < %s -analyze -dot-cfg-only 2>/dev/null
;RUN: opt < %s -analyze -passes=dot-cfg-only 2>/dev/null
;PR 1497
define void @foo() {