Add an option, -view-sunit-dags, for viewing the actual SUnit DAGs used by
authorDan Gohman <gohman@apple.com>
Tue, 28 Aug 2007 20:32:58 +0000 (20:32 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 28 Aug 2007 20:32:58 +0000 (20:32 +0000)
scheduling.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41556 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/ScheduleDAG.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp

index d52936abab64558a272c7bd2e2e9769f450b5997..fdae9273e780e1c74b40f5341d9d4dfcb7879791 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/SmallSet.h"
 
 namespace llvm {
@@ -191,6 +192,11 @@ namespace llvm {
 
     virtual ~ScheduleDAG() {}
 
+    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
+    /// using 'dot'.
+    ///
+    void viewGraph();
+  
     /// Run - perform scheduling.
     ///
     MachineBasicBlock *Run();
@@ -315,6 +321,68 @@ namespace llvm {
   ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
                                       SelectionDAG *DAG,
                                       MachineBasicBlock *BB);
+
+  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
+    SUnit *Node;
+    unsigned Operand;
+
+    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
+  public:
+    bool operator==(const SUnitIterator& x) const {
+      return Operand == x.Operand;
+    }
+    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
+
+    const SUnitIterator &operator=(const SUnitIterator &I) {
+      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
+      Operand = I.Operand;
+      return *this;
+    }
+
+    pointer operator*() const {
+      return Node->Preds[Operand].first;
+    }
+    pointer operator->() const { return operator*(); }
+
+    SUnitIterator& operator++() {                // Preincrement
+      ++Operand;
+      return *this;
+    }
+    SUnitIterator operator++(int) { // Postincrement
+      SUnitIterator tmp = *this; ++*this; return tmp;
+    }
+
+    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
+    static SUnitIterator end  (SUnit *N) {
+      return SUnitIterator(N, N->Preds.size());
+    }
+
+    unsigned getOperand() const { return Operand; }
+    const SUnit *getNode() const { return Node; }
+    bool isChain() const { return Node->Preds[Operand].second; }
+  };
+
+  template <> struct GraphTraits<SUnit*> {
+    typedef SUnit NodeType;
+    typedef SUnitIterator ChildIteratorType;
+    static inline NodeType *getEntryNode(SUnit *N) { return N; }
+    static inline ChildIteratorType child_begin(NodeType *N) {
+      return SUnitIterator::begin(N);
+    }
+    static inline ChildIteratorType child_end(NodeType *N) {
+      return SUnitIterator::end(N);
+    }
+  };
+
+  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
+    typedef std::vector<SUnit>::iterator nodes_iterator;
+    static nodes_iterator nodes_begin(ScheduleDAG *G) {
+      return G->SUnits.begin();
+    }
+    static nodes_iterator nodes_end(ScheduleDAG *G) {
+      return G->SUnits.end();
+    }
+  };
 }
 
 #endif
index 92e34bbc48f88cd96d92a0c5f2a4397a754f3bbb..60a9cd1def4e4a895c0e154987029bf167e9e8a1 100644 (file)
@@ -54,8 +54,11 @@ ViewISelDAGs("view-isel-dags", cl::Hidden,
 static cl::opt<bool>
 ViewSchedDAGs("view-sched-dags", cl::Hidden,
           cl::desc("Pop up a window to show sched dags as they are processed"));
+static cl::opt<bool>
+ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
+          cl::desc("Pop up a window to show SUnit dags after they are processed"));
 #else
-static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0;
+static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0, ViewSUnitDAGs = 0;
 #endif
 
 //===---------------------------------------------------------------------===//
@@ -4842,6 +4845,9 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
   
   ScheduleDAG *SL = Ctor(this, &DAG, BB);
   BB = SL->Run();
+
+  if (ViewSUnitDAGs) SL->viewGraph();
+
   delete SL;
 }
 
index 12b568262483e04a5537f1f13f1351af5b76d129..0ce46fdf041030f486711d3d2053bc6a41f80920 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Function.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/Target/MRegisterInfo.h"
@@ -243,3 +244,72 @@ void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
 #endif
 }
 
+namespace llvm {
+  template<>
+  struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
+    static std::string getGraphName(const ScheduleDAG *G) {
+      return DOTGraphTraits<SelectionDAG*>::getGraphName(&G->DAG);
+    }
+
+    static bool renderGraphFromBottomUp() {
+      return true;
+    }
+    
+    static bool hasNodeAddressLabel(const SUnit *Node,
+                                    const ScheduleDAG *Graph) {
+      return true;
+    }
+    
+    /// If you want to override the dot attributes printed for a particular
+    /// edge, override this method.
+    template<typename EdgeIter>
+    static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
+      if (EI.isChain())
+        return "color=blue,style=dashed";
+      return "";
+    }
+    
+
+    static std::string getNodeLabel(const SUnit *Node,
+                                    const ScheduleDAG *Graph);
+    static std::string getNodeAttributes(const SUnit *N,
+                                         const ScheduleDAG *Graph) {
+      return "shape=Mrecord";
+    }
+
+    static void addCustomGraphFeatures(ScheduleDAG *G,
+                                       GraphWriter<ScheduleDAG*> &GW) {
+      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
+      if (G->DAG.getRoot().Val)
+        GW.emitEdge(0, -1, G->SUnitMap[G->DAG.getRoot().Val], -1, "");
+    }
+  };
+}
+
+std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
+                                                       const ScheduleDAG *G) {
+  std::string Op;
+
+  for (unsigned i = 0; i < SU->FlaggedNodes.size(); ++i) {
+    Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->FlaggedNodes[i],
+                                                      &G->DAG) + "\n";
+  }
+
+  Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->Node, &G->DAG);
+
+  return Op;
+}
+
+
+/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
+/// rendered using 'dot'.
+///
+void ScheduleDAG::viewGraph() {
+// This code is only for debugging!
+#ifndef NDEBUG
+  ViewGraph(this, "dag." + DAG.getMachineFunction().getFunction()->getName());
+#else
+  cerr << "ScheduleDAG::viewGraph is only available in debug builds on "
+       << "systems with Graphviz or gv!\n";
+#endif  // NDEBUG
+}