LLVM  3.7.0
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"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/DebugInfo.h"
23 #include "llvm/Support/Debug.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "dag-printer"
31 
32 namespace llvm {
33  template<>
35 
36  explicit DOTGraphTraits(bool isSimple=false) :
37  DefaultDOTGraphTraits(isSimple) {}
38 
39  static bool hasEdgeDestLabels() {
40  return true;
41  }
42 
43  static unsigned numEdgeDestLabels(const void *Node) {
44  return ((const SDNode *) Node)->getNumValues();
45  }
46 
47  static std::string getEdgeDestLabel(const void *Node, unsigned i) {
48  return ((const SDNode *) Node)->getValueType(i).getEVTString();
49  }
50 
51  template<typename EdgeIter>
52  static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
53  return itostr(I - SDNodeIterator::begin((const SDNode *) Node));
54  }
55 
56  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
57  /// should actually target another edge source, not a node. If this method
58  /// is implemented, getEdgeTarget should be implemented.
59  template<typename EdgeIter>
60  static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
61  return true;
62  }
63 
64  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
65  /// called to determine which outgoing edge of Node is the target of this
66  /// edge.
67  template<typename EdgeIter>
68  static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
69  SDNode *TargetNode = *I;
70  SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
71  std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
72  return NI;
73  }
74 
75  static std::string getGraphName(const SelectionDAG *G) {
76  return G->getMachineFunction().getName();
77  }
78 
79  static bool renderGraphFromBottomUp() {
80  return true;
81  }
82 
83  static bool hasNodeAddressLabel(const SDNode *Node,
84  const SelectionDAG *Graph) {
85  return true;
86  }
87 
88  /// If you want to override the dot attributes printed for a particular
89  /// edge, override this method.
90  template<typename EdgeIter>
91  static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
92  const SelectionDAG *Graph) {
93  SDValue Op = EI.getNode()->getOperand(EI.getOperand());
94  EVT VT = Op.getValueType();
95  if (VT == MVT::Glue)
96  return "color=red,style=bold";
97  else if (VT == MVT::Other)
98  return "color=blue,style=dashed";
99  return "";
100  }
101 
102 
103  static std::string getSimpleNodeLabel(const SDNode *Node,
104  const SelectionDAG *G) {
105  std::string Result = Node->getOperationName(G);
106  {
107  raw_string_ostream OS(Result);
108  Node->print_details(OS, G);
109  }
110  return Result;
111  }
112  std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
113  static std::string getNodeAttributes(const SDNode *N,
114  const SelectionDAG *Graph) {
115 #ifndef NDEBUG
116  const std::string &Attrs = Graph->getGraphAttrs(N);
117  if (!Attrs.empty()) {
118  if (Attrs.find("shape=") == std::string::npos)
119  return std::string("shape=Mrecord,") + Attrs;
120  else
121  return Attrs;
122  }
123 #endif
124  return "shape=Mrecord";
125  }
126 
129  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
130  if (G->getRoot().getNode())
131  GW.emitEdge(nullptr, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
132  "color=blue,style=dashed");
133  }
134  };
135 }
136 
138  const SelectionDAG *G) {
140 }
141 
142 
143 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
144 /// rendered using 'dot'.
145 ///
146 void SelectionDAG::viewGraph(const std::string &Title) {
147 // This code is only for debugging!
148 #ifndef NDEBUG
149  ViewGraph(this, "dag." + getMachineFunction().getName(),
150  false, Title);
151 #else
152  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
153  << "systems with Graphviz or gv!\n";
154 #endif // NDEBUG
155 }
156 
157 // This overload is defined out-of-line here instead of just using a
158 // default parameter because this is easiest for gdb to call.
160  viewGraph("");
161 }
162 
163 /// clearGraphAttrs - Clear all previously defined node graph attributes.
164 /// Intended to be used from a debugging tool (eg. gdb).
166 #ifndef NDEBUG
167  NodeGraphAttrs.clear();
168 #else
169  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
170  << " on systems with Graphviz or gv!\n";
171 #endif
172 }
173 
174 
175 /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
176 ///
177 void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
178 #ifndef NDEBUG
179  NodeGraphAttrs[N] = Attrs;
180 #else
181  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
182  << " on systems with Graphviz or gv!\n";
183 #endif
184 }
185 
186 
187 /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
188 /// Used from getNodeAttributes.
189 const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
190 #ifndef NDEBUG
191  std::map<const SDNode *, std::string>::const_iterator I =
192  NodeGraphAttrs.find(N);
193 
194  if (I != NodeGraphAttrs.end())
195  return I->second;
196  else
197  return "";
198 #else
199  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
200  << " on systems with Graphviz or gv!\n";
201  return std::string();
202 #endif
203 }
204 
205 /// setGraphColor - Convenience for setting node color attribute.
206 ///
207 void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
208 #ifndef NDEBUG
209  NodeGraphAttrs[N] = std::string("color=") + Color;
210 #else
211  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
212  << " on systems with Graphviz or gv!\n";
213 #endif
214 }
215 
216 /// setSubgraphColorHelper - Implement setSubgraphColor. Return
217 /// whether we truncated the search.
218 ///
219 bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
220  int level, bool &printed) {
221  bool hit_limit = false;
222 
223 #ifndef NDEBUG
224  if (level >= 20) {
225  if (!printed) {
226  printed = true;
227  DEBUG(dbgs() << "setSubgraphColor hit max level\n");
228  }
229  return true;
230  }
231 
232  unsigned oldSize = visited.size();
233  visited.insert(N);
234  if (visited.size() != oldSize) {
235  setGraphColor(N, Color);
237  i != iend;
238  ++i) {
239  hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
240  }
241  }
242 #else
243  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
244  << " on systems with Graphviz or gv!\n";
245 #endif
246  return hit_limit;
247 }
248 
249 /// setSubgraphColor - Convenience for setting subgraph color attribute.
250 ///
251 void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
252 #ifndef NDEBUG
253  DenseSet<SDNode *> visited;
254  bool printed = false;
255  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
256  // Visually mark that we hit the limit
257  if (strcmp(Color, "red") == 0) {
258  setSubgraphColorHelper(N, "blue", visited, 0, printed);
259  } else if (strcmp(Color, "yellow") == 0) {
260  setSubgraphColorHelper(N, "green", visited, 0, printed);
261  }
262  }
263 
264 #else
265  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
266  << " on systems with Graphviz or gv!\n";
267 #endif
268 }
269 
270 std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
271  std::string s;
272  raw_string_ostream O(s);
273  O << "SU(" << SU->NodeNum << "): ";
274  if (SU->getNode()) {
275  SmallVector<SDNode *, 4> GluedNodes;
276  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
277  GluedNodes.push_back(N);
278  while (!GluedNodes.empty()) {
279  O << DOTGraphTraits<SelectionDAG*>
280  ::getSimpleNodeLabel(GluedNodes.back(), DAG);
281  GluedNodes.pop_back();
282  if (!GluedNodes.empty())
283  O << "\n ";
284  }
285  } else {
286  O << "CROSS RC COPY";
287  }
288  return O.str();
289 }
290 
292  if (DAG) {
293  // Draw a special "GraphRoot" node to indicate the root of the graph.
294  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
295  const SDNode *N = DAG->getRoot().getNode();
296  if (N && N->getNodeId() != -1)
297  GW.emitEdge(nullptr, -1, &SUnits[N->getNodeId()], -1,
298  "color=blue,style=dashed");
299  }
300 }
static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
const std::string getGraphAttrs(const SDNode *N) const
Get graph attributes for a node.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static std::string getSimpleNodeLabel(const SDNode *Node, const SelectionDAG *G)
static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter< SelectionDAG * > &GW)
size_type size() const
Definition: DenseSet.h:53
DenseSet - This implements a dense probed hash-table based set.
Definition: DenseSet.h:39
void emitSimpleNode(const void *ID, const std::string &Attr, const std::string &Label, unsigned NumEdgeSources=0, const std::vector< std::string > *EdgeSourceLabels=nullptr)
emitSimpleNode - Outputs a simple (non-record) node
Definition: GraphWriter.h:260
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
virtual void getCustomGraphFeatures(GraphWriter< ScheduleDAG * > &GW) const
static bool hasNodeAddressLabel(const SDNode *Node, const SelectionDAG *Graph)
void setSubgraphColor(SDNode *N, const char *Color)
Convenience for setting subgraph color attribute.
const SDValue & getOperand(unsigned Num) const
static std::string getGraphName(const SelectionDAG *G)
static std::string getEdgeDestLabel(const void *Node, unsigned i)
unsigned getResNo() const
get the index which selects a specific result in the SDNode
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:283
static void advance(T &it, size_t Val)
static unsigned numEdgeDestLabels(const void *Node)
static StringRef getName(Value *V)
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 &)
getNodeLabel - Given a node and a pointer to the top level graph, return the label to print in the no...
static SDNodeIterator begin(const SDNode *N)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
std::string getOperationName(const SelectionDAG *G=nullptr) const
Return the opcode of this operation for printing.
SDNode * getNode() const
get the SDNode which holds the desired result
void setGraphColor(const SDNode *N, const char *Color)
Convenience for setting node color attribute.
SDNode * getNode() const
getNode - Return the representative SDNode for this SUnit.
Definition: ScheduleDAG.h:388
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void clearGraphAttrs()
Clear all previously defined node graph attributes.
static std::string getEdgeAttributes(const void *Node, EdgeIter EI, const SelectionDAG *Graph)
If you want to override the dot attributes printed for a particular edge, override this method...
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:348
const SDNode * getNode() const
EVT - Extended Value Type.
Definition: ValueTypes.h:31
static std::string itostr(int64_t X)
Definition: StringExtras.h:109
static std::string getNodeAttributes(const SDNode *N, const SelectionDAG *Graph)
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:480
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
Definition: SelectionDAG.h:335
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:147
Color
A "color", which is either even or odd.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:179
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
static EdgeIter getEdgeTarget(const void *Node, EdgeIter I)
getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is called to determine which outgo...
Represents one node in the SelectionDAG.
void print_details(raw_ostream &OS, const SelectionDAG *G) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
std::string getGraphNodeLabel(const SUnit *SU) const override
getGraphNodeLabel - Return a label for an SUnit node in a visualization of the ScheduleDAG.
std::map< const SDNode *, std::string > NodeGraphAttrs
Definition: SelectionDAG.h:296
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
int getNodeId() const
Return the unique node id.
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned NodeNum
Definition: ScheduleDAG.h:283
void setGraphAttrs(const SDNode *N, const char *Attrs)
Set graph attributes for a node. (eg. "color=red".)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:465
static SDNodeIterator end(const SDNode *N)
#define DEBUG(X)
Definition: Debug.h:92
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
std::vector< SUnit > SUnits
Definition: ScheduleDAG.h:565
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
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:283
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:261