Jlm
DotWriter.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <jlm/llvm/DotWriter.hpp>
9 #include <jlm/llvm/ir/types.hpp>
11 #include <jlm/rvsdg/control.hpp>
12 #include <jlm/rvsdg/region.hpp>
13 #include <jlm/rvsdg/UnitType.hpp>
14 
15 namespace jlm::llvm
16 {
17 
18 LlvmDotWriter::~LlvmDotWriter() noexcept = default;
19 
20 void
21 LlvmDotWriter::AnnotateTypeGraphNode(const rvsdg::Type & type, util::graph::Node & node)
22 {
23  auto & typeGraph = node.GetGraph();
24 
25  // Some types get special handling, such as adding incoming edges from aggregate types
26  if (type.Kind() == rvsdg::TypeKind::State || rvsdg::is<rvsdg::BitType>(type)
27  || rvsdg::is<PointerType>(type) || rvsdg::is<FloatingPointType>(type)
28  || rvsdg::is<VariableArgumentType>(type) || rvsdg::is<rvsdg::UnitType>(type)
29  || rvsdg::is<rvsdg::ControlType>(type))
30  {
31  // No need to provide any information beyond the debug string
32  }
33  else if (auto arrayType = dynamic_cast<const ArrayType *>(&type))
34  {
35  auto & elementTypeNode = GetOrCreateTypeGraphNode(arrayType->element_type(), typeGraph);
36  typeGraph.CreateDirectedEdge(elementTypeNode, node);
37  }
38  else if (auto structType = dynamic_cast<const StructType *>(&type))
39  {
40  for (size_t n = 0; n < structType->numElements(); n++)
41  {
42  auto & elementTypeNode = GetOrCreateTypeGraphNode(*structType->getElementType(n), typeGraph);
43  typeGraph.CreateDirectedEdge(elementTypeNode, node);
44  }
45  }
46  else if (const auto vectorType = dynamic_cast<const VectorType *>(&type))
47  {
48  auto & elementTypeNode = GetOrCreateTypeGraphNode(vectorType->type(), typeGraph);
49  typeGraph.CreateDirectedEdge(elementTypeNode, node);
50  }
51  else if (auto functionType = dynamic_cast<const rvsdg::FunctionType *>(&type))
52  {
53  for (size_t n = 0; n < functionType->NumArguments(); n++)
54  {
55  auto & argumentTypeNode = GetOrCreateTypeGraphNode(functionType->ArgumentType(n), typeGraph);
56  auto & edge = typeGraph.CreateDirectedEdge(argumentTypeNode, node);
57  edge.SetAttribute("Argument#", util::strfmt(n));
58  }
59  for (size_t n = 0; n < functionType->NumResults(); n++)
60  {
61  auto & resultTypeNode = GetOrCreateTypeGraphNode(functionType->ResultType(n), typeGraph);
62  auto & edge = typeGraph.CreateDirectedEdge(resultTypeNode, node);
63  edge.SetAttribute("Result#", util::strfmt(n));
64  }
65  }
66  else
67  {
68  JLM_UNREACHABLE("Unknown type");
69  }
70 }
71 
72 void
74 {
75  if (rvsdg::is<MemoryStateType>(rvsdgInput.Type()))
77  if (rvsdg::is<IOStateType>(rvsdgInput.Type()))
79 }
80 
89 void
91  const rvsdg::RegionArgument & rvsdgArgument,
92  util::graph::Node & node,
93  util::graph::Graph * typeGraph)
94 {
95  // If the argument is a GraphImport, include extra type and linkage data
96  if (const auto graphImport = dynamic_cast<const LlvmGraphImport *>(&rvsdgArgument))
97  {
98  node.SetAttribute("linkage", std::string(linkageToString(graphImport->linkage())));
99  if (typeGraph)
100  {
101  // The output of a GraphImport is always a PointerType
102  // Expose the underlying type as a separate attribute
103  auto & valueTypeNode = GetOrCreateTypeGraphNode(*graphImport->ValueType(), *typeGraph);
104  node.SetAttributeGraphElement("valueType", valueTypeNode);
105  }
106  }
107 }
108 
117 void
119  const rvsdg::Node & rvsdgNode,
120  util::graph::Node & node,
121  util::graph::Graph * typeGraph)
122 {
123  node.SetAttribute("NodeId", util::strfmt(rvsdgNode.GetNodeId()));
124 
125  if (const auto delta = dynamic_cast<const rvsdg::DeltaNode *>(&rvsdgNode))
126  {
127  if (auto op = dynamic_cast<const llvm::DeltaOperation *>(&delta->GetOperation()))
128  {
129  node.SetAttribute("linkage", std::string(linkageToString(op->linkage())));
130  node.SetAttribute("constant", op->constant() ? "true" : "false");
131  }
132 
133  if (typeGraph)
134  {
135  // The output of a delta node is always a PointerType
136  // Expose the underlying type as a separate attribute
137  auto & typeNode = GetOrCreateTypeGraphNode(*delta->GetOperation().Type(), *typeGraph);
138  node.SetAttributeGraphElement("type", typeNode);
139  }
140  }
141 }
142 
143 }
Delta operation.
Definition: delta.hpp:22
~LlvmDotWriter() noexcept override
void AnnotateRegionArgument(const rvsdg::RegionArgument &regionArgument, util::graph::Node &node, util::graph::Graph *typeGraph) override
Definition: DotWriter.cpp:90
void AnnotateEdge(const rvsdg::Input &rvsdgInput, util::graph::Edge &edge) override
Definition: DotWriter.cpp:73
void AnnotateGraphNode(const rvsdg::Node &rvsdgNode, util::graph::Node &node, util::graph::Graph *typeGraph) override
Definition: DotWriter.cpp:118
StructType class.
Definition: types.hpp:184
Delta node.
Definition: delta.hpp:129
util::graph::Node & GetOrCreateTypeGraphNode(const Type &type, util::graph::Graph &typeGraph)
Definition: DotWriter.cpp:43
Function type class.
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:67
Id GetNodeId() const noexcept
Definition: node.hpp:600
Represents the argument of a region.
Definition: region.hpp:41
void SetAttribute(const std::string &attribute, std::string value)
void SetAttributeGraphElement(const std::string &attribute, const GraphElement &element)
#define JLM_UNREACHABLE(msg)
Definition: common.hpp:43
Global memory state passed between functions.
std::string_view linkageToString(const Linkage linkage)
Definition: Linkage.cpp:17
static std::string type(const Node *n)
Definition: view.cpp:255
@ State
Designate a state type.
const char *const Red
const char *const Green
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35