forked from OSchip/llvm-project
[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:
parent
ab7ccf0ecb
commit
06a67ba57d
|
@ -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
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue