Index: llvm/trunk/include/llvm/Analysis/CFGPrinter.h =================================================================== --- llvm/trunk/include/llvm/Analysis/CFGPrinter.h +++ llvm/trunk/include/llvm/Analysis/CFGPrinter.h @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// // +// This file defines a 'dot-cfg' analysis pass, which emits the +// cfg..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 { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +class CFGOnlyViewerPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +class CFGPrinterPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + +class CFGOnlyPrinterPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { @@ -152,8 +181,8 @@ namespace llvm { class FunctionPass; - FunctionPass *createCFGPrinterPass (); - FunctionPass *createCFGOnlyPrinterPass (); + FunctionPass *createCFGPrinterLegacyPassPass (); + FunctionPass *createCFGOnlyPrinterLegacyPassPass (); } // End llvm namespace #endif Index: llvm/trunk/include/llvm/InitializePasses.h =================================================================== --- llvm/trunk/include/llvm/InitializePasses.h +++ llvm/trunk/include/llvm/InitializePasses.h @@ -80,11 +80,11 @@ 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&); Index: llvm/trunk/lib/Analysis/Analysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/Analysis.cpp +++ llvm/trunk/lib/Analysis/Analysis.cpp @@ -30,10 +30,10 @@ 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); Index: llvm/trunk/lib/Analysis/CFGPrinter.cpp =================================================================== --- llvm/trunk/lib/Analysis/CFGPrinter.cpp +++ llvm/trunk/lib/Analysis/CFGPrinter.cpp @@ -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 @@ }; } -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,29 +72,39 @@ }; } -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) +PreservedAnalyses CFGOnlyViewerPass::run(Function &F, + FunctionAnalysisManager &AM) { + F.viewCFGOnly(); + return PreservedAnalyses::all(); +} + +static void writeCFGToDotFile(Function &F) { + std::string Filename = ("cfg." + F.getName() + ".dot").str(); + errs() << "Writing '" << Filename << "'..."; + + std::error_code EC; + raw_fd_ostream File(Filename, EC, sys::fs::F_Text); + + if (!EC) + WriteGraph(File, (const Function*)&F); + else + errs() << " error opening file for writing!"; + errs() << "\n"; +} + namespace { - struct CFGPrinter : public FunctionPass { + struct CFGPrinterLegacyPass : public FunctionPass { static char ID; // Pass identification, replacement for typeid - CFGPrinter() : FunctionPass(ID) { - initializeCFGPrinterPass(*PassRegistry::getPassRegistry()); + CFGPrinterLegacyPass() : FunctionPass(ID) { + initializeCFGPrinterLegacyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override { - std::string Filename = ("cfg." + F.getName() + ".dot").str(); - errs() << "Writing '" << Filename << "'..."; - - std::error_code EC; - raw_fd_ostream File(Filename, EC, sys::fs::F_Text); - - if (!EC) - WriteGraph(File, (const Function*)&F); - else - errs() << " error opening file for writing!"; - errs() << "\n"; + writeCFGToDotFile(F); return false; } @@ -99,29 +116,25 @@ }; } -char CFGPrinter::ID = 0; -INITIALIZE_PASS(CFGPrinter, "dot-cfg", "Print CFG of function to 'dot' file", +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 CFGOnlyPrinter : public FunctionPass { + struct CFGOnlyPrinterLegacyPass : public FunctionPass { static char ID; // Pass identification, replacement for typeid - CFGOnlyPrinter() : FunctionPass(ID) { - initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry()); + CFGOnlyPrinterLegacyPass() : FunctionPass(ID) { + initializeCFGOnlyPrinterLegacyPassPass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override { - std::string Filename = ("cfg." + F.getName() + ".dot").str(); - errs() << "Writing '" << Filename << "'..."; - - std::error_code EC; - raw_fd_ostream File(Filename, EC, sys::fs::F_Text); - - if (!EC) - WriteGraph(File, (const Function*)&F, true); - else - errs() << " error opening file for writing!"; - errs() << "\n"; + writeCFGToDotFile(F); return false; } void print(raw_ostream &OS, const Module* = nullptr) const override {} @@ -132,11 +145,17 @@ }; } -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 @@ 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(); } Index: llvm/trunk/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/trunk/lib/Passes/PassBuilder.cpp +++ llvm/trunk/lib/Passes/PassBuilder.cpp @@ -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" Index: llvm/trunk/lib/Passes/PassRegistry.def =================================================================== --- llvm/trunk/lib/Passes/PassRegistry.def +++ llvm/trunk/lib/Passes/PassRegistry.def @@ -139,6 +139,8 @@ 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", LoopVerifierPass()) FUNCTION_PASS("verify", MemorySSAVerifierPass()) FUNCTION_PASS("verify", RegionInfoVerifierPass()) +FUNCTION_PASS("view-cfg", CFGViewerPass()) +FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass()) #undef FUNCTION_PASS #ifndef LOOP_ANALYSIS Index: llvm/trunk/test/Other/2007-06-05-PassID.ll =================================================================== --- llvm/trunk/test/Other/2007-06-05-PassID.ll +++ llvm/trunk/test/Other/2007-06-05-PassID.ll @@ -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() {