LLVM  4.0.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) :
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;
279  raw_string_ostream O(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 }
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_t i
Implements a dense probed hash-table based set.
Definition: DenseSet.h:202
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:251
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
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)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
uint16_t PersistentId
Unique and persistent id per SDNode in the DAG.
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:327
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)
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
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)
static SDNodeIterator begin(const SDNode *N)
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:371
static std::string getNodeIdentifierLabel(const SDNode *Node, const SelectionDAG *Graph)
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:339
const SDNode * getNode() const
EVT - Extended Value Type.
Definition: ValueTypes.h:31
static std::string itostr(int64_t X)
Definition: StringExtras.h:95
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:479
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
Definition: SelectionDAG.h:378
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to '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:166
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
const DataFlowGraph & G
Definition: RDFGraph.cpp:206
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:132
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:340
#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:266
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:463
static SDNodeIterator end(const SDNode *N)
#define DEBUG(X)
Definition: Debug.h:100
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:583
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:274
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:244