LLVM  7.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"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/Support/Debug.h"
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "dag-printer"
29 
30 namespace llvm {
31  template<>
33 
34  explicit DOTGraphTraits(bool isSimple=false) :
36 
37  static bool hasEdgeDestLabels() {
38  return true;
39  }
40 
41  static unsigned numEdgeDestLabels(const void *Node) {
42  return ((const SDNode *) Node)->getNumValues();
43  }
44 
45  static std::string getEdgeDestLabel(const void *Node, unsigned i) {
46  return ((const SDNode *) Node)->getValueType(i).getEVTString();
47  }
48 
49  template<typename EdgeIter>
50  static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
51  return itostr(I - SDNodeIterator::begin((const SDNode *) Node));
52  }
53 
54  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
55  /// should actually target another edge source, not a node. If this method
56  /// is implemented, getEdgeTarget should be implemented.
57  template<typename EdgeIter>
58  static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
59  return true;
60  }
61 
62  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
63  /// called to determine which outgoing edge of Node is the target of this
64  /// edge.
65  template<typename EdgeIter>
66  static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
67  SDNode *TargetNode = *I;
68  SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
69  std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
70  return NI;
71  }
72 
73  static std::string getGraphName(const SelectionDAG *G) {
74  return G->getMachineFunction().getName();
75  }
76 
77  static bool renderGraphFromBottomUp() {
78  return true;
79  }
80 
81  static std::string getNodeIdentifierLabel(const SDNode *Node,
82  const SelectionDAG *Graph) {
83  std::string R;
84  raw_string_ostream OS(R);
85 #ifndef NDEBUG
86  OS << 't' << Node->PersistentId;
87 #else
88  OS << static_cast<const void *>(Node);
89 #endif
90  return R;
91  }
92 
93  /// If you want to override the dot attributes printed for a particular
94  /// edge, override this method.
95  template<typename EdgeIter>
96  static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
97  const SelectionDAG *Graph) {
98  SDValue Op = EI.getNode()->getOperand(EI.getOperand());
99  EVT VT = Op.getValueType();
100  if (VT == MVT::Glue)
101  return "color=red,style=bold";
102  else if (VT == MVT::Other)
103  return "color=blue,style=dashed";
104  return "";
105  }
106 
107 
108  static std::string getSimpleNodeLabel(const SDNode *Node,
109  const SelectionDAG *G) {
110  std::string Result = Node->getOperationName(G);
111  {
112  raw_string_ostream OS(Result);
113  Node->print_details(OS, G);
114  }
115  return Result;
116  }
117  std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
118  static std::string getNodeAttributes(const SDNode *N,
119  const SelectionDAG *Graph) {
120 #ifndef NDEBUG
121  const std::string &Attrs = Graph->getGraphAttrs(N);
122  if (!Attrs.empty()) {
123  if (Attrs.find("shape=") == std::string::npos)
124  return std::string("shape=Mrecord,") + Attrs;
125  else
126  return Attrs;
127  }
128 #endif
129  return "shape=Mrecord";
130  }
131 
134  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
135  if (G->getRoot().getNode())
136  GW.emitEdge(nullptr, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
137  "color=blue,style=dashed");
138  }
139  };
140 }
141 
143  const SelectionDAG *G) {
145 }
146 
147 
148 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
149 /// rendered using 'dot'.
150 ///
151 void SelectionDAG::viewGraph(const std::string &Title) {
152 // This code is only for debugging!
153 #ifndef NDEBUG
154  ViewGraph(this, "dag." + getMachineFunction().getName(),
155  false, Title);
156 #else
157  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
158  << "systems with Graphviz or gv!\n";
159 #endif // NDEBUG
160 }
161 
162 // This overload is defined out-of-line here instead of just using a
163 // default parameter because this is easiest for gdb to call.
165  viewGraph("");
166 }
167 
168 /// clearGraphAttrs - Clear all previously defined node graph attributes.
169 /// Intended to be used from a debugging tool (eg. gdb).
171 #ifndef NDEBUG
172  NodeGraphAttrs.clear();
173 #else
174  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
175  << " on systems with Graphviz or gv!\n";
176 #endif
177 }
178 
179 
180 /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
181 ///
182 void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
183 #ifndef NDEBUG
184  NodeGraphAttrs[N] = Attrs;
185 #else
186  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
187  << " on systems with Graphviz or gv!\n";
188 #endif
189 }
190 
191 
192 /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
193 /// Used from getNodeAttributes.
194 const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
195 #ifndef NDEBUG
196  std::map<const SDNode *, std::string>::const_iterator I =
197  NodeGraphAttrs.find(N);
198 
199  if (I != NodeGraphAttrs.end())
200  return I->second;
201  else
202  return "";
203 #else
204  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
205  << " on systems with Graphviz or gv!\n";
206  return std::string();
207 #endif
208 }
209 
210 /// setGraphColor - Convenience for setting node color attribute.
211 ///
212 void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
213 #ifndef NDEBUG
214  NodeGraphAttrs[N] = std::string("color=") + Color;
215 #else
216  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
217  << " on systems with Graphviz or gv!\n";
218 #endif
219 }
220 
221 /// setSubgraphColorHelper - Implement setSubgraphColor. Return
222 /// whether we truncated the search.
223 ///
224 bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
225  int level, bool &printed) {
226  bool hit_limit = false;
227 
228 #ifndef NDEBUG
229  if (level >= 20) {
230  if (!printed) {
231  printed = true;
232  LLVM_DEBUG(dbgs() << "setSubgraphColor hit max level\n");
233  }
234  return true;
235  }
236 
237  unsigned oldSize = visited.size();
238  visited.insert(N);
239  if (visited.size() != oldSize) {
240  setGraphColor(N, Color);
242  i != iend;
243  ++i) {
244  hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
245  }
246  }
247 #else
248  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
249  << " on systems with Graphviz or gv!\n";
250 #endif
251  return hit_limit;
252 }
253 
254 /// setSubgraphColor - Convenience for setting subgraph color attribute.
255 ///
256 void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
257 #ifndef NDEBUG
258  DenseSet<SDNode *> visited;
259  bool printed = false;
260  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
261  // Visually mark that we hit the limit
262  if (strcmp(Color, "red") == 0) {
263  setSubgraphColorHelper(N, "blue", visited, 0, printed);
264  } else if (strcmp(Color, "yellow") == 0) {
265  setSubgraphColorHelper(N, "green", visited, 0, printed);
266  }
267  }
268 
269 #else
270  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
271  << " on systems with Graphviz or gv!\n";
272 #endif
273 }
274 
275 std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
276  std::string s;
278  O << "SU(" << SU->NodeNum << "): ";
279  if (SU->getNode()) {
280  SmallVector<SDNode *, 4> GluedNodes;
281  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
282  GluedNodes.push_back(N);
283  while (!GluedNodes.empty()) {
284  O << DOTGraphTraits<SelectionDAG*>
285  ::getSimpleNodeLabel(GluedNodes.back(), DAG);
286  GluedNodes.pop_back();
287  if (!GluedNodes.empty())
288  O << "\n ";
289  }
290  } else {
291  O << "CROSS RC COPY";
292  }
293  return O.str();
294 }
295 
297  if (DAG) {
298  // Draw a special "GraphRoot" node to indicate the root of the graph.
299  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
300  const SDNode *N = DAG->getRoot().getNode();
301  if (N && N->getNodeId() != -1)
302  GW.emitEdge(nullptr, -1, &SUnits[N->getNodeId()], -1,
303  "color=blue,style=dashed");
304  }
305 }
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:395
static SDNodeIterator begin(const SDNode *N)
std::string itostr(int64_t X)
Definition: StringExtras.h:229
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:493
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:222
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
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:133
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:62
static std::string getNodeLabel(const ValueInfo &VI, GlobalValueSummary *GVS)
#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:454
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:477
unsigned getResNo() const
get the index which selects a specific result in the SDNode
static SDNodeIterator end(const SDNode *N)
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
#define LLVM_DEBUG(X)
Definition: Debug.h:119
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