Jlm
Loading...
Searching...
No Matches
RvsdgTreePrinter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
13
14#include <algorithm>
15#include <fstream>
16
17namespace jlm::llvm
18{
19
21{
22public:
23 ~Statistics() override = default;
24
25 explicit Statistics(const util::FilePath & sourceFile)
26 : util::Statistics(util::Statistics::Id::RvsdgTreePrinter, sourceFile)
27 {}
28
29 void
30 Start() noexcept
31 {
32 AddTimer(Label::Timer).start();
33 }
34
35 void
36 Stop() noexcept
37 {
38 GetTimer(Label::Timer).stop();
39 }
40
41 static std::unique_ptr<Statistics>
42 Create(const util::FilePath & sourceFile)
43 {
44 return std::make_unique<Statistics>(sourceFile);
45 }
46};
47
48RvsdgTreePrinter::~RvsdgTreePrinter() noexcept = default;
49
50void
52 rvsdg::RvsdgModule & rvsdgModule,
53 util::StatisticsCollector & statisticsCollector)
54{
55 auto statistics = Statistics::Create(rvsdgModule.SourceFilePath().value());
56 statistics->Start();
57
58 auto annotationMap = ComputeAnnotationMap(rvsdgModule.Rvsdg());
59 const auto json = rvsdg::Region::toJson(rvsdgModule.Rvsdg().GetRootRegion(), annotationMap);
60
61 auto file = statisticsCollector.createOutputFile("rvsdgTree.txt", true);
62 file.open("w");
63 fprintf(file.fd(), "%s\n", json.c_str());
64 file.close();
65
66 statistics->Stop();
68}
69
72{
73 util::AnnotationMap annotationMap;
74 for (const auto annotation : Configuration_.RequiredAnnotations().Items())
75 {
76 switch (annotation)
77 {
79 {
80 AnnotateDebugIds(rvsdg, annotationMap);
81 break;
82 }
84 {
85 const auto matchNode = [](const rvsdg::Node &)
86 {
87 return true;
88 };
89 AnnotateNumNodes(rvsdg, matchNode, "NumRvsdgNodes", annotationMap);
90 break;
91 }
93 {
94 const auto matchAggregateAlloca = [](const rvsdg::Node & node)
95 {
96 const auto allocaOperation = dynamic_cast<const AllocaOperation *>(&node.GetOperation());
97 return allocaOperation && IsAggregateType(*allocaOperation->allocatedType());
98 };
99 AnnotateNumNodes(rvsdg, matchAggregateAlloca, "NumAggregateAllocaNodes", annotationMap);
100 break;
101 }
103 {
104 const auto matchAlloca = [](const rvsdg::Node & node)
105 {
106 return rvsdg::is<AllocaOperation>(&node);
107 };
108 AnnotateNumNodes(rvsdg, matchAlloca, "NumAllocaNodes", annotationMap);
109 break;
110 }
112 {
113 const auto matchLoad = [](const rvsdg::Node & node)
114 {
115 return rvsdg::is<LoadOperation>(&node);
116 };
117 AnnotateNumNodes(rvsdg, matchLoad, "NumLoadNodes", annotationMap);
118 break;
119 }
121 {
122 const auto matchStore = [](const rvsdg::Node & node)
123 {
124 return rvsdg::is<StoreOperation>(&node);
125 };
126 AnnotateNumNodes(rvsdg, matchStore, "NumStoreNodes", annotationMap);
127 break;
128 }
130 {
131 AnnotateNumMemoryStateInputsOutputs(rvsdg, annotationMap);
132 break;
133 }
134 default:
135 JLM_UNREACHABLE("Unhandled RVSDG tree annotation.");
136 }
137 }
138
139 return annotationMap;
140}
141
142void
144 const rvsdg::Graph & rvsdg,
145 const std::function<bool(const rvsdg::Node &)> & match,
146 const std::string_view & label,
147 util::AnnotationMap & annotationMap)
148{
149 std::function<size_t(const rvsdg::Region &)> annotateRegion = [&](const rvsdg::Region & region)
150 {
151 size_t numNodes = 0;
152 for (auto & node : region.Nodes())
153 {
154 if (auto structuralNode = dynamic_cast<const rvsdg::StructuralNode *>(&node))
155 {
156 size_t numSubregionNodes = 0;
157 for (size_t n = 0; n < structuralNode->nsubregions(); n++)
158 {
159 auto subregion = structuralNode->subregion(n);
160 numSubregionNodes += annotateRegion(*subregion);
161 }
162
163 annotationMap.AddAnnotation(
164 structuralNode,
165 { label, static_cast<uint64_t>(numSubregionNodes) });
166 }
167
168 if (match(node))
169 {
170 numNodes++;
171 }
172 }
173
174 annotationMap.AddAnnotation(&region, { label, static_cast<uint64_t>(numNodes) });
175
176 return numNodes;
177 };
178
179 annotateRegion(rvsdg.GetRootRegion());
180}
181
182void
184 const rvsdg::Graph & rvsdg,
185 util::AnnotationMap & annotationMap)
186{
187 std::string_view argumentLabel("NumMemoryStateTypeArguments");
188 std::string_view resultLabel("NumMemoryStateTypeResults");
189 std::string_view inputLabel("NumMemoryStateTypeInputs");
190 std::string_view outputLabel("NumMemoryStateTypeOutputs");
191
192 std::function<void(const rvsdg::Region &)> annotateRegion = [&](const rvsdg::Region & region)
193 {
194 auto argumentRange = region.Arguments();
195 auto numMemoryStateArguments =
196 std::count_if(argumentRange.begin(), argumentRange.end(), IsMemoryStateOutput);
197 annotationMap.AddAnnotation(
198 &region,
199 { argumentLabel, static_cast<uint64_t>(numMemoryStateArguments) });
200
201 auto resultRange = region.Results();
202 auto numMemoryStateResults =
203 std::count_if(resultRange.begin(), resultRange.end(), IsMemoryStateInput);
204 annotationMap.AddAnnotation(
205 &region,
206 { resultLabel, static_cast<uint64_t>(numMemoryStateResults) });
207
208 for (auto & node : region.Nodes())
209 {
210 if (auto structuralNode = dynamic_cast<const rvsdg::StructuralNode *>(&node))
211 {
212 size_t numMemoryStateInputs = 0;
213 for (size_t n = 0; n < structuralNode->ninputs(); n++)
214 {
215 auto input = structuralNode->input(n);
216 if (rvsdg::is<MemoryStateType>(input->Type()))
217 {
218 numMemoryStateInputs++;
219 }
220 }
221 annotationMap.AddAnnotation(
222 structuralNode,
223 { inputLabel, static_cast<uint64_t>(numMemoryStateInputs) });
224
225 size_t numMemoryStateOutputs = 0;
226 for (size_t n = 0; n < structuralNode->noutputs(); n++)
227 {
228 auto output = structuralNode->output(n);
229 if (rvsdg::is<MemoryStateType>(output->Type()))
230 {
231 numMemoryStateOutputs++;
232 }
233 }
234 annotationMap.AddAnnotation(
235 structuralNode,
236 { outputLabel, static_cast<uint64_t>(numMemoryStateOutputs) });
237
238 for (size_t n = 0; n < structuralNode->nsubregions(); n++)
239 {
240 auto subregion = structuralNode->subregion(n);
241 annotateRegion(*subregion);
242 }
243 }
244 }
245 };
246
247 annotateRegion(rvsdg.GetRootRegion());
248}
249
250void
252{
253 std::string_view nodeIdLabel("NodeId");
254 std::string_view regionIdLabel("RegionId");
255
256 std::function<void(const rvsdg::Region &)> annotateRegion = [&](const rvsdg::Region & region)
257 {
258 for (auto & node : region.Nodes())
259 {
260 if (const auto structuralNode = dynamic_cast<const rvsdg::StructuralNode *>(&node))
261 {
262 for (auto & subregion : structuralNode->Subregions())
263 annotateRegion(subregion);
264
265 annotationMap.AddAnnotation(
266 structuralNode,
267 { nodeIdLabel, static_cast<uint64_t>(structuralNode->GetNodeId()) });
268 }
269 }
270
271 annotationMap.AddAnnotation(
272 &region,
273 { regionIdLabel, static_cast<uint64_t>(region.getRegionId()) });
274 };
275
276 annotateRegion(rvsdg.GetRootRegion());
277}
278
279bool
281{
282 return rvsdg::is<MemoryStateType>(input->Type());
283}
284
285bool
287{
288 return rvsdg::is<MemoryStateType>(output->Type());
289}
290
291}
static jlm::util::StatisticsCollector statisticsCollector
const util::HashSet< Annotation > & RequiredAnnotations() const noexcept
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
Statistics(const util::FilePath &sourceFile)
RVSDG tree printer debug pass.
util::AnnotationMap ComputeAnnotationMap(const rvsdg::Graph &rvsdg) const
static bool IsMemoryStateOutput(const rvsdg::Output *output) noexcept
~RvsdgTreePrinter() noexcept override
static void AnnotateDebugIds(const rvsdg::Graph &rvsdg, util::AnnotationMap &annotationMap)
static void AnnotateNumMemoryStateInputsOutputs(const rvsdg::Graph &rvsdg, util::AnnotationMap &annotationMap)
static bool IsMemoryStateInput(const rvsdg::Input *input) noexcept
static void AnnotateNumNodes(const rvsdg::Graph &rvsdg, const std::function< bool(const rvsdg::Node &)> &match, const std::string_view &label, util::AnnotationMap &annotationMap)
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
static std::string toJson(const Region &region, const util::AnnotationMap &annotationMap) noexcept
Definition region.cpp:492
void AddAnnotation(const void *key, Annotation annotation)
void open(const char *mode)
Definition file.hpp:374
IteratorRange< ItemConstIterator > Items() const noexcept
Definition HashSet.hpp:223
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
File createOutputFile(std::string fileNameSuffix, bool includeCount=false)
Statistics Interface.
util::Timer & GetTimer(const std::string &name)
util::Timer & AddTimer(std::string name)
void start() noexcept
Definition time.hpp:54
void stop() noexcept
Definition time.hpp:67
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
Global memory state passed between functions.
bool IsAggregateType(const jlm::rvsdg::Type &type)
Definition types.hpp:531
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872