LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SelectionDAGPrinter.cpp
Go to the documentation of this file.
1 //===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements the SelectionDAG::viewGraph method.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "ScheduleDAGSDNodes.h"
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Assembly/Writer.h"
22 #include "llvm/DebugInfo.h"
23 #include "llvm/IR/Constants.h"
24 #include "llvm/Support/Debug.h"
29 using namespace llvm;
30 
31 namespace llvm {
32  template<>
34 
35  explicit DOTGraphTraits(bool isSimple=false) :
36  DefaultDOTGraphTraits(isSimple) {}
37 
38  static bool hasEdgeDestLabels() {
39  return true;
40  }
41 
42  static unsigned numEdgeDestLabels(const void *Node) {
43  return ((const SDNode *) Node)->getNumValues();
44  }
45 
46  static std::string getEdgeDestLabel(const void *Node, unsigned i) {
47  return ((const SDNode *) Node)->getValueType(i).getEVTString();
48  }
49 
50  template<typename EdgeIter>
51  static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
52  return itostr(I - SDNodeIterator::begin((const SDNode *) Node));
53  }
54 
55  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
56  /// should actually target another edge source, not a node. If this method
57  /// is implemented, getEdgeTarget should be implemented.
58  template<typename EdgeIter>
59  static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
60  return true;
61  }
62 
63  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
64  /// called to determine which outgoing edge of Node is the target of this
65  /// edge.
66  template<typename EdgeIter>
67  static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
68  SDNode *TargetNode = *I;
69  SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
70  std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
71  return NI;
72  }
73 
74  static std::string getGraphName(const SelectionDAG *G) {
75  return G->getMachineFunction().getName();
76  }
77 
78  static bool renderGraphFromBottomUp() {
79  return true;
80  }
81 
82  static bool hasNodeAddressLabel(const SDNode *Node,
83  const SelectionDAG *Graph) {
84  return true;
85  }
86 
87  /// If you want to override the dot attributes printed for a particular
88  /// edge, override this method.
89  template<typename EdgeIter>
90  static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
91  const SelectionDAG *Graph) {
92  SDValue Op = EI.getNode()->getOperand(EI.getOperand());
93  EVT VT = Op.getValueType();
94  if (VT == MVT::Glue)
95  return "color=red,style=bold";
96  else if (VT == MVT::Other)
97  return "color=blue,style=dashed";
98  return "";
99  }
100 
101 
102  static std::string getSimpleNodeLabel(const SDNode *Node,
103  const SelectionDAG *G) {
104  std::string Result = Node->getOperationName(G);
105  {
106  raw_string_ostream OS(Result);
107  Node->print_details(OS, G);
108  }
109  return Result;
110  }
111  std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
112  static std::string getNodeAttributes(const SDNode *N,
113  const SelectionDAG *Graph) {
114 #ifndef NDEBUG
115  const std::string &Attrs = Graph->getGraphAttrs(N);
116  if (!Attrs.empty()) {
117  if (Attrs.find("shape=") == std::string::npos)
118  return std::string("shape=Mrecord,") + Attrs;
119  else
120  return Attrs;
121  }
122 #endif
123  return "shape=Mrecord";
124  }
125 
128  GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
129  if (G->getRoot().getNode())
130  GW.emitEdge(0, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
131  "color=blue,style=dashed");
132  }
133  };
134 }
135 
137  const SelectionDAG *G) {
139 }
140 
141 
142 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
143 /// rendered using 'dot'.
144 ///
145 void SelectionDAG::viewGraph(const std::string &Title) {
146 // This code is only for debugging!
147 #ifndef NDEBUG
148  ViewGraph(this, "dag." + getMachineFunction().getName(),
149  false, Title);
150 #else
151  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
152  << "systems with Graphviz or gv!\n";
153 #endif // NDEBUG
154 }
155 
156 // This overload is defined out-of-line here instead of just using a
157 // default parameter because this is easiest for gdb to call.
159  viewGraph("");
160 }
161 
162 /// clearGraphAttrs - Clear all previously defined node graph attributes.
163 /// Intended to be used from a debugging tool (eg. gdb).
165 #ifndef NDEBUG
166  NodeGraphAttrs.clear();
167 #else
168  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
169  << " on systems with Graphviz or gv!\n";
170 #endif
171 }
172 
173 
174 /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
175 ///
176 void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
177 #ifndef NDEBUG
178  NodeGraphAttrs[N] = Attrs;
179 #else
180  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
181  << " on systems with Graphviz or gv!\n";
182 #endif
183 }
184 
185 
186 /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
187 /// Used from getNodeAttributes.
188 const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
189 #ifndef NDEBUG
190  std::map<const SDNode *, std::string>::const_iterator I =
191  NodeGraphAttrs.find(N);
192 
193  if (I != NodeGraphAttrs.end())
194  return I->second;
195  else
196  return "";
197 #else
198  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
199  << " on systems with Graphviz or gv!\n";
200  return std::string();
201 #endif
202 }
203 
204 /// setGraphColor - Convenience for setting node color attribute.
205 ///
206 void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
207 #ifndef NDEBUG
208  NodeGraphAttrs[N] = std::string("color=") + Color;
209 #else
210  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
211  << " on systems with Graphviz or gv!\n";
212 #endif
213 }
214 
215 /// setSubgraphColorHelper - Implement setSubgraphColor. Return
216 /// whether we truncated the search.
217 ///
218 bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
219  int level, bool &printed) {
220  bool hit_limit = false;
221 
222 #ifndef NDEBUG
223  if (level >= 20) {
224  if (!printed) {
225  printed = true;
226  DEBUG(dbgs() << "setSubgraphColor hit max level\n");
227  }
228  return true;
229  }
230 
231  unsigned oldSize = visited.size();
232  visited.insert(N);
233  if (visited.size() != oldSize) {
234  setGraphColor(N, Color);
236  i != iend;
237  ++i) {
238  hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
239  }
240  }
241 #else
242  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
243  << " on systems with Graphviz or gv!\n";
244 #endif
245  return hit_limit;
246 }
247 
248 /// setSubgraphColor - Convenience for setting subgraph color attribute.
249 ///
250 void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
251 #ifndef NDEBUG
252  DenseSet<SDNode *> visited;
253  bool printed = false;
254  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
255  // Visually mark that we hit the limit
256  if (strcmp(Color, "red") == 0) {
257  setSubgraphColorHelper(N, "blue", visited, 0, printed);
258  } else if (strcmp(Color, "yellow") == 0) {
259  setSubgraphColorHelper(N, "green", visited, 0, printed);
260  }
261  }
262 
263 #else
264  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
265  << " on systems with Graphviz or gv!\n";
266 #endif
267 }
268 
269 std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
270  std::string s;
271  raw_string_ostream O(s);
272  O << "SU(" << SU->NodeNum << "): ";
273  if (SU->getNode()) {
274  SmallVector<SDNode *, 4> GluedNodes;
275  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
276  GluedNodes.push_back(N);
277  while (!GluedNodes.empty()) {
278  O << DOTGraphTraits<SelectionDAG*>
279  ::getSimpleNodeLabel(GluedNodes.back(), DAG);
280  GluedNodes.pop_back();
281  if (!GluedNodes.empty())
282  O << "\n ";
283  }
284  } else {
285  O << "CROSS RC COPY";
286  }
287  return O.str();
288 }
289 
291  if (DAG) {
292  // Draw a special "GraphRoot" node to indicate the root of the graph.
293  GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
294  const SDNode *N = DAG->getRoot().getNode();
295  if (N && N->getNodeId() != -1)
296  GW.emitEdge(0, -1, &SUnits[N->getNodeId()], -1,
297  "color=blue,style=dashed");
298  }
299 }
int strcmp(const char *s1, const char *s2);
void emitSimpleNode(const void *ID, const std::string &Attr, const std::string &Label, unsigned NumEdgeSources=0, const std::vector< std::string > *EdgeSourceLabels=0)
emitSimpleNode - Outputs a simple (non-record) node
Definition: GraphWriter.h:261
static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I)
const std::string getGraphAttrs(const SDNode *N) const
raw_ostream & errs()
static std::string getSimpleNodeLabel(const SDNode *Node, const SelectionDAG *G)
static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter< SelectionDAG * > &GW)
SDNode * getGluedNode() const
virtual void getCustomGraphFeatures(GraphWriter< ScheduleDAG * > &GW) const
static bool hasNodeAddressLabel(const SDNode *Node, const SelectionDAG *Graph)
void setSubgraphColor(SDNode *N, const char *Color)
const SDValue & getOperand(unsigned Num) const
static std::string getGraphName(const SelectionDAG *G)
static std::string getEdgeDestLabel(const void *Node, unsigned i)
virtual std::string getGraphNodeLabel(const SUnit *SU) const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
static error_code advance(T &it, size_t Val)
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:280
static unsigned numEdgeDestLabels(const void *Node)
static std::string getEdgeSourceLabel(const void *Node, EdgeIter I)
#define G(x, y, z)
Definition: MD5.cpp:52
std::string getNodeLabel(const void *, const GraphType &)
static SDNodeIterator begin(const SDNode *N)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
SDNode * getNode() const
get the SDNode which holds the desired result
void setGraphColor(const SDNode *N, const char *Color)
SDNode * getNode() const
Definition: ScheduleDAG.h:368
static std::string getEdgeAttributes(const void *Node, EdgeIter EI, const SelectionDAG *Graph)
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
Definition: GraphWriter.h:346
const SDNode * getNode() const
static std::string itostr(int64_t X)
Definition: StringExtras.h:104
static std::string getNodeAttributes(const SDNode *N, const SelectionDAG *Graph)
std::string & str()
Definition: raw_ostream.h:441
const SDValue & getRoot() const
Definition: SelectionDAG.h:328
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:117
static EdgeIter getEdgeTarget(const void *Node, EdgeIter I)
void print_details(raw_ostream &OS, const SelectionDAG *G) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Definition: Debug.cpp:101
std::map< const SDNode *, std::string > NodeGraphAttrs
Definition: SelectionDAG.h:293
std::string getName(ID id, ArrayRef< Type * > Tys=None)
Definition: Function.cpp:400
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
int getNodeId() const
EVT getValueType() const
unsigned NodeNum
Definition: ScheduleDAG.h:271
unsigned size() const
Definition: DenseSet.h:34
void setGraphAttrs(const SDNode *N, const char *Attrs)
static SDNodeIterator end(const SDNode *N)
#define DEBUG(X)
Definition: Debug.h:97
StringRef getName() const
std::vector< SUnit > SUnits
Definition: ScheduleDAG.h:545
void emitEdge(const void *SrcNodeID, int SrcNodePort, const void *DestNodeID, int DestNodePort, const std::string &Attrs)
emitEdge - Output an edge from a simple node into the graph...
Definition: GraphWriter.h:284
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:249
std::string getOperationName(const SelectionDAG *G=0) const