Skip to content

Instantly share code, notes, and snippets.

@Trass3r
Created October 16, 2022 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Trass3r/ec4f9050515c22c7efe4906da1899bfc to your computer and use it in GitHub Desktop.
Save Trass3r/ec4f9050515c22c7efe4906da1899bfc to your computer and use it in GitHub Desktop.
Index: include/llvm/Analysis/CFGPrinter.h
===================================================================
--- include/llvm/Analysis/CFGPrinter.h (revision 177877)
+++ include/llvm/Analysis/CFGPrinter.h (working copy)
@@ -15,6 +15,7 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
+#include "llvm/PassSupport.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
@@ -103,12 +104,42 @@ struct DOTGraphTraits<const Function*> :
return "";
}
};
-} // End llvm namespace
-namespace llvm {
- class FunctionPass;
- FunctionPass *createCFGPrinterPass ();
- FunctionPass *createCFGOnlyPrinterPass ();
+template <class FC, bool CFGOnly> struct CFGPrinterBase {
+ CFGPrinterBase(const PassInfo *P = 0, const char *O = 0) : PI(P), Order(O) {
+ assert(!PI == !Order);
+ }
+ bool run(FC *F) {
+ std::string Filename = "cfg." + F->template getName().str();
+ if (PI)
+ Filename = Filename + "." + Order + "." + PI->getPassArgument() + ".dot";
+ else
+ Filename += ".dot";
+ errs() << "Writing '" << Filename << "'...";
+
+ std::string ErrorInfo;
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo);
+
+ if (ErrorInfo.empty())
+ WriteGraph(File, (const FC *)F, CFGOnly);
+ else
+ errs() << " error opening file for writing!";
+
+ errs() << "\n";
+ return false;
+ }
+
+private:
+ const PassInfo *PI;
+ const char *Order;
+};
+
+class FunctionPass;
+FunctionPass *createCFGPrinterPass();
+FunctionPass *createCFGPrinterPass(const PassInfo *, const char *);
+FunctionPass *createCFGOnlyPrinterPass();
+FunctionPass *createMachineCFGPrinterPass(const PassInfo *, const char *);
+FunctionPass *createMachineCFGOnlyPrinterPass();
} // End llvm namespace
#endif
Index: include/llvm/Analysis/CFGPrinter.h
===================================================================
--- include/llvm/Analysis/CFGPrinter.h (revision 183332)
+++ include/llvm/Analysis/CFGPrinter.h (working copy)
@@ -1,114 +0,0 @@
-//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines external functions that can be called to explicitly
-// instantiate the CFG printer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_CFGPRINTER_H
-#define LLVM_ANALYSIS_CFGPRINTER_H
-
-#include "llvm/Assembly/Writer.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/Analysis/CFG.h"
-#include "llvm/Support/GraphWriter.h"
-
-namespace llvm {
-template<>
-struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
-
- DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
-
- static std::string getGraphName(const Function *F) {
- return "CFG for '" + F->getName().str() + "' function";
- }
-
- static std::string getSimpleNodeLabel(const BasicBlock *Node,
- const Function *) {
- if (!Node->getName().empty())
- return Node->getName().str();
-
- std::string Str;
- raw_string_ostream OS(Str);
-
- WriteAsOperand(OS, Node, false);
- return OS.str();
- }
-
- static std::string getCompleteNodeLabel(const BasicBlock *Node,
- const Function *) {
- std::string Str;
- raw_string_ostream OS(Str);
-
- if (Node->getName().empty()) {
- WriteAsOperand(OS, Node, false);
- OS << ":";
- }
-
- OS << *Node;
- std::string OutStr = OS.str();
- if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
-
- // Process string output to make it nicer...
- for (unsigned i = 0; i != OutStr.length(); ++i)
- if (OutStr[i] == '\n') { // Left justify
- OutStr[i] = '\\';
- OutStr.insert(OutStr.begin()+i+1, 'l');
- } else if (OutStr[i] == ';') { // Delete comments!
- unsigned Idx = OutStr.find('\n', i+1); // Find end of line
- OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
- --i;
- }
-
- return OutStr;
- }
-
- std::string getNodeLabel(const BasicBlock *Node,
- const Function *Graph) {
- if (isSimple())
- return getSimpleNodeLabel(Node, Graph);
- else
- return getCompleteNodeLabel(Node, Graph);
- }
-
- static std::string getEdgeSourceLabel(const BasicBlock *Node,
- succ_const_iterator I) {
- // Label source of conditional branches with "T" or "F"
- if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
- if (BI->isConditional())
- return (I == succ_begin(Node)) ? "T" : "F";
-
- // Label source of switch edges with the associated value.
- if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
- unsigned SuccNo = I.getSuccessorIndex();
-
- if (SuccNo == 0) return "def";
-
- std::string Str;
- raw_string_ostream OS(Str);
- SwitchInst::ConstCaseIt Case =
- SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
- OS << Case.getCaseValue()->getValue();
- return OS.str();
- }
- return "";
- }
-};
-} // End llvm namespace
-
-namespace llvm {
- class FunctionPass;
- FunctionPass *createCFGPrinterPass ();
- FunctionPass *createCFGOnlyPrinterPass ();
-} // End llvm namespace
-
-#endif
Index: include/llvm/Analysis/DOTGraphTraitsPass.h
===================================================================
--- include/llvm/Analysis/DOTGraphTraitsPass.h (revision 183332)
+++ include/llvm/Analysis/DOTGraphTraitsPass.h (working copy)
@@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
-#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
namespace llvm {
Index: include/llvm/Pass.h
===================================================================
--- include/llvm/Pass.h (revision 183332)
+++ include/llvm/Pass.h (working copy)
@@ -129,6 +129,11 @@ public:
virtual Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const = 0;
+ /// createCFGPrinterPass - Get a Pass appropriate to print the CFG of functions
+ /// this pass operates. By default it returns Function CFG Printer pass. The
+ /// MachineFunction Pass overrides the definition.
+ virtual Pass *createCFGPrinterPass(const PassInfo *PI, const char *) const;
+
/// Each pass is responsible for assigning a pass manager to itself.
/// PMS is the stack of available pass manager.
virtual void assignPassManager(PMStack &,
Index: include/llvm/CodeGen/MachineFunctionPass.h
===================================================================
--- include/llvm/CodeGen/MachineFunctionPass.h (revision 183332)
+++ include/llvm/CodeGen/MachineFunctionPass.h (working copy)
@@ -51,6 +51,8 @@ private:
virtual Pass *createPrinterPass(raw_ostream &O,
const std::string &Banner) const;
+ virtual Pass *createCFGPrinterPass(const PassInfo *, const char *) const;
+
virtual bool runOnFunction(Function &F);
};
Index: lib/IR/PassManager.cpp
===================================================================
--- lib/IR/PassManager.cpp (revision 183335)
+++ lib/IR/PassManager.cpp (working copy)
@@ -17,6 +17,7 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -70,6 +71,16 @@ PrintAfter("print-after",
llvm::cl::desc("Print IR after specified passes"),
cl::Hidden);
+static PassOptionList
+DotCfgBefore("dot-cfg-before",
+ llvm::cl::desc("Dump CFG DOT file before specified passes"),
+ cl::Hidden);
+
+static PassOptionList
+DotCfgAfter("dot-cfg-after",
+ llvm::cl::desc("Dump CFG DOT file after specified passes"),
+ cl::Hidden);
+
static cl::opt<bool>
PrintBeforeAll("print-before-all",
llvm::cl::desc("Print IR before each pass"),
@@ -106,6 +117,18 @@ static bool ShouldPrintAfterPass(const P
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PI, PrintAfter);
}
+/// This is a utility to check whether a pass should have DOT CFG dumped
+/// before it.
+static bool ShouldPrintCFGBeforePass(const PassInfo *PI) {
+ return ShouldPrintBeforeOrAfterPass(PI, DotCfgBefore);
+}
+
+/// This is a utility to check whether a pass should have DOT CFG dumped
+/// after it.
+static bool ShouldPrintCFGAfterPass(const PassInfo *PI) {
+ return ShouldPrintBeforeOrAfterPass(PI, DotCfgAfter);
+}
+
} // End of llvm namespace
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
@@ -674,6 +697,12 @@ void PMTopLevelManager::schedulePass(Pas
PP->assignPassManager(activeStack, getTopLevelPassManagerType());
}
+ if (PI && !PI->isAnalysis() && (P->getPassKind() != PT_Loop) &&
+ ShouldPrintCFGBeforePass(PI)) {
+ Pass *PP = P->createCFGPrinterPass(PI, "before");
+ PP->assignPassManager(activeStack, getTopLevelPassManagerType());
+ }
+
// Add the requested pass to the best available pass manager.
P->assignPassManager(activeStack, getTopLevelPassManagerType());
@@ -682,6 +711,11 @@ void PMTopLevelManager::schedulePass(Pas
dbgs(), std::string("*** IR Dump After ") + P->getPassName() + " ***");
PP->assignPassManager(activeStack, getTopLevelPassManagerType());
}
+
+ if (PI && !PI->isAnalysis() && ShouldPrintCFGAfterPass(PI)) {
+ Pass *PP = P->createCFGPrinterPass(PI, "after");
+ PP->assignPassManager(activeStack, getTopLevelPassManagerType());
+ }
}
/// Find the pass that implements Analysis AID. Search immutable
Index: lib/IR/Pass.cpp
===================================================================
--- lib/IR/Pass.cpp (revision 183335)
+++ lib/IR/Pass.cpp (working copy)
@@ -16,6 +16,7 @@
#include "llvm/Pass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/PassRegistry.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
@@ -63,6 +64,10 @@ const char *Pass::getPassName() const {
return "Unnamed pass: implement Pass::getPassName()";
}
+Pass * Pass::createCFGPrinterPass(const PassInfo *PI, const char *O) const {
+ return llvm::createCFGPrinterPass(PI, O);
+}
+
void Pass::preparePassManager(PMStack &) {
// By default, don't do anything.
}
Index: lib/Analysis/CFGPrinter.cpp
===================================================================
--- lib/Analysis/CFGPrinter.cpp (revision 177877)
+++ lib/Analysis/CFGPrinter.cpp (working copy)
@@ -17,8 +17,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
using namespace llvm;
namespace {
@@ -69,69 +71,42 @@ INITIALIZE_PASS(CFGOnlyViewer, "view-cfg
"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) {
+template <bool CFGOnly>
+struct CFGPrinterT : public FunctionPass,
+ public CFGPrinterBase<Function, CFGOnly> {
+
+ static char ID; // Pass identification, replacement for typeid
+ typedef CFGPrinterBase<Function, CFGOnly> BaseT;
+
+ CFGPrinterT(const PassInfo *P = 0, const char *O = 0)
+ : FunctionPass(ID), BaseT(P, O) {
+ if (CFGOnly)
+ initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
+ else
initializeCFGPrinterPass(*PassRegistry::getPassRegistry());
- }
+ }
- virtual bool runOnFunction(Function &F) {
- std::string Filename = "cfg." + F.getName().str() + ".dot";
- errs() << "Writing '" << Filename << "'...";
-
- std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
-
- if (ErrorInfo.empty())
- WriteGraph(File, (const Function*)&F);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
- return false;
- }
+ virtual bool runOnFunction(Function &F) { return BaseT::run(&F); }
- void print(raw_ostream &OS, const Module* = 0) const {}
+ void print(raw_ostream &OS, const Module * = 0) const {}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
-}
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ 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 {
- static char ID; // Pass identification, replacement for typeid
- CFGOnlyPrinter() : FunctionPass(ID) {
- initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
- }
-
- virtual bool runOnFunction(Function &F) {
- std::string Filename = "cfg." + F.getName().str() + ".dot";
- errs() << "Writing '" << Filename << "'...";
+template<bool CFGOnly> char CFGPrinterT<CFGOnly> ::ID = 0;
+template struct CFGPrinterT<true>;
+template struct CFGPrinterT<false>;
+typedef CFGPrinterT<true> CFGOnlyPrinter;
+typedef CFGPrinterT<false> CFGPrinter;
- std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
-
- if (ErrorInfo.empty())
- WriteGraph(File, (const Function*)&F, true);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
- return false;
- }
- void print(raw_ostream &OS, const Module* = 0) const {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
}
-char CFGOnlyPrinter::ID = 0;
+INITIALIZE_PASS(CFGPrinter, "dot-cfg", "Print CFG of function to 'dot' file",
+ false, true)
+
INITIALIZE_PASS(CFGOnlyPrinter, "dot-cfg-only",
"Print CFG of function to 'dot' file (with no function bodies)",
false, true)
@@ -158,7 +133,10 @@ FunctionPass *llvm::createCFGPrinterPass
return new CFGPrinter();
}
+FunctionPass *llvm::createCFGPrinterPass (const PassInfo *PI, const char *O) {
+ return new CFGPrinter(PI, O);
+}
+
FunctionPass *llvm::createCFGOnlyPrinterPass () {
return new CFGOnlyPrinter();
}
-
Index: lib/Analysis/CFGPrinter.cpp
===================================================================
--- lib/Analysis/CFGPrinter.cpp (revision 183332)
+++ lib/Analysis/CFGPrinter.cpp (working copy)
@@ -1,164 +0,0 @@
-//===- CFGPrinter.cpp - DOT printer for the control flow graph ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-// The other main feature of this file is that it implements the
-// Function::viewCFG method, which is useful for debugging passes which operate
-// on the CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/CFGPrinter.h"
-#include "llvm/Pass.h"
-using namespace llvm;
-
-namespace {
- struct CFGViewer : public FunctionPass {
- static char ID; // Pass identifcation, replacement for typeid
- CFGViewer() : FunctionPass(ID) {
- initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
- }
-
- virtual bool runOnFunction(Function &F) {
- F.viewCFG();
- return false;
- }
-
- void print(raw_ostream &OS, const Module* = 0) const {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
-}
-
-char CFGViewer::ID = 0;
-INITIALIZE_PASS(CFGViewer, "view-cfg", "View CFG of function", false, true)
-
-namespace {
- struct CFGOnlyViewer : public FunctionPass {
- static char ID; // Pass identifcation, replacement for typeid
- CFGOnlyViewer() : FunctionPass(ID) {
- initializeCFGOnlyViewerPass(*PassRegistry::getPassRegistry());
- }
-
- virtual bool runOnFunction(Function &F) {
- F.viewCFGOnly();
- return false;
- }
-
- void print(raw_ostream &OS, const Module* = 0) const {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
-}
-
-char CFGOnlyViewer::ID = 0;
-INITIALIZE_PASS(CFGOnlyViewer, "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());
- }
-
- virtual bool runOnFunction(Function &F) {
- std::string Filename = "cfg." + F.getName().str() + ".dot";
- errs() << "Writing '" << Filename << "'...";
-
- std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
-
- if (ErrorInfo.empty())
- WriteGraph(File, (const Function*)&F);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
- return false;
- }
-
- void print(raw_ostream &OS, const Module* = 0) const {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- 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 {
- static char ID; // Pass identification, replacement for typeid
- CFGOnlyPrinter() : FunctionPass(ID) {
- initializeCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
- }
-
- virtual bool runOnFunction(Function &F) {
- std::string Filename = "cfg." + F.getName().str() + ".dot";
- errs() << "Writing '" << Filename << "'...";
-
- std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
-
- if (ErrorInfo.empty())
- WriteGraph(File, (const Function*)&F, true);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
- return false;
- }
- void print(raw_ostream &OS, const Module* = 0) const {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
-}
-
-char CFGOnlyPrinter::ID = 0;
-INITIALIZE_PASS(CFGOnlyPrinter, "dot-cfg-only",
- "Print CFG of function to 'dot' file (with no function bodies)",
- false, true)
-
-/// 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
-/// being a 'dot' and 'gv' program in your path.
-///
-void Function::viewCFG() const {
- ViewGraph(this, "cfg" + getName());
-}
-
-/// viewCFGOnly - This function is meant for use from the debugger. It works
-/// just like viewCFG, but it does not include the contents of basic blocks
-/// into the nodes, just the label. If you are only interested in the CFG t
-/// his can make the graph smaller.
-///
-void Function::viewCFGOnly() const {
- ViewGraph(this, "cfg" + getName(), true);
-}
-
-FunctionPass *llvm::createCFGPrinterPass () {
- return new CFGPrinter();
-}
-
-FunctionPass *llvm::createCFGOnlyPrinterPass () {
- return new CFGOnlyPrinter();
-}
-
Index: lib/CodeGen/MachineFunctionPass.cpp
===================================================================
--- lib/CodeGen/MachineFunctionPass.cpp (revision 183335)
+++ lib/CodeGen/MachineFunctionPass.cpp (working copy)
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/Analysis/CFGPrinter.h"
using namespace llvm;
Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
@@ -23,6 +24,12 @@ Pass *MachineFunctionPass::createPrinter
return createMachineFunctionPrinterPass(O, Banner);
}
+Pass *MachineFunctionPass::createCFGPrinterPass(const PassInfo *PI,
+ const char *O) const {
+
+ return createMachineCFGPrinterPass(PI, O);
+}
+
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
Index: lib/CodeGen/MachineFunctionPrinterPass.cpp
===================================================================
--- lib/CodeGen/MachineFunctionPrinterPass.cpp (revision 183335)
+++ lib/CodeGen/MachineFunctionPrinterPass.cpp (working copy)
@@ -15,6 +15,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -49,12 +50,54 @@ struct MachineFunctionPrinterPass : publ
};
char MachineFunctionPrinterPass::ID = 0;
+
+template <bool CFGOnly>
+struct MachineCFGPrinterT : public MachineFunctionPass,
+ public CFGPrinterBase<MachineFunction, CFGOnly> {
+
+ static char ID; // Pass identification, replacement for typeid
+ typedef CFGPrinterBase<MachineFunction, CFGOnly> BaseT;
+
+ MachineCFGPrinterT(const PassInfo *P = 0, const char *O = 0)
+ : MachineFunctionPass(ID), BaseT(P, O) {
+ if (CFGOnly)
+ initializeMachineCFGOnlyPrinterPass(*PassRegistry::getPassRegistry());
+ else
+ initializeMachineCFGPrinterPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual bool runOnMachineFunction(MachineFunction &F) {
+ return BaseT::run(&F);
+ }
+
+ void print(raw_ostream &OS, const Module * = 0) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+};
+
+template <bool CFGOnly> char MachineCFGPrinterT<CFGOnly>::ID = 0;
+template struct MachineCFGPrinterT<true>;
+template struct MachineCFGPrinterT<false>;
+typedef MachineCFGPrinterT<true> MachineCFGOnlyPrinter;
+typedef MachineCFGPrinterT<false> MachineCFGPrinter;
+
}
char &llvm::MachineFunctionPrinterPassID = MachineFunctionPrinterPass::ID;
INITIALIZE_PASS(MachineFunctionPrinterPass, "print-machineinstrs",
"Machine Function Printer", false, false)
+INITIALIZE_PASS(MachineCFGPrinter, "machine-dot-cfg",
+ "Print CFG of machine function to 'dot' file", false, true)
+INITIALIZE_PASS(
+ MachineCFGOnlyPrinter, "machine-dot-cfg-only",
+ "Print CFG of machine function to 'dot' file (with no function bodies)",
+ false, true)
+
+
namespace llvm {
/// Returns a newly-created MachineFunction Printer pass. The
/// default banner is empty.
@@ -64,4 +107,12 @@ MachineFunctionPass *createMachineFuncti
return new MachineFunctionPrinterPass(OS, Banner);
}
+FunctionPass *createMachineCFGPrinterPass (const PassInfo *PI, const char *O) {
+ return new MachineCFGPrinter(PI, O);
+}
+
+FunctionPass *createMachineCFGOnlyPrinterPass () {
+ return new MachineCFGOnlyPrinter();
+}
+
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment