LLVM  15.0.0git
SelectionDAGPrinter.cpp
Go to the documentation of this file.
1 //===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This implements the SelectionDAG::viewGraph method.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ScheduleDAGSDNodes.h"
14 #include "llvm/ADT/DenseSet.h"
15 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Debug.h"
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "dag-printer"
24 
25 namespace llvm {
26  template<>
28 
29  explicit DOTGraphTraits(bool isSimple=false) :
31 
32  static bool hasEdgeDestLabels() {
33  return true;
34  }
35 
36  static unsigned numEdgeDestLabels(const void *Node) {
37  return ((const SDNode *) Node)->getNumValues();
38  }
39 
40  static std::string getEdgeDestLabel(const void *Node, unsigned i) {
41  return ((const SDNode *) Node)->getValueType(i).getEVTString();
42  }
43 
44  template<typename EdgeIter>
45  static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
46  return itostr(I - SDNodeIterator::begin((const SDNode *) Node));
47  }
48 
49  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
50  /// should actually target another edge source, not a node. If this method
51  /// is implemented, getEdgeTarget should be implemented.
52  template<typename EdgeIter>
53  static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
54  return true;
55  }
56 
57  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
58  /// called to determine which outgoing edge of Node is the target of this
59  /// edge.
60  template<typename EdgeIter>
61  static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
62  SDNode *TargetNode = *I;
63  SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
64  std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
65  return NI;
66  }
67 
68  static std::string getGraphName(const SelectionDAG *G) {
69  return std::string(G->getMachineFunction().getName());
70  }
71 
72  static bool renderGraphFromBottomUp() {
73  return true;
74  }
75 
76  static std::string getNodeIdentifierLabel(const SDNode *Node,
77  const SelectionDAG *Graph) {
78  std::string R;
80 #ifndef NDEBUG
81  OS << 't' << Node->PersistentId;
82 #else
83  OS << static_cast<const void *>(Node);
84 #endif
85  return R;
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 /// Just dump dot graph to a user-provided path and title.
164 /// This doesn't open the dot viewer program and
165 /// helps visualization when outside debugging session.
166 /// FileName expects absolute path. If provided
167 /// without any path separators then the file
168 /// will be created in the current directory.
169 /// Error will be emitted if the path is insane.
170 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
172  const Twine &Title) {
173  dumpDotGraphToFile(this, FileName, Title);
174 }
175 #endif
176 
177 /// clearGraphAttrs - Clear all previously defined node graph attributes.
178 /// Intended to be used from a debugging tool (eg. gdb).
180 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
181  NodeGraphAttrs.clear();
182 #else
183  errs() << "SelectionDAG::clearGraphAttrs is only available in builds with "
184  << "ABI breaking checks enabled on systems with Graphviz or gv!\n";
185 #endif
186 }
187 
188 
189 /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
190 ///
191 void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
192 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
193  NodeGraphAttrs[N] = Attrs;
194 #else
195  errs() << "SelectionDAG::setGraphAttrs is only available in builds with "
196  << "ABI breaking checks enabled on systems with Graphviz or gv!\n";
197 #endif
198 }
199 
200 
201 /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
202 /// Used from getNodeAttributes.
203 std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
204 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
205  std::map<const SDNode *, std::string>::const_iterator I =
206  NodeGraphAttrs.find(N);
207 
208  if (I != NodeGraphAttrs.end())
209  return I->second;
210  else
211  return "";
212 #else
213  errs() << "SelectionDAG::getGraphAttrs is only available in builds with "
214  << "ABI breaking checks enabled on systems with Graphviz or gv!\n";
215  return std::string();
216 #endif
217 }
218 
219 /// setGraphColor - Convenience for setting node color attribute.
220 ///
221 void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
222 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
223  NodeGraphAttrs[N] = std::string("color=") + Color;
224 #else
225  errs() << "SelectionDAG::setGraphColor is only available in builds with "
226  << "ABI breaking checks enabled on systems with Graphviz or gv!\n";
227 #endif
228 }
229 
230 /// setSubgraphColorHelper - Implement setSubgraphColor. Return
231 /// whether we truncated the search.
232 ///
233 bool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
234  int level, bool &printed) {
235  bool hit_limit = false;
236 
237 #ifndef NDEBUG
238  if (level >= 20) {
239  if (!printed) {
240  printed = true;
241  LLVM_DEBUG(dbgs() << "setSubgraphColor hit max level\n");
242  }
243  return true;
244  }
245 
246  unsigned oldSize = visited.size();
247  visited.insert(N);
248  if (visited.size() != oldSize) {
249  setGraphColor(N, Color);
251  i != iend;
252  ++i) {
253  hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
254  }
255  }
256 #else
257  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
258  << " on systems with Graphviz or gv!\n";
259 #endif
260  return hit_limit;
261 }
262 
263 /// setSubgraphColor - Convenience for setting subgraph color attribute.
264 ///
265 void SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
266 #ifndef NDEBUG
267  DenseSet<SDNode *> visited;
268  bool printed = false;
269  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
270  // Visually mark that we hit the limit
271  if (strcmp(Color, "red") == 0) {
272  setSubgraphColorHelper(N, "blue", visited, 0, printed);
273  } else if (strcmp(Color, "yellow") == 0) {
274  setSubgraphColorHelper(N, "green", visited, 0, printed);
275  }
276  }
277 
278 #else
279  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
280  << " on systems with Graphviz or gv!\n";
281 #endif
282 }
283 
284 std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
285  std::string s;
287  O << "SU(" << SU->NodeNum << "): ";
288  if (SU->getNode()) {
289  SmallVector<SDNode *, 4> GluedNodes;
290  for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
291  GluedNodes.push_back(N);
292  while (!GluedNodes.empty()) {
293  O << DOTGraphTraits<SelectionDAG*>
294  ::getSimpleNodeLabel(GluedNodes.back(), DAG);
295  GluedNodes.pop_back();
296  if (!GluedNodes.empty())
297  O << "\n ";
298  }
299  } else {
300  O << "CROSS RC COPY";
301  }
302  return O.str();
303 }
304 
306  if (DAG) {
307  // Draw a special "GraphRoot" node to indicate the root of the graph.
308  GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
309  const SDNode *N = DAG->getRoot().getNode();
310  if (N && N->getNodeId() != -1)
311  GW.emitEdge(nullptr, -1, &SUnits[N->getNodeId()], -1,
312  "color=blue,style=dashed");
313  }
314 }
i
i
Definition: README.txt:29
llvm::DOTGraphTraits< SelectionDAG * >::getEdgeTarget
static EdgeIter getEdgeTarget(const void *Node, EdgeIter I)
getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is called to determine which outgo...
Definition: SelectionDAGPrinter.cpp:61
Attrs
Function Attrs
Definition: README_ALTIVEC.txt:215
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:494
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::DOTGraphTraits< SelectionDAG * >::renderGraphFromBottomUp
static bool renderGraphFromBottomUp()
Definition: SelectionDAGPrinter.cpp:72
llvm::GraphWriter
Definition: ScheduleDAG.h:34
llvm::DOTGraphTraits< SelectionDAG * >::getEdgeAttributes
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.
Definition: SelectionDAGPrinter.cpp:91
llvm::SelectionDAG::setSubgraphColor
void setSubgraphColor(SDNode *N, const char *Color)
Convenience for setting subgraph color attribute.
Definition: SelectionDAGPrinter.cpp:265
llvm::SelectionDAG::setGraphColor
void setGraphColor(const SDNode *N, const char *Color)
Convenience for setting node color attribute.
Definition: SelectionDAGPrinter.cpp:221
llvm::Function::empty
bool empty() const
Definition: Function.h:731
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition: SelectionDAGNodes.h:151
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:632
llvm::SelectionDAG::setGraphAttrs
void setGraphAttrs(const SDNode *N, const char *Attrs)
Set graph attributes for a node. (eg. "color=red".)
Definition: SelectionDAGPrinter.cpp:191
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::SelectionDAG::getRoot
const SDValue & getRoot() const
Return the root tag of the SelectionDAG.
Definition: SelectionDAG.h:525
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:454
llvm::ScheduleDAGSDNodes::getCustomGraphFeatures
virtual void getCustomGraphFeatures(GraphWriter< ScheduleDAG * > &GW) const
Definition: SelectionDAGPrinter.cpp:305
llvm::MVT::Glue
@ Glue
Definition: MachineValueType.h:262
llvm::DOTGraphTraits< SelectionDAG * >::getNodeIdentifierLabel
static std::string getNodeIdentifierLabel(const SDNode *Node, const SelectionDAG *Graph)
Definition: SelectionDAGPrinter.cpp:76
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::ViewGraph
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:427
llvm::ScheduleDAGSDNodes::DAG
SelectionDAG * DAG
Definition: ScheduleDAGSDNodes.h:49
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
SelectionDAG.h
llvm::DOTGraphTraits< SelectionDAG * >::edgeTargetsEdgeSource
static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
Definition: SelectionDAGPrinter.cpp:53
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:240
llvm::SDNodeIterator::begin
static SDNodeIterator begin(const SDNode *N)
Definition: SelectionDAGNodes.h:2972
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::SelectionDAG
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:220
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
llvm::SUnit::NodeNum
unsigned NodeNum
Entry # of node in the node vector.
Definition: ScheduleDAG.h:264
llvm::ScheduleDAGSDNodes::getGraphNodeLabel
std::string getGraphNodeLabel(const SUnit *SU) const override
Returns a label for an SUnit node in a visualization of the ScheduleDAG.
Definition: SelectionDAGPrinter.cpp:284
DenseSet.h
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::size
size_type size() const
Definition: DenseSet.h:81
llvm::DOTGraphTraits< SelectionDAG * >::getGraphName
static std::string getGraphName(const SelectionDAG *G)
Definition: SelectionDAGPrinter.cpp:68
llvm::DOTGraphTraits< SelectionDAG * >::getEdgeDestLabel
static std::string getEdgeDestLabel(const void *Node, unsigned i)
Definition: SelectionDAGPrinter.cpp:40
ScheduleDAGSDNodes.h
llvm::SelectionDAG::viewGraph
void viewGraph()
Definition: SelectionDAGPrinter.cpp:159
llvm::DOTGraphTraits
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
Definition: DOTGraphTraits.h:166
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
s
multiplies can be turned into SHL s
Definition: README.txt:370
llvm::dumpDotGraphToFile
LLVM_DUMP_METHOD void dumpDotGraphToFile(const GraphType &G, const Twine &FileName, const Twine &Title, bool ShortNames=false, const Twine &Name="")
DumpDotGraph - Just dump a dot graph to the user-provided file name.
Definition: GraphWriter.h:416
llvm::SelectionDAG::getGraphAttrs
std::string getGraphAttrs(const SDNode *N) const
Get graph attributes for a node.
Definition: SelectionDAGPrinter.cpp:203
llvm::DOTGraphTraits< SelectionDAG * >::getSimpleNodeLabel
static std::string getSimpleNodeLabel(const SDNode *Node, const SelectionDAG *G)
Definition: SelectionDAGPrinter.cpp:103
I
#define I(x, y, z)
Definition: MD5.cpp:58
StringExtras.h
llvm::DOTGraphTraits< SelectionDAG * >::addCustomGraphFeatures
static void addCustomGraphFeatures(SelectionDAG *G, GraphWriter< SelectionDAG * > &GW)
Definition: SelectionDAGPrinter.cpp:127
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
llvm::DOTGraphTraits< SelectionDAG * >::hasEdgeDestLabels
static bool hasEdgeDestLabels()
Definition: SelectionDAGPrinter.cpp:32
llvm::SelectionDAG::clearGraphAttrs
void clearGraphAttrs()
Clear all previously defined node graph attributes.
Definition: SelectionDAGPrinter.cpp:179
llvm::GraphWriter::emitSimpleNode
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:310
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::ScheduleDAG::SUnits
std::vector< SUnit > SUnits
The scheduling units.
Definition: ScheduleDAG.h:562
GraphWriter.h
llvm::SDNodeIterator
Definition: SelectionDAGNodes.h:2936
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:326
llvm::SUnit::getNode
SDNode * getNode() const
Returns the representative SDNode for this SUnit.
Definition: ScheduleDAG.h:355
llvm::SelectionDAG::dumpDotGraph
LLVM_DUMP_METHOD void dumpDotGraph(const Twine &FileName, const Twine &Title)
Just dump dot graph to a user-provided path and title.
Definition: SelectionDAGPrinter.cpp:171
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:137
isSimple
static bool isSimple(Instruction *I)
Definition: SLPVectorizer.cpp:664
llvm::DOTGraphTraits< SelectionDAG * >::DOTGraphTraits
DOTGraphTraits(bool isSimple=false)
Definition: SelectionDAGPrinter.cpp:29
N
#define N
llvm::DOTGraphTraits< SelectionDAG * >::numEdgeDestLabels
static unsigned numEdgeDestLabels(const void *Node)
Definition: SelectionDAGPrinter.cpp:36
llvm::DOTGraphTraits< SelectionDAG * >::getEdgeSourceLabel
static std::string getEdgeSourceLabel(const void *Node, EdgeIter I)
Definition: SelectionDAGPrinter.cpp:45
llvm::DefaultDOTGraphTraits::getNodeLabel
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...
Definition: DOTGraphTraits.h:76
llvm::DefaultDOTGraphTraits
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
Definition: DOTGraphTraits.h:28
llvm::DOTGraphTraits< SelectionDAG * >::getNodeAttributes
static std::string getNodeAttributes(const SDNode *N, const SelectionDAG *Graph)
Definition: SelectionDAGPrinter.cpp:113
getNodeLabel
static std::string getNodeLabel(const ValueInfo &VI, GlobalValueSummary *GVS)
Definition: ModuleSummaryIndex.cpp:482
llvm::SUnit
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
llvm::SelectionDAG::getMachineFunction
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:449
raw_ostream.h
MachineFunction.h
llvm::GraphWriter::emitEdge
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:333
Debug.h
llvm::SDNodeIterator::end
static SDNodeIterator end(const SDNode *N)
Definition: SelectionDAGNodes.h:2973