1 //===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This implements the SelectionDAG::viewGraph method.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Constants.h"
15 #include "llvm/Function.h"
16 #include "llvm/Assembly/Writer.h"
17 #include "llvm/CodeGen/SelectionDAG.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/Target/MRegisterInfo.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Support/GraphWriter.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Config/config.h"
30 struct DOTGraphTraits
<SelectionDAG
*> : public DefaultDOTGraphTraits
{
31 static std::string
getGraphName(const SelectionDAG
*G
) {
32 return G
->getMachineFunction().getFunction()->getName();
35 static bool renderGraphFromBottomUp() {
39 static bool hasNodeAddressLabel(const SDNode
*Node
,
40 const SelectionDAG
*Graph
) {
44 static std::string
getNodeLabel(const SDNode
*Node
,
45 const SelectionDAG
*Graph
);
46 static std::string
getNodeAttributes(const SDNode
*N
) {
47 return "shape=Mrecord";
50 static void addCustomGraphFeatures(SelectionDAG
*G
,
51 GraphWriter
<SelectionDAG
*> &GW
) {
52 GW
.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
53 GW
.emitEdge(0, -1, G
->getRoot().Val
, -1, "");
58 std::string DOTGraphTraits
<SelectionDAG
*>::getNodeLabel(const SDNode
*Node
,
59 const SelectionDAG
*G
) {
60 std::string Op
= Node
->getOperationName(G
);
62 for (unsigned i
= 0, e
= Node
->getNumValues(); i
!= e
; ++i
)
63 if (Node
->getValueType(i
) == MVT::Other
)
66 Op
= Op
+ ":" + MVT::getValueTypeString(Node
->getValueType(i
));
68 if (const ConstantSDNode
*CSDN
= dyn_cast
<ConstantSDNode
>(Node
)) {
69 Op
+= ": " + utostr(CSDN
->getValue());
70 } else if (const ConstantFPSDNode
*CSDN
= dyn_cast
<ConstantFPSDNode
>(Node
)) {
71 Op
+= ": " + ftostr(CSDN
->getValue());
72 } else if (const GlobalAddressSDNode
*GADN
=
73 dyn_cast
<GlobalAddressSDNode
>(Node
)) {
74 int offset
= GADN
->getOffset();
75 Op
+= ": " + GADN
->getGlobal()->getName();
77 Op
+= "+" + itostr(offset
);
80 } else if (const FrameIndexSDNode
*FIDN
= dyn_cast
<FrameIndexSDNode
>(Node
)) {
81 Op
+= " " + itostr(FIDN
->getIndex());
82 } else if (const ConstantPoolSDNode
*CP
= dyn_cast
<ConstantPoolSDNode
>(Node
)){
83 if (ConstantFP
*CFP
= dyn_cast
<ConstantFP
>(CP
->get()))
84 Op
+= "<" + ftostr(CFP
->getValue()) + ">";
85 else if (ConstantInt
*CI
= dyn_cast
<ConstantInt
>(CP
->get()))
86 Op
+= "<" + utostr(CI
->getZExtValue()) + ">";
88 std::ostringstream SS
;
89 WriteAsOperand(SS
, CP
->get(), false);
90 Op
+= "<" + SS
.str() + ">";
92 } else if (const BasicBlockSDNode
*BBDN
= dyn_cast
<BasicBlockSDNode
>(Node
)) {
94 const Value
*LBB
= (const Value
*)BBDN
->getBasicBlock()->getBasicBlock();
97 //Op += " " + (const void*)BBDN->getBasicBlock();
98 } else if (const RegisterSDNode
*R
= dyn_cast
<RegisterSDNode
>(Node
)) {
99 if (G
&& R
->getReg() != 0 && MRegisterInfo::isPhysicalRegister(R
->getReg())) {
100 Op
= Op
+ " " + G
->getTarget().getRegisterInfo()->getName(R
->getReg());
102 Op
+= " #" + utostr(R
->getReg());
104 } else if (const ExternalSymbolSDNode
*ES
=
105 dyn_cast
<ExternalSymbolSDNode
>(Node
)) {
106 Op
+= "'" + std::string(ES
->getSymbol()) + "'";
107 } else if (const SrcValueSDNode
*M
= dyn_cast
<SrcValueSDNode
>(Node
)) {
109 Op
+= "<" + M
->getValue()->getName() + ":" + itostr(M
->getOffset()) + ">";
111 Op
+= "<null:" + itostr(M
->getOffset()) + ">";
112 } else if (const VTSDNode
*N
= dyn_cast
<VTSDNode
>(Node
)) {
113 Op
= Op
+ " VT=" + getValueTypeString(N
->getVT());
114 } else if (const StringSDNode
*N
= dyn_cast
<StringSDNode
>(Node
)) {
115 Op
= Op
+ "\"" + N
->getValue() + "\"";
122 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
123 /// rendered using 'dot'.
125 void SelectionDAG::viewGraph() {
126 // This code is only for debugging!
128 ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName());
130 std::cerr
<< "SelectionDAG::viewGraph is only available in debug builds on "
131 << "systems with Graphviz or gv!\n";