Jlm
Loading...
Searching...
No Matches
Annotation.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
9
10#include <algorithm>
11#include <typeindex>
12
13namespace jlm::llvm
14{
15
16std::string
18{
19 std::string debugString("{");
20
21 bool isFirst = true;
22 for (auto & variable : Variables())
23 {
24 debugString += isFirst ? "" : ", ";
25 debugString += variable.name();
26 isFirst = false;
27 }
28
29 debugString += "}";
30
31 return debugString;
32}
33
34AnnotationSet::~AnnotationSet() noexcept = default;
35
36EntryAnnotationSet::~EntryAnnotationSet() noexcept = default;
37
38std::string
39EntryAnnotationSet::DebugString() const noexcept
40{
41 return util::strfmt(
42 "ReadSet:",
43 ReadSet().DebugString(),
44 " ",
45 "AllWriteSet:",
46 AllWriteSet().DebugString(),
47 " ",
48 "FullWriteSet:",
49 FullWriteSet().DebugString(),
50 " ",
51 "TopSet:",
52 TopSet_.DebugString(),
53 " ");
54}
55
56bool
58{
59 auto otherEntryDemandSet = dynamic_cast<const EntryAnnotationSet *>(&other);
60 return otherEntryDemandSet && AnnotationSet::operator==(other)
61 && TopSet_ == otherEntryDemandSet->TopSet_;
62}
63
64ExitAnnotationSet::~ExitAnnotationSet() noexcept = default;
65
66std::string
67ExitAnnotationSet::DebugString() const noexcept
68{
69 return util::strfmt(
70 "ReadSet:",
71 ReadSet().DebugString(),
72 " ",
73 "AllWriteSet:",
74 AllWriteSet().DebugString(),
75 " ",
76 "FullWriteSet:",
77 FullWriteSet().DebugString(),
78 " ");
79}
80
81bool
83{
84 auto otherExitDemandSet = dynamic_cast<const ExitAnnotationSet *>(&other);
85 return otherExitDemandSet && AnnotationSet::operator==(other);
86}
87
89
90std::string
91BasicBlockAnnotationSet::DebugString() const noexcept
92{
93 return util::strfmt(
94 "ReadSet:",
95 ReadSet().DebugString(),
96 " ",
97 "AllWriteSet:",
98 AllWriteSet().DebugString(),
99 " ",
100 "FullWriteSet:",
101 FullWriteSet().DebugString(),
102 " ");
103}
104
105bool
107{
108 auto otherBasicBlockDemandSet = dynamic_cast<const BasicBlockAnnotationSet *>(&other);
109 return otherBasicBlockDemandSet && AnnotationSet::operator==(other);
110}
111
113
114std::string
115LinearAnnotationSet::DebugString() const noexcept
116{
117 return util::strfmt(
118 "ReadSet:",
119 ReadSet().DebugString(),
120 " ",
121 "AllWriteSet:",
122 AllWriteSet().DebugString(),
123 " ",
124 "FullWriteSet:",
125 FullWriteSet().DebugString(),
126 " ");
127}
128
129bool
131{
132 auto otherLinearDemandSet = dynamic_cast<const LinearAnnotationSet *>(&other);
133 return otherLinearDemandSet && AnnotationSet::operator==(other);
134}
135
137
138std::string
139BranchAnnotationSet::DebugString() const noexcept
140{
141 return util::strfmt(
142 "ReadSet:",
143 ReadSet().DebugString(),
144 " ",
145 "AllWriteSet:",
146 AllWriteSet().DebugString(),
147 " ",
148 "FullWriteSet:",
149 FullWriteSet().DebugString(),
150 " ",
151 "TopSet:",
152 InputVariables().DebugString(),
153 " ",
154 "BottomSet:",
155 OutputVariables().DebugString(),
156 " ");
157}
158
159bool
161{
162 auto otherBranchDemandSet = dynamic_cast<const BranchAnnotationSet *>(&other);
163 return otherBranchDemandSet && AnnotationSet::operator==(other)
164 && InputVariables_ == otherBranchDemandSet->InputVariables_
165 && OutputVariables_ == otherBranchDemandSet->OutputVariables_;
166}
167
168LoopAnnotationSet::~LoopAnnotationSet() noexcept = default;
169
170std::string
171LoopAnnotationSet::DebugString() const noexcept
172{
173 return util::strfmt(
174 "ReadSet:",
175 ReadSet().DebugString(),
176 " ",
177 "AllWriteSet:",
178 AllWriteSet().DebugString(),
179 " ",
180 "FullWriteSet:",
181 FullWriteSet().DebugString(),
182 " ",
183 "LoopVariables:",
184 LoopVariables_.DebugString(),
185 " ");
186}
187
188bool
190{
191 auto otherLoopDemandSet = dynamic_cast<const LoopAnnotationSet *>(&other);
192 return otherLoopDemandSet && AnnotationSet::operator==(other)
193 && LoopVariables_ == otherLoopDemandSet->LoopVariables_;
194}
195
196static void
198
199static void
200AnnotateReadWrite(const EntryAggregationNode & entryAggregationNode, AnnotationMap & demandMap)
201{
202 VariableSet allWriteSet;
203 VariableSet fullWriteSet;
204 for (auto & argument : entryAggregationNode)
205 {
206 allWriteSet.Insert(argument);
207 fullWriteSet.Insert(argument);
208 }
209
210 auto demandSet =
211 EntryAnnotationSet::Create(VariableSet(), std::move(allWriteSet), std::move(fullWriteSet));
212 demandMap.Insert(entryAggregationNode, std::move(demandSet));
213}
214
215static void
216AnnotateReadWrite(const ExitAggregationNode & exitAggregationNode, AnnotationMap & demandMap)
217{
218 VariableSet readSet;
219 for (auto & result : exitAggregationNode)
220 readSet.Insert(*result);
221
222 auto demandSet = ExitAnnotationSet::Create(std::move(readSet), VariableSet(), VariableSet());
223 demandMap.Insert(exitAggregationNode, std::move(demandSet));
224}
225
226static void
228 const BasicBlockAggregationNode & basicBlockAggregationNode,
229 AnnotationMap & demandMap)
230{
231 auto & threeAddressCodeList = basicBlockAggregationNode.tacs();
232
233 VariableSet readSet;
234 VariableSet allWriteSet;
235 VariableSet fullWriteSet;
236 for (auto it = threeAddressCodeList.rbegin(); it != threeAddressCodeList.rend(); it++)
237 {
238 auto & tac = *it;
239 if (is<AssignmentOperation>(tac->operation()))
240 {
241 /*
242 We need special treatment for assignment operation, since the variable
243 they assign the value to is modeled as an argument of the three address code.
244 */
245 JLM_ASSERT(tac->noperands() == 2 && tac->nresults() == 0);
246 readSet.Remove(*tac->operand(0));
247 allWriteSet.Insert(*tac->operand(0));
248 fullWriteSet.Insert(*tac->operand(0));
249 readSet.Insert(*tac->operand(1));
250 }
251 else
252 {
253 for (size_t n = 0; n < tac->nresults(); n++)
254 {
255 readSet.Remove(*tac->result(n));
256 allWriteSet.Insert(*tac->result(n));
257 fullWriteSet.Insert(*tac->result(n));
258 }
259 for (size_t n = 0; n < tac->noperands(); n++)
260 readSet.Insert(*tac->operand(n));
261 }
262 }
263
264 auto demandSet = BasicBlockAnnotationSet::Create(
265 std::move(readSet),
266 std::move(allWriteSet),
267 std::move(fullWriteSet));
268 demandMap.Insert(basicBlockAggregationNode, std::move(demandSet));
269}
270
271static void
272AnnotateReadWrite(const LinearAggregationNode & linearAggregationNode, AnnotationMap & demandMap)
273{
274 VariableSet readSet;
275 VariableSet allWriteSet;
276 VariableSet fullWriteSet;
277 for (size_t n = linearAggregationNode.nchildren() - 1; n != static_cast<size_t>(-1); n--)
278 {
279 auto & childDemandSet = demandMap.Lookup<AnnotationSet>(*linearAggregationNode.child(n));
280
281 readSet.Remove(childDemandSet.FullWriteSet());
282 readSet.Insert(childDemandSet.ReadSet());
283 allWriteSet.Insert(childDemandSet.AllWriteSet());
284 fullWriteSet.Insert(childDemandSet.FullWriteSet());
285 }
286
287 auto demandSet = LinearAnnotationSet::Create(
288 std::move(readSet),
289 std::move(allWriteSet),
290 std::move(fullWriteSet));
291 demandMap.Insert(linearAggregationNode, std::move(demandSet));
292}
293
294static void
295AnnotateReadWrite(const BranchAggregationNode & branchAggregationNode, AnnotationMap & demandMap)
296{
297 auto & case0DemandSet = demandMap.Lookup<AnnotationSet>(*branchAggregationNode.child(0));
298 auto & case0ReadSet = case0DemandSet.ReadSet();
299 auto & case0AllWriteSet = case0DemandSet.AllWriteSet();
300 auto & case0FullWriteSet = case0DemandSet.FullWriteSet();
301
302 VariableSet branchReadSet(case0ReadSet);
303 VariableSet branchAllWriteSet(case0AllWriteSet);
304 VariableSet branchFullWriteSet(case0FullWriteSet);
305 for (size_t n = 1; n < branchAggregationNode.nchildren(); n++)
306 {
307 auto & caseDemandSet = demandMap.Lookup<AnnotationSet>(*branchAggregationNode.child(n));
308
309 branchAllWriteSet.Insert(caseDemandSet.AllWriteSet());
310 branchFullWriteSet.Intersect(caseDemandSet.FullWriteSet());
311 branchReadSet.Insert(caseDemandSet.ReadSet());
312 }
313
314 auto branchDemandSet = BranchAnnotationSet::Create(
315 std::move(branchReadSet),
316 std::move(branchAllWriteSet),
317 std::move(branchFullWriteSet));
318 demandMap.Insert(branchAggregationNode, std::move(branchDemandSet));
319}
320
321static void
322AnnotateReadWrite(const LoopAggregationNode & loopAggregationNode, AnnotationMap & demandMap)
323{
324 auto & loopBody = *loopAggregationNode.child(0);
325 auto & bodyDemandSet = demandMap.Lookup<AnnotationSet>(loopBody);
326
327 auto demandSet = LoopAnnotationSet::Create(
328 bodyDemandSet.ReadSet(),
329 bodyDemandSet.AllWriteSet(),
330 bodyDemandSet.FullWriteSet());
331 demandMap.Insert(loopAggregationNode, std::move(demandSet));
332}
333
334static void
335AnnotateReadWrite(const AggregationNode & aggregationNode, AnnotationMap & demandMap)
336{
337 for (size_t n = 0; n < aggregationNode.nchildren(); n++)
338 AnnotateReadWrite(*aggregationNode.child(n), demandMap);
339
340 if (auto entryNode = dynamic_cast<const EntryAggregationNode *>(&aggregationNode))
341 {
342 AnnotateReadWrite(*entryNode, demandMap);
343 }
344 else if (auto exitNode = dynamic_cast<const ExitAggregationNode *>(&aggregationNode))
345 {
346 AnnotateReadWrite(*exitNode, demandMap);
347 }
348 else if (auto blockNode = dynamic_cast<const BasicBlockAggregationNode *>(&aggregationNode))
349 {
350 AnnotateReadWrite(*blockNode, demandMap);
351 }
352 else if (const auto linearNode = dynamic_cast<const LinearAggregationNode *>(&aggregationNode))
353 {
354 AnnotateReadWrite(*linearNode, demandMap);
355 }
356 else if (auto branchNode = dynamic_cast<const BranchAggregationNode *>(&aggregationNode))
357 {
358 AnnotateReadWrite(*branchNode, demandMap);
359 }
360 else if (auto loopNode = dynamic_cast<const LoopAggregationNode *>(&aggregationNode))
361 {
362 AnnotateReadWrite(*loopNode, demandMap);
363 }
364 else
365 {
366 JLM_UNREACHABLE("Unhandled aggregation node type");
367 }
368}
369
370static void
371AnnotateDemandSet(const AggregationNode &, VariableSet &, AnnotationMap &);
372
373static void
375 const EntryAggregationNode & entryAggregationNode,
376 VariableSet & workingSet,
377 AnnotationMap & demandMap)
378{
379 auto & demandSet = demandMap.Lookup<EntryAnnotationSet>(entryAggregationNode);
380
381 workingSet.Remove(demandSet.FullWriteSet());
382
383 demandSet.TopSet_ = workingSet;
384}
385
386static void
388 const ExitAggregationNode & exitAggregationNode,
389 VariableSet & workingSet,
390 AnnotationMap & demandMap)
391{
392 auto & demandSet = demandMap.Lookup<ExitAnnotationSet>(exitAggregationNode);
393 workingSet.Insert(demandSet.ReadSet());
394}
395
396static void
398 const BasicBlockAggregationNode & basicBlockAggregationNode,
399 VariableSet & workingSet,
400 AnnotationMap & demandMap)
401{
402 auto & demandSet = demandMap.Lookup<BasicBlockAnnotationSet>(basicBlockAggregationNode);
403 workingSet.Remove(demandSet.FullWriteSet());
404 workingSet.Insert(demandSet.ReadSet());
405}
406
407static void
409 const LinearAggregationNode & linearAggregationNode,
410 VariableSet & workingSet,
411 AnnotationMap & demandMap)
412{
413 auto & demandSet = demandMap.Lookup<LinearAnnotationSet>(linearAggregationNode);
414
415 for (size_t n = linearAggregationNode.nchildren() - 1; n != static_cast<size_t>(-1); n--)
416 AnnotateDemandSet(*linearAggregationNode.child(n), workingSet, demandMap);
417
418 workingSet.Remove(demandSet.FullWriteSet());
419 workingSet.Insert(demandSet.ReadSet());
420}
421
422static void
424 const BranchAggregationNode & branchAggregationNode,
425 VariableSet & workingSet,
426 AnnotationMap & demandMap)
427{
428 auto & demandSet = demandMap.Lookup<BranchAnnotationSet>(branchAggregationNode);
429
430 VariableSet branchWorkingSet = workingSet;
431 branchWorkingSet.Intersect(demandSet.AllWriteSet());
432 demandSet.SetOutputVariables(branchWorkingSet);
433
434 for (size_t n = 0; n < branchAggregationNode.nchildren(); n++)
435 {
436 auto caseWorkingSet = branchWorkingSet;
437 AnnotateDemandSet(*branchAggregationNode.child(n), caseWorkingSet, demandMap);
438 }
439
440 branchWorkingSet.Remove(demandSet.FullWriteSet());
441 branchWorkingSet.Insert(demandSet.ReadSet());
442 demandSet.SetInputVariables(branchWorkingSet);
443
444 workingSet.Insert(branchWorkingSet);
445}
446
447static void
449 const LoopAggregationNode & loopAggregationNode,
450 VariableSet & workingSet,
451 AnnotationMap & demandMap)
452{
453 auto & demandSet = demandMap.Lookup<LoopAnnotationSet>(loopAggregationNode);
454
455 workingSet.Insert(demandSet.ReadSet());
456 demandSet.SetLoopVariables(workingSet);
457 AnnotateDemandSet(*loopAggregationNode.child(0), workingSet, demandMap);
458}
459
460template<class T>
461static void
463 const AggregationNode * aggregationNode,
464 VariableSet & workingSet,
465 AnnotationMap & demandMap)
466{
467 JLM_ASSERT(is<T>(aggregationNode));
468 AnnotateDemandSet(*static_cast<const T *>(aggregationNode), workingSet, demandMap);
469}
470
471static void
473 const AggregationNode & aggregationNode,
474 VariableSet & workingSet,
475 AnnotationMap & demandMap)
476{
477 static std::unordered_map<
478 std::type_index,
479 void (*)(const AggregationNode *, VariableSet &, AnnotationMap &)>
480 map({ { typeid(EntryAggregationNode), AnnotateDemandSet<EntryAggregationNode> },
481 { typeid(ExitAggregationNode), AnnotateDemandSet<ExitAggregationNode> },
482 { typeid(BasicBlockAggregationNode), AnnotateDemandSet<BasicBlockAggregationNode> },
483 { typeid(LinearAggregationNode), AnnotateDemandSet<LinearAggregationNode> },
484 { typeid(BranchAggregationNode), AnnotateDemandSet<BranchAggregationNode> },
485 { typeid(LoopAggregationNode), AnnotateDemandSet<LoopAggregationNode> } });
486
487 JLM_ASSERT(map.find(typeid(aggregationNode)) != map.end());
488 return map[typeid(aggregationNode)](&aggregationNode, workingSet, demandMap);
489}
490
491std::unique_ptr<AnnotationMap>
492Annotate(const AggregationNode & aggregationTreeRoot)
493{
494 auto demandMap = AnnotationMap::Create();
495 AnnotateReadWrite(aggregationTreeRoot, *demandMap);
496
497 VariableSet workingSet;
498 AnnotateDemandSet(aggregationTreeRoot, workingSet, *demandMap);
499
500 return demandMap;
501}
502
503}
size_t nchildren() const noexcept
AggregationNode * child(size_t n) const noexcept
T & Lookup(const AggregationNode &aggregationNode) const noexcept
void Insert(const AggregationNode &aggregationNode, std::unique_ptr< AnnotationSet > annotationSet)
static std::unique_ptr< AnnotationMap > Create()
virtual ~AnnotationSet() noexcept
virtual bool operator==(const AnnotationSet &other) const
const VariableSet & ReadSet() const noexcept
const ThreeAddressCodeList & tacs() const noexcept
~BasicBlockAnnotationSet() noexcept override
static std::unique_ptr< BasicBlockAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
bool operator==(const AnnotationSet &other) const override
bool operator==(const AnnotationSet &other) const override
~BranchAnnotationSet() noexcept override
static std::unique_ptr< BranchAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
static std::unique_ptr< EntryAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
bool operator==(const AnnotationSet &other) const override
static std::unique_ptr< ExitAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
~ExitAnnotationSet() noexcept override
bool operator==(const AnnotationSet &other) const override
~LinearAnnotationSet() noexcept override
static std::unique_ptr< LinearAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
bool operator==(const AnnotationSet &other) const override
~LoopAnnotationSet() noexcept override
static std::unique_ptr< LoopAnnotationSet > Create(VariableSet readSet, VariableSet allWriteSet, VariableSet fullWriteSet)
bool operator==(const AnnotationSet &other) const override
void Insert(const Variable &v)
std::string DebugString() const noexcept
ConstRange Variables() const noexcept
void Remove(const Variable &v)
void Intersect(const VariableSet &variableSet)
#define JLM_ASSERT(x)
Definition common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
Global memory state passed between functions.
static void AnnotateReadWrite(const AggregationNode &, AnnotationMap &)
static void AnnotateDemandSet(const AggregationNode &, VariableSet &, AnnotationMap &)
std::unique_ptr< AnnotationMap > Annotate(const AggregationNode &aggregationTreeRoot)
static std::string strfmt(Args... args)
Definition strfmt.hpp:35