LLVM  6.0.0svn
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 
14 #include "ScheduleDAGSDNodes.h"
15 #include "llvm/ADT/DenseSet.h"
16 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/DebugInfo.h"
24 #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) :
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 std::string getNodeIdentifierLabel(const SDNode *Node,
84  const SelectionDAG *Graph) {
85  std::string R;
86  raw_string_ostream OS(R);
87 #ifndef NDEBUG
88  OS << 't' << Node->PersistentId;
89 #else
90  OS << static_cast<const void *>(Node);
91 #endif
92  return R;
93  }
94 
95  /// If you want to override the dot attributes printed for a particular
96  /// edge, override this method.
97  template<typename EdgeIter>
98  static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
99  const SelectionDAG *Graph) {
100  SDValue Op = EI.getNode()->getOperand(EI.getOperand());
101  EVT VT = Op.getValueType();
102  if (VT == MVT::Glue)
103  return "color=red,style=bold";
104  else if (VT == MVT::Other)
105  return "color=blue,style=dashed";
106  return "";
107  }
108 
109 
110  static std::string getSimpleNodeLabel(const SDNode *Node,
111  const SelectionDAG *G) {
112  std::string Result = Node->getOperationName(G);
113  {
114  raw_string_ostream OS(Result);
115  Node->print_details(OS, G);
116  }
117  return Result;
118  }
119  std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
120  static std::string getNodeAttributes(const SDNode *N,
121  const SelectionDAG *Graph) {
122 #ifndef NDEBUG
123  const std::string &Attrs = Graph->getGraphAttrs(N);
124  if (!Attrs.empty()) {
125  if (Attrs.find("shape=") == std::string::npos)
126  return std::string("shape=Mrecord,") + Attrs;
127  else
128  return Attrs;
129  }
130 #endif
131  return "shape=Mrecord";
132  }
133 
136  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
137  if (G->getRoot().getNode())
138  GW.emitEdge(nullptr, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
139  "color=blue,style=dashed");
140  }
141  };
142 }
143 
145  const SelectionDAG *G) {
147 }
148 
149 
150 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
151 /// rendered using 'dot'.
152 ///
153 void SelectionDAG::viewGraph(const std::string &Title) {
154 // This code is only for debugging!
155 #ifndef NDEBUG
156  ViewGraph(this, "dag." + getMachineFunction().getName(),
157  false, Title);
158 #else
159  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
160  << "systems with Graphviz or gv!\n";
161 #endif // NDEBUG
162 }
163 
164 // This overload is defined out-of-line here instead of just using a
165 // default parameter because this is easiest for gdb to call.
167  viewGraph("");
168 }
169 
170 /// clearGraphAttrs - Clear all previously defined node graph attributes.
171 /// Intended to be used from a debugging tool (eg. gdb).
173 #ifndef NDEBUG
174  NodeGraphAttrs.clear();
175 #else
176  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
177  << " on systems with Graphviz or gv!\n";
178 #endif
179 }
180 
181 
182 /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
183 ///
184 void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
185 #ifndef NDEBUG
186  NodeGraphAttrs[N] = Attrs;
187 #else
188  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
189  << " on systems with Graphviz or gv!\n";
190 #endif
191 }
192 
193 
194 /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
195 /// Used from getNodeAttributes.
196 const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
197 #ifndef NDEBUG
198  std::map<const SDNode *, std::string>::const_iterator I =
199  NodeGraphAttrs.find(N);
200 
201  if (I != NodeGraphAttrs.end())
202  return I->second;
203  else
204  return "";
205 #else
206  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
207  << " on systems with Graphviz or gv!\n";
208  return std::string();
209 #endif
210 }
211 
212 /// setGraphColor - Convenience for setting node color attribute.
213 ///
214 void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
215 #ifndef NDEBUG
216  NodeGraphAttrs[N] = std::string("color=") + Color;
217 #else
218  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
219  << " on systems with Graphviz or gv!\n";
220 #endif
221 }
222 
223 /// setSubgraphColorHelper - Implement setSubgraphColor. Return
224 /// whether we truncated the search.
225 ///
226 bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
227  int level, bool &printed) {
228  bool hit_limit = false;
229 
230 #ifndef NDEBUG
231  if (level >= 20) {
232  if (!printed) {
233  printed = true;
234  DEBUG(dbgs() << "setSubgraphColor hit max level\n");
235  }
236  return true;
237  }
238 
239  unsigned oldSize = visited.size();
240  visited.insert(N);
241  if (visited.size() != oldSize) {
242  setGraphColor(N, Color);
244  i != iend;
245  ++i) {
246  hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
247  }
248  }
249 #else
250  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
251  << " on systems with Graphviz or gv!\n";
252 #endif
253  return hit_limit;
254 }
255 
256 /// setSubgraphColor - Convenience for setting subgraph color attribute.
257 ///
258 void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
259 #ifndef NDEBUG
260  DenseSet<SDNode *> visited;
261  bool printed = false;
262  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
263  // Visually mark that we hit the limit
264  if (strcmp(Color, "red") == 0) {
265  setSubgraphColorHelper(N, "blue", visited, 0, printed);
266  } else if (strcmp(Color, "yellow") == 0) {
267  setSubgraphColorHelper(N, "green", visited, 0, printed);
268  }
269  }
270 
271 #else
272  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
273  << " on systems with Graphviz or gv!\n";
274 #endif
275 }
276 
277 std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
278  std::string s;
280  O << "SU(" << SU->NodeNum << "): ";
281  if (SU->getNode()) {
282  SmallVector<SDNode *, 4> GluedNodes;
283  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
284  GluedNodes.push_back(N);
285  while (!GluedNodes.empty()) {
286  O << DOTGraphTraits<SelectionDAG*>
287  ::getSimpleNodeLabel(GluedNodes.back(), DAG);
288  GluedNodes.pop_back();
289  if (!GluedNodes.empty())
290  O << "\n ";
291  }
292  } else {
293  O << "CROSS RC COPY";
294  }
295  return O.str();
296 }
297 
299  if (DAG) {
300  // Draw a special "GraphRoot" node to indicate the root of the graph.
301  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
302  const SDNode *N = DAG->getRoot().getNode();
303  if (N && N->getNodeId() != -1)
304  GW.emitEdge(nullptr, -1, &SUnits[N->getNodeId()], -1,
305  "color=blue,style=dashed");
306  }
307 }
EVT getValueType() const
Return the ValueType of the referenced return value.
static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
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
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static std::string getSimpleNodeLabel(const SDNode *Node, const SelectionDAG *G)
std::string getOperationName(const SelectionDAG *G=nullptr) const
Return the opcode of this operation for printing.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
Definition: ScheduleDAG.h:360
Implements a dense probed hash-table based set.
Definition: DenseSet.h:221
const std::string getGraphAttrs(const SDNode *N) const
Get graph attributes for a node.
const SDNode * getNode() const
void print_details(raw_ostream &OS, const SelectionDAG *G) const
virtual void getCustomGraphFeatures(GraphWriter< ScheduleDAG *> &GW) const
void setSubgraphColor(SDNode *N, const char *Color)
Convenience for setting subgraph color attribute.
static std::string getGraphName(const SelectionDAG *G)
SDNode * getNode() const
get the SDNode which holds the desired result
static std::string getEdgeDestLabel(const void *Node, unsigned i)
uint16_t PersistentId
Unique and persistent id per SDNode in the DAG.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static unsigned numEdgeDestLabels(const void *Node)
static StringRef getName(Value *V)
static std::string getEdgeSourceLabel(const void *Node, EdgeIter I)
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 bool isSimple(Instruction *I)
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:385
static SDNodeIterator begin(const SDNode *N)
std::string itostr(int64_t X)
Definition: StringExtras.h:189
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void setGraphColor(const SDNode *N, const char *Color)
Convenience for setting node color attribute.
static std::string getNodeIdentifierLabel(const SDNode *Node, const SelectionDAG *Graph)
const SDValue & getOperand(unsigned Num) const
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...
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
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 &#39;dot&#39;, run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:348
Extended Value Type.
Definition: ValueTypes.h:34
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&#39;s reference.
Definition: raw_ostream.h:478
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to &#39;dot...
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:209
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
const DataFlowGraph & G
Definition: RDFGraph.cpp:211
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter< SelectionDAG *> &GW)
std::string getGraphNodeLabel(const SUnit *SU) const override
Returns a label for an SUnit node in a visualization of the ScheduleDAG.
int getNodeId() const
Return the unique node id.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
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
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
Definition: SelectionDAG.h:443
unsigned NodeNum
Entry # of node in the node vector.
Definition: ScheduleDAG.h:269
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:462
unsigned getResNo() const
get the index which selects a specific result in the SDNode
static SDNodeIterator end(const SDNode *N)
#define DEBUG(X)
Definition: Debug.h:118
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:247