X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FCFGPrinter.cpp;h=73f50d741c616d7da425fbd18d42e25a30432460;hb=bab812b4b0126839fe6e026aad54c90164c89765;hp=cc0f6b43182ada94850abd5d1efc632a067db1fa;hpb=a196b993e0b79142c6388c75b71f1fc54c767dd1;p=oota-llvm.git diff --git a/lib/Analysis/CFGPrinter.cpp b/lib/Analysis/CFGPrinter.cpp index cc0f6b43182..73f50d741c6 100644 --- a/lib/Analysis/CFGPrinter.cpp +++ b/lib/Analysis/CFGPrinter.cpp @@ -2,12 +2,12 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file defines a '-print-cfg' analysis pass, which emits the +// 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. // @@ -31,26 +31,21 @@ #include using namespace llvm; -/// CFGOnly flag - This is used to control whether or not the CFG graph printer -/// prints out the contents of basic blocks or not. This is acceptable because -/// this code is only really used for debugging purposes. -/// -static bool CFGOnly = false; - namespace llvm { template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { static std::string getGraphName(const Function *F) { - return "CFG for '" + F->getName() + "' function"; + return "CFG for '" + F->getNameStr() + "' function"; } static std::string getNodeLabel(const BasicBlock *Node, - const Function *Graph) { - if (CFGOnly && !Node->getName().empty()) - return Node->getName() + ":"; + const Function *Graph, + bool ShortNames) { + if (ShortNames && !Node->getName().empty()) + return Node->getNameStr() + ":"; std::ostringstream Out; - if (CFGOnly) { + if (ShortNames) { WriteAsOperand(Out, Node, false); return Out.str(); } @@ -92,7 +87,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { namespace { struct VISIBILITY_HIDDEN CFGViewer : public FunctionPass { static char ID; // Pass identifcation, replacement for typeid - CFGViewer() : FunctionPass((intptr_t)&ID) {} + CFGViewer() : FunctionPass(&ID) {} virtual bool runOnFunction(Function &F) { F.viewCFG(); @@ -105,19 +100,19 @@ namespace { AU.setPreservesAll(); } }; +} - char CFGViewer::ID = 0; - RegisterPass V0("view-cfg", - "View CFG of function"); +char CFGViewer::ID = 0; +static RegisterPass +V0("view-cfg", "View CFG of function", false, true); +namespace { struct VISIBILITY_HIDDEN CFGOnlyViewer : public FunctionPass { static char ID; // Pass identifcation, replacement for typeid - CFGOnlyViewer() : FunctionPass((intptr_t)&ID) {} + CFGOnlyViewer() : FunctionPass(&ID) {} virtual bool runOnFunction(Function &F) { - CFGOnly = true; F.viewCFG(); - CFGOnly = false; return false; } @@ -127,17 +122,21 @@ namespace { AU.setPreservesAll(); } }; +} - char CFGOnlyViewer::ID = 0; - RegisterPass V1("view-cfg-only", - "View CFG of function (with no function bodies)"); +char CFGOnlyViewer::ID = 0; +static RegisterPass +V1("view-cfg-only", + "View CFG of function (with no function bodies)", false, true); +namespace { struct VISIBILITY_HIDDEN CFGPrinter : public FunctionPass { static char ID; // Pass identification, replacement for typeid - CFGPrinter() : FunctionPass((intptr_t)&ID) {} + CFGPrinter() : FunctionPass(&ID) {} + explicit CFGPrinter(void *pid) : FunctionPass(pid) {} virtual bool runOnFunction(Function &F) { - std::string Filename = "cfg." + F.getName() + ".dot"; + std::string Filename = "cfg." + F.getNameStr() + ".dot"; cerr << "Writing '" << Filename << "'..."; std::ofstream File(Filename.c_str()); @@ -155,18 +154,27 @@ namespace { AU.setPreservesAll(); } }; +} - char CFGPrinter::ID = 0; - RegisterPass P1("print-cfg", - "Print CFG of function to 'dot' file"); +char CFGPrinter::ID = 0; +static RegisterPass +P1("dot-cfg", "Print CFG of function to 'dot' file", false, true); - struct VISIBILITY_HIDDEN CFGOnlyPrinter : public CFGPrinter { +namespace { + struct VISIBILITY_HIDDEN CFGOnlyPrinter : public FunctionPass { static char ID; // Pass identification, replacement for typeid + CFGOnlyPrinter() : FunctionPass(&ID) {} + explicit CFGOnlyPrinter(void *pid) : FunctionPass(pid) {} virtual bool runOnFunction(Function &F) { - bool OldCFGOnly = CFGOnly; - CFGOnly = true; - CFGPrinter::runOnFunction(F); - CFGOnly = OldCFGOnly; + std::string Filename = "cfg." + F.getNameStr() + ".dot"; + cerr << "Writing '" << Filename << "'..."; + std::ofstream File(Filename.c_str()); + + if (File.good()) + WriteGraph(File, (const Function*)&F, true); + else + cerr << " error opening file for writing!"; + cerr << "\n"; return false; } void print(std::ostream &OS, const Module* = 0) const {} @@ -175,20 +183,20 @@ namespace { AU.setPreservesAll(); } }; - - char CFGOnlyPrinter::ID = 0; - RegisterPass - P2("print-cfg-only", - "Print CFG of function to 'dot' file (with no function bodies)"); } +char CFGOnlyPrinter::ID = 0; +static RegisterPass +P2("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()); + ViewGraph(this, "cfg" + getNameStr()); } /// viewCFGOnly - This function is meant for use from the debugger. It works @@ -197,9 +205,7 @@ void Function::viewCFG() const { /// his can make the graph smaller. /// void Function::viewCFGOnly() const { - CFGOnly = true; - viewCFG(); - CFGOnly = false; + ViewGraph(this, "cfg" + getNameStr(), true); } FunctionPass *llvm::createCFGPrinterPass () {