In the TD pass, don't iterate over the scalar map to find the globals, iterate over
[oota-llvm.git] / lib / Analysis / DataStructure / Printer.cpp
index 7f0bf5a5120d6ae859a5b4d7660eead83813d9c1..7cea561c1480041a051da12d779c33534fb2d3ca 100644 (file)
@@ -1,4 +1,11 @@
 //===- Printer.cpp - Code for printing data structure graphs nicely -------===//
+// 
+//                     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 implements the 'dot' graph printer.
 //
 #include "llvm/Analysis/DSGraph.h"
 #include "llvm/Analysis/DSGraphTraits.h"
 #include "llvm/Module.h"
+#include "llvm/Constants.h"
 #include "llvm/Assembly/Writer.h"
 #include "Support/CommandLine.h"
 #include "Support/GraphWriter.h"
 #include "Support/Statistic.h"
 #include <fstream>
 #include <sstream>
+using namespace llvm;
 
 // OnlyPrintMain - The DataStructure printer exposes this option to allow
 // printing of only the graph for "main".
 //
 namespace {
   cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
+  cl::opt<bool> DontPrintAnything("dont-print-ds", cl::ReallyHidden);
   Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
   Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
 }
 
-
 void DSNode::dump() const { print(std::cerr, 0); }
 
 static std::string getCaption(const DSNode *N, const DSGraph *G) {
   std::stringstream OS;
-  Module *M = G && G->hasFunction() ? G->getFunction().getParent() : 0;
+  Module *M = 0;
+  // Get the module from ONE of the functions in the graph it is available.
+  if (G && !G->getReturnNodes().empty())
+    M = G->getReturnNodes().begin()->first->getParent();
 
   if (N->isNodeCompletelyFolded())
-    OS << "FOLDED";
+    OS << "COLLAPSED";
   else {
     WriteTypeSymbolic(OS, N->getType(), M);
     if (N->isArray())
       OS << " array";
   }
-  if (N->NodeType) {
+  if (unsigned NodeType = N->getNodeFlags()) {
     OS << ": ";
-    if (N->NodeType & DSNode::AllocaNode ) OS << "S";
-    if (N->NodeType & DSNode::HeapNode   ) OS << "H";
-    if (N->NodeType & DSNode::GlobalNode ) OS << "G";
-    if (N->NodeType & DSNode::UnknownNode) OS << "U";
-    if (N->NodeType & DSNode::Incomplete ) OS << "I";
-    if (N->NodeType & DSNode::Modified   ) OS << "M";
-    if (N->NodeType & DSNode::Read       ) OS << "R";
-    if (N->NodeType & DSNode::DEAD       ) OS << "<dead>";
+    if (NodeType & DSNode::AllocaNode ) OS << "S";
+    if (NodeType & DSNode::HeapNode   ) OS << "H";
+    if (NodeType & DSNode::GlobalNode ) OS << "G";
+    if (NodeType & DSNode::UnknownNode) OS << "U";
+    if (NodeType & DSNode::Incomplete ) OS << "I";
+    if (NodeType & DSNode::Modified   ) OS << "M";
+    if (NodeType & DSNode::Read       ) OS << "R";
+#ifndef NDEBUG
+    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
+#endif
     OS << "\n";
   }
 
@@ -59,13 +73,15 @@ static std::string getCaption(const DSNode *N, const DSGraph *G) {
   return OS.str();
 }
 
+namespace llvm {
 template<>
 struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
   static std::string getGraphName(const DSGraph *G) {
-    if (G->hasFunction())
-      return "Function " + G->getFunction().getName();
-    else
-      return "Global graph";
+    switch (G->getReturnNodes().size()) {
+    case 0: return G->getFunctionNames();
+    case 1: return "Function " + G->getFunctionNames();
+    default: return "Functions: " + G->getFunctionNames();
+    }
   }
 
   static const char *getGraphProperties(const DSGraph *G) {
@@ -86,13 +102,14 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
   ///
   static void addCustomGraphFeatures(const DSGraph *G,
                                      GraphWriter<const DSGraph*> &GW) {
-    Module *CurMod = G->hasFunction() ? G->getFunction().getParent() : 0;
+    Module *CurMod = 0;
+    if (!G->getReturnNodes().empty())
+      CurMod = G->getReturnNodes().begin()->first->getParent();
 
     // Add scalar nodes to the graph...
-    const hash_map<Value*, DSNodeHandle> &VM = G->getScalarMap();
-    for (hash_map<Value*, DSNodeHandle>::const_iterator I = VM.begin();
-         I != VM.end(); ++I)
-      if (!isa<GlobalValue>(I->first)) {
+    const DSGraph::ScalarMapTy &VM = G->getScalarMap();
+    for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
+      if (!isa<GlobalValue>(I->first) && !isa<ConstantPointerRef>(I->first)) {
         std::stringstream OS;
         WriteAsOperand(OS, I->first, false, true, CurMod);
         GW.emitSimpleNode(I->first, "", OS.str());
@@ -106,16 +123,24 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
 
 
     // Output the returned value pointer...
-    if (G->getRetNode().getNode() != 0) {
-      // Output the return node...
-      GW.emitSimpleNode((void*)1, "plaintext=circle", "returning");
-
-      // Add edge from return node to real destination
-      int RetEdgeDest = G->getRetNode().getOffset() >> DS::PointerShift;;
-      if (RetEdgeDest == 0) RetEdgeDest = -1;
-      GW.emitEdge((void*)1, -1, G->getRetNode().getNode(),
-                  RetEdgeDest, "arrowtail=tee,color=gray63");
-    }
+    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
+    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
+           E = RetNodes.end(); I != E; ++I)
+      if (I->second.getNode()) {
+        std::string Label;
+        if (RetNodes.size() == 1)
+          Label = "returning";
+        else
+          Label = I->first->getName() + " ret node";
+        // Output the return node...
+        GW.emitSimpleNode((void*)I->first, "plaintext=circle", Label);
+
+        // Add edge from return node to real destination
+        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
+        if (RetEdgeDest == 0) RetEdgeDest = -1;
+        GW.emitEdge((void*)I->first, -1, I->second.getNode(),
+                    RetEdgeDest, "arrowtail=tee,color=gray63");
+      }
 
     // Output all of the call nodes...
     const std::vector<DSCallSite> &FCs =
@@ -155,6 +180,7 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
     }
   }
 };
+}   // end namespace llvm
 
 void DSNode::print(std::ostream &O, const DSGraph *G) const {
   GraphWriter<const DSGraph *> W(O, G);
@@ -247,13 +273,23 @@ static void printCollection(const Collection &C, std::ostream &O,
 
 // print - Print out the analysis results...
 void LocalDataStructures::print(std::ostream &O, const Module *M) const {
+  if (DontPrintAnything) return;
   printCollection(*this, O, M, "ds.");
 }
 
 void BUDataStructures::print(std::ostream &O, const Module *M) const {
+  if (DontPrintAnything) return;
   printCollection(*this, O, M, "bu.");
 }
 
 void TDDataStructures::print(std::ostream &O, const Module *M) const {
+  if (DontPrintAnything) return;
   printCollection(*this, O, M, "td.");
 }
+
+void CompleteBUDataStructures::print(std::ostream &O, const Module *M) const {
+  if (DontPrintAnything) return;
+  printCollection(*this, O, M, "cbu.");
+}
+
+