Get rid of the global CFGOnly flag by threading a ShortNames parameters through the GraphViz rendering code.

Update other uses in the codebase for this change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74084 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2009-06-24 17:37:09 +00:00
parent 8539cfd30e
commit 8cbc94afb7
8 changed files with 57 additions and 49 deletions

View File

@ -51,7 +51,8 @@ struct DefaultDOTGraphTraits {
/// getNodeLabel - Given a node and a pointer to the top level graph, return /// getNodeLabel - Given a node and a pointer to the top level graph, return
/// the label to print in the node. /// the label to print in the node.
template<typename GraphType> template<typename GraphType>
static std::string getNodeLabel(const void *Node, const GraphType& Graph) { static std::string getNodeLabel(const void *Node,
const GraphType& Graph, bool ShortNames) {
return ""; return "";
} }

View File

@ -72,6 +72,7 @@ template<typename GraphType>
class GraphWriter { class GraphWriter {
std::ostream &O; std::ostream &O;
const GraphType &G; const GraphType &G;
bool ShortNames;
typedef DOTGraphTraits<GraphType> DOTTraits; typedef DOTGraphTraits<GraphType> DOTTraits;
typedef GraphTraits<GraphType> GTraits; typedef GraphTraits<GraphType> GTraits;
@ -79,7 +80,8 @@ class GraphWriter {
typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::nodes_iterator node_iterator;
typedef typename GTraits::ChildIteratorType child_iterator; typedef typename GTraits::ChildIteratorType child_iterator;
public: public:
GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {} GraphWriter(std::ostream &o, const GraphType &g, bool SN) :
O(o), G(g), ShortNames(SN) {}
void writeHeader(const std::string &Name) { void writeHeader(const std::string &Name) {
std::string GraphName = DOTTraits::getGraphName(G); std::string GraphName = DOTTraits::getGraphName(G);
@ -130,7 +132,7 @@ public:
O << "label=\"{"; O << "label=\"{";
if (!DOTTraits::renderGraphFromBottomUp()) { if (!DOTTraits::renderGraphFromBottomUp()) {
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
// If we should include the address of the node in the label, do so now. // If we should include the address of the node in the label, do so now.
if (DOTTraits::hasNodeAddressLabel(Node, G)) if (DOTTraits::hasNodeAddressLabel(Node, G))
@ -156,7 +158,7 @@ public:
} }
if (DOTTraits::renderGraphFromBottomUp()) { if (DOTTraits::renderGraphFromBottomUp()) {
O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames));
// If we should include the address of the node in the label, do so now. // If we should include the address of the node in the label, do so now.
if (DOTTraits::hasNodeAddressLabel(Node, G)) if (DOTTraits::hasNodeAddressLabel(Node, G))
@ -250,10 +252,11 @@ public:
template<typename GraphType> template<typename GraphType>
std::ostream &WriteGraph(std::ostream &O, const GraphType &G, std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
bool ShortNames = false,
const std::string &Name = "", const std::string &Name = "",
const std::string &Title = "") { const std::string &Title = "") {
// Start the graph emission process... // Start the graph emission process...
GraphWriter<GraphType> W(O, G); GraphWriter<GraphType> W(O, G, ShortNames);
// Output the header for the graph... // Output the header for the graph...
W.writeHeader(Title); W.writeHeader(Title);
@ -272,6 +275,7 @@ std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
template<typename GraphType> template<typename GraphType>
sys::Path WriteGraph(const GraphType &G, sys::Path WriteGraph(const GraphType &G,
const std::string& Name, const std::string& Name,
bool ShortNames = false,
const std::string& Title = "") { const std::string& Title = "") {
std::string ErrMsg; std::string ErrMsg;
sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg); sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
@ -290,7 +294,7 @@ sys::Path WriteGraph(const GraphType &G,
std::ofstream O(Filename.c_str()); std::ofstream O(Filename.c_str());
if (O.good()) { if (O.good()) {
WriteGraph(O, G, Name, Title); WriteGraph(O, G, ShortNames, Name, Title);
cerr << " done. \n"; cerr << " done. \n";
O.close(); O.close();
@ -308,8 +312,9 @@ sys::Path WriteGraph(const GraphType &G,
template<typename GraphType> template<typename GraphType>
void ViewGraph(const GraphType& G, void ViewGraph(const GraphType& G,
const std::string& Name, const std::string& Name,
bool ShortNames = false,
const std::string& Title = "") { const std::string& Title = "") {
sys::Path Filename = WriteGraph(G, Name, Title); sys::Path Filename = WriteGraph(G, Name, ShortNames, Title);
if (Filename.isEmpty()) { if (Filename.isEmpty()) {
return; return;

View File

@ -31,12 +31,6 @@
#include <fstream> #include <fstream>
using namespace llvm; 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 { namespace llvm {
template<> template<>
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
@ -45,12 +39,13 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
} }
static std::string getNodeLabel(const BasicBlock *Node, static std::string getNodeLabel(const BasicBlock *Node,
const Function *Graph) { const Function *Graph,
if (CFGOnly && !Node->getName().empty()) bool ShortNames) {
if (ShortNames && !Node->getName().empty())
return Node->getName() + ":"; return Node->getName() + ":";
std::ostringstream Out; std::ostringstream Out;
if (CFGOnly) { if (ShortNames) {
WriteAsOperand(Out, Node, false); WriteAsOperand(Out, Node, false);
return Out.str(); return Out.str();
} }
@ -117,9 +112,7 @@ namespace {
CFGOnlyViewer() : FunctionPass(&ID) {} CFGOnlyViewer() : FunctionPass(&ID) {}
virtual bool runOnFunction(Function &F) { virtual bool runOnFunction(Function &F) {
CFGOnly = true;
F.viewCFG(); F.viewCFG();
CFGOnly = false;
return false; return false;
} }
@ -168,14 +161,20 @@ static RegisterPass<CFGPrinter>
P1("dot-cfg", "Print CFG of function to 'dot' file", false, true); P1("dot-cfg", "Print CFG of function to 'dot' file", false, true);
namespace { namespace {
struct VISIBILITY_HIDDEN CFGOnlyPrinter : public CFGPrinter { struct VISIBILITY_HIDDEN CFGOnlyPrinter : public FunctionPass {
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
CFGOnlyPrinter() : CFGPrinter(&ID) {} CFGOnlyPrinter() : FunctionPass(&ID) {}
explicit CFGOnlyPrinter(void *pid) : FunctionPass(pid) {}
virtual bool runOnFunction(Function &F) { virtual bool runOnFunction(Function &F) {
bool OldCFGOnly = CFGOnly; std::string Filename = "cfg." + F.getName() + ".dot";
CFGOnly = true; cerr << "Writing '" << Filename << "'...";
CFGPrinter::runOnFunction(F); std::ofstream File(Filename.c_str());
CFGOnly = OldCFGOnly;
if (File.good())
WriteGraph(File, (const Function*)&F, true);
else
cerr << " error opening file for writing!";
cerr << "\n";
return false; return false;
} }
void print(std::ostream &OS, const Module* = 0) const {} void print(std::ostream &OS, const Module* = 0) const {}
@ -206,9 +205,7 @@ void Function::viewCFG() const {
/// his can make the graph smaller. /// his can make the graph smaller.
/// ///
void Function::viewCFGOnly() const { void Function::viewCFGOnly() const {
CFGOnly = true; ViewGraph(this, "cfg" + getName(), true);
viewCFG();
CFGOnly = false;
} }
FunctionPass *llvm::createCFGPrinterPass () { FunctionPass *llvm::createCFGPrinterPass () {

View File

@ -295,12 +295,6 @@ void MachineFunction::print(std::ostream &OS) const {
OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
} }
/// 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 { namespace llvm {
template<> template<>
struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
@ -309,13 +303,14 @@ namespace llvm {
} }
static std::string getNodeLabel(const MachineBasicBlock *Node, static std::string getNodeLabel(const MachineBasicBlock *Node,
const MachineFunction *Graph) { const MachineFunction *Graph,
if (CFGOnly && Node->getBasicBlock() && bool ShortNames) {
if (ShortNames && Node->getBasicBlock() &&
!Node->getBasicBlock()->getName().empty()) !Node->getBasicBlock()->getName().empty())
return Node->getBasicBlock()->getName() + ":"; return Node->getBasicBlock()->getName() + ":";
std::ostringstream Out; std::ostringstream Out;
if (CFGOnly) { if (ShortNames) {
Out << Node->getNumber() << ':'; Out << Node->getNumber() << ':';
return Out.str(); return Out.str();
} }
@ -348,9 +343,12 @@ void MachineFunction::viewCFG() const
void MachineFunction::viewCFGOnly() const void MachineFunction::viewCFGOnly() const
{ {
CFGOnly = true; #ifndef NDEBUG
viewCFG(); ViewGraph(this, "mf" + getFunction()->getName(), true);
CFGOnly = false; #else
cerr << "SelectionDAG::viewGraph is only available in debug builds on "
<< "systems with Graphviz or gv!\n";
#endif // NDEBUG
} }
// The next two methods are used to construct and to retrieve // The next two methods are used to construct and to retrieve

View File

@ -59,7 +59,8 @@ namespace llvm {
static std::string getNodeLabel(const SUnit *Node, static std::string getNodeLabel(const SUnit *Node,
const ScheduleDAG *Graph); const ScheduleDAG *Graph,
bool ShortNames);
static std::string getNodeAttributes(const SUnit *N, static std::string getNodeAttributes(const SUnit *N,
const ScheduleDAG *Graph) { const ScheduleDAG *Graph) {
return "shape=Mrecord"; return "shape=Mrecord";
@ -73,7 +74,8 @@ namespace llvm {
} }
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU, std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) { const ScheduleDAG *G,
bool ShortNames) {
return G->getGraphNodeLabel(SU); return G->getGraphNodeLabel(SU);
} }
@ -84,11 +86,11 @@ void ScheduleDAG::viewGraph() {
// This code is only for debugging! // This code is only for debugging!
#ifndef NDEBUG #ifndef NDEBUG
if (BB->getBasicBlock()) if (BB->getBasicBlock())
ViewGraph(this, "dag." + MF.getFunction()->getName(), ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName() + ':' + "Scheduling-Units Graph for " + MF.getFunction()->getName() + ':' +
BB->getBasicBlock()->getName()); BB->getBasicBlock()->getName());
else else
ViewGraph(this, "dag." + MF.getFunction()->getName(), ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName()); "Scheduling-Units Graph for " + MF.getFunction()->getName());
#else #else
cerr << "ScheduleDAG::viewGraph is only available in debug builds on " cerr << "ScheduleDAG::viewGraph is only available in debug builds on "

View File

@ -94,7 +94,8 @@ namespace llvm {
static std::string getNodeLabel(const SDNode *Node, static std::string getNodeLabel(const SDNode *Node,
const SelectionDAG *Graph); const SelectionDAG *Graph,
bool ShortNames);
static std::string getNodeAttributes(const SDNode *N, static std::string getNodeAttributes(const SDNode *N,
const SelectionDAG *Graph) { const SelectionDAG *Graph) {
#ifndef NDEBUG #ifndef NDEBUG
@ -120,7 +121,8 @@ namespace llvm {
} }
std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node, std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
const SelectionDAG *G) { const SelectionDAG *G,
bool ShortNames) {
std::string Op = Node->getOperationName(G); std::string Op = Node->getOperationName(G);
if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) { if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
@ -262,7 +264,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
void SelectionDAG::viewGraph(const std::string &Title) { void SelectionDAG::viewGraph(const std::string &Title) {
// This code is only for debugging! // This code is only for debugging!
#ifndef NDEBUG #ifndef NDEBUG
ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(), ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(), false,
Title); Title);
#else #else
cerr << "SelectionDAG::viewGraph is only available in debug builds on " cerr << "SelectionDAG::viewGraph is only available in debug builds on "
@ -393,7 +395,8 @@ std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
FlaggedNodes.push_back(N); FlaggedNodes.push_back(N);
while (!FlaggedNodes.empty()) { while (!FlaggedNodes.empty()) {
O << DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(), DAG); O << DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(),
DAG, false);
FlaggedNodes.pop_back(); FlaggedNodes.pop_back();
if (!FlaggedNodes.empty()) if (!FlaggedNodes.empty())
O << "\n "; O << "\n ";

View File

@ -477,7 +477,8 @@ namespace llvm {
{ {
template<typename GraphType> template<typename GraphType>
static std::string getNodeLabel(const Node* N, const GraphType&) static std::string getNodeLabel(const Node* N, const GraphType&,
bool ShortNames)
{ {
if (N->ToolPtr) if (N->ToolPtr)
if (N->ToolPtr->IsJoin()) if (N->ToolPtr->IsJoin())

View File

@ -49,7 +49,8 @@ namespace llvm {
return "Call Graph"; return "Call Graph";
} }
static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph,
bool ShortNames) {
if (Node->getFunction()) if (Node->getFunction())
return ((Value*)Node->getFunction())->getName(); return ((Value*)Node->getFunction())->getName();
else else