Jlm
Loading...
Searching...
No Matches
InterProceduralGraphConversion.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
18#include <jlm/llvm/ir/ssa.hpp>
19#include <jlm/rvsdg/binary.hpp>
20#include <jlm/rvsdg/gamma.hpp>
21#include <jlm/rvsdg/Phi.hpp>
22#include <jlm/rvsdg/theta.hpp>
24#include <jlm/util/time.hpp>
25
26#include <stack>
27#include <utility>
28
29namespace jlm::llvm
30{
31
32class VariableMap final
33{
34public:
35 bool
36 contains(const Variable * v) const noexcept
37 {
38 return Map_.find(v) != Map_.end();
39 }
40
42 lookup(const Variable * v) const
43 {
45 return Map_.at(v);
46 }
47
48 void
50 {
51 JLM_ASSERT(v->type() == *o->Type());
52 Map_[v] = o;
53 }
54
55private:
56 std::unordered_map<const Variable *, rvsdg::Output *> Map_;
57};
58
60{
61public:
67
69 const InterProceduralGraphModule & interProceduralGraphModule,
70 rvsdg::Region & region)
71 : InterProceduralGraphModule_(interProceduralGraphModule)
72 {
73 PushRegion(region);
74 }
75
76 size_t
77 NumRegions() const noexcept
78 {
80 return VariableMapStack_.size();
81 }
82
84 VariableMap(size_t n) noexcept
85 {
87 return *VariableMapStack_[n];
88 }
89
92 {
94 return VariableMap(NumRegions() - 1);
95 }
96
98 GetRegion(size_t n) noexcept
99 {
100 JLM_ASSERT(n < NumRegions());
101 return *RegionStack_[n];
102 }
103
105 GetTopRegion() noexcept
106 {
107 JLM_ASSERT(NumRegions() > 0);
108 return GetRegion(NumRegions() - 1);
109 }
110
111 void
113 {
114 VariableMapStack_.push_back(std::make_unique<llvm::VariableMap>());
115 RegionStack_.push_back(&region);
116 }
117
118 void
120 {
121 VariableMapStack_.pop_back();
122 RegionStack_.pop_back();
123 }
124
127 {
129 }
130
131private:
133 std::vector<std::unique_ptr<llvm::VariableMap>> VariableMapStack_;
134 std::vector<rvsdg::Region *> RegionStack_;
135};
136
138{
139public:
141
143 const util::FilePath & sourceFileName,
144 const std::string & functionName)
145 : Statistics(Statistics::Id::ControlFlowRecovery, sourceFileName)
146 {
147 AddMeasurement(Label::FunctionNameLabel_, functionName);
148 }
149
150 void
151 Start(const ControlFlowGraph & cfg) noexcept
152 {
153 AddMeasurement(Label::NumCfgNodes, cfg.nnodes());
154 AddTimer(Label::Timer).start();
155 }
156
157 void
158 End() noexcept
159 {
160 GetTimer(Label::Timer).stop();
161 }
162
163 static std::unique_ptr<ControlFlowRestructuringStatistics>
164 Create(const util::FilePath & sourceFileName, const std::string & functionName)
165 {
166 return std::make_unique<ControlFlowRestructuringStatistics>(sourceFileName, functionName);
167 }
168};
169
171{
172public:
173 ~AggregationStatistics() override = default;
174
175 AggregationStatistics(const util::FilePath & sourceFileName, const std::string & functionName)
176 : Statistics(util::Statistics::Id::Aggregation, sourceFileName)
177 {
178 AddMeasurement(Label::FunctionNameLabel_, functionName);
179 }
180
181 void
182 Start(const ControlFlowGraph & cfg) noexcept
183 {
184 AddMeasurement(Label::NumCfgNodes, cfg.nnodes());
185 AddTimer(Label::Timer).start();
186 }
187
188 void
189 End() noexcept
190 {
191 GetTimer(Label::Timer).stop();
192 }
193
194 static std::unique_ptr<AggregationStatistics>
195 Create(const util::FilePath & sourceFileName, const std::string & functionName)
196 {
197 return std::make_unique<AggregationStatistics>(sourceFileName, functionName);
198 }
199};
200
202{
203public:
204 ~AnnotationStatistics() override = default;
205
206 AnnotationStatistics(const util::FilePath & sourceFileName, const std::string & functionName)
207 : Statistics(util::Statistics::Id::Annotation, sourceFileName)
208 {
209 AddMeasurement(Label::FunctionNameLabel_, functionName);
210 }
211
212 void
213 Start(const AggregationNode & node) noexcept
214 {
215 AddMeasurement(Label::NumThreeAddressCodes, llvm::ntacs(node));
216 AddTimer(Label::Timer).start();
217 }
218
219 void
220 End() noexcept
221 {
222 GetTimer(Label::Timer).stop();
223 }
224
225 static std::unique_ptr<AnnotationStatistics>
226 Create(const util::FilePath & sourceFileName, const std::string & functionName)
227 {
228 return std::make_unique<AnnotationStatistics>(sourceFileName, functionName);
229 }
230};
231
233{
234public:
236
238 const util::FilePath & sourceFileName,
239 const std::string & functionName)
240 : Statistics(util::Statistics::Id::JlmToRvsdgConversion, sourceFileName)
241 {
242 AddMeasurement(Label::FunctionNameLabel_, functionName);
243 }
244
245 void
246 Start() noexcept
247 {
248 AddTimer(Label::Timer).start();
249 }
250
251 void
252 End() noexcept
253 {
254 GetTimer(Label::Timer).stop();
255 }
256
257 static std::unique_ptr<AggregationTreeToLambdaStatistics>
258 Create(const util::FilePath & sourceFileName, const std::string & functionName)
259 {
260 return std::make_unique<AggregationTreeToLambdaStatistics>(sourceFileName, functionName);
261 }
262};
263
265{
266public:
267 ~DataNodeToDeltaStatistics() override = default;
268
269 DataNodeToDeltaStatistics(const util::FilePath & sourceFileName, const std::string & dataNodeName)
270 : Statistics(util::Statistics::Id::DataNodeToDelta, sourceFileName)
271 {
272 AddMeasurement("DataNode", dataNodeName);
273 }
274
275 void
276 Start(size_t numInitializationThreeAddressCodes) noexcept
277 {
278 AddMeasurement(Label::NumThreeAddressCodes, numInitializationThreeAddressCodes);
279 AddTimer(Label::Timer).start();
280 }
281
282 void
283 End() noexcept
284 {
285 GetTimer(Label::Timer).stop();
286 }
287
288 static std::unique_ptr<DataNodeToDeltaStatistics>
289 Create(const util::FilePath & sourceFileName, const std::string & dataNodeName)
290 {
291 return std::make_unique<DataNodeToDeltaStatistics>(sourceFileName, dataNodeName);
292 }
293};
294
296{
297public:
299
301 : Statistics(util::Statistics::Id::RvsdgConstruction, sourceFileName)
302 {}
303
304 void
305 Start(const InterProceduralGraphModule & interProceduralGraphModule) noexcept
306 {
307 AddMeasurement(Label::NumThreeAddressCodes, llvm::ntacs(interProceduralGraphModule));
308 AddTimer(Label::Timer).start();
309 }
310
311 void
312 End(const rvsdg::Graph & graph) noexcept
313 {
314 GetTimer(Label::Timer).stop();
315 AddMeasurement(Label::NumRvsdgNodes, rvsdg::nnodes(&graph.GetRootRegion()));
316 }
317
318 static std::unique_ptr<InterProceduralGraphToRvsdgStatistics>
319 Create(const util::FilePath & sourceFileName)
320 {
321 return std::make_unique<InterProceduralGraphToRvsdgStatistics>(sourceFileName);
322 }
323};
324
326{
327public:
334
335 void
337 const std::function<void(ControlFlowGraph *)> & restructureControlFlowGraph,
338 ControlFlowGraph & cfg,
339 std::string functionName)
340 {
341 auto statistics =
343
344 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
345 {
346 restructureControlFlowGraph(&cfg);
347 return;
348 }
349
350 statistics->Start(cfg);
351 restructureControlFlowGraph(&cfg);
352 statistics->End();
353
354 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
355 }
356
357 std::unique_ptr<AggregationNode>
359 const std::function<std::unique_ptr<AggregationNode>(ControlFlowGraph &)> &
360 aggregateControlFlowGraph,
361 ControlFlowGraph & cfg,
362 std::string functionName)
363 {
364 auto statistics = AggregationStatistics::Create(SourceFileName_, std::move(functionName));
365
366 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
367 return aggregateControlFlowGraph(cfg);
368
369 statistics->Start(cfg);
370 auto aggregationTreeRoot = aggregateControlFlowGraph(cfg);
371 statistics->End();
372
373 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
374
375 return aggregationTreeRoot;
376 }
377
378 std::unique_ptr<AnnotationMap>
380 const std::function<std::unique_ptr<AnnotationMap>(const AggregationNode &)> &
381 annotateAggregationTree,
382 const AggregationNode & aggregationTreeRoot,
383 std::string functionName)
384 {
385 auto statistics = AnnotationStatistics::Create(SourceFileName_, std::move(functionName));
386
387 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
388 return annotateAggregationTree(aggregationTreeRoot);
389
390 statistics->Start(aggregationTreeRoot);
391 auto demandMap = annotateAggregationTree(aggregationTreeRoot);
392 statistics->End();
393
394 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
395
396 return demandMap;
397 }
398
399 void
401 const std::function<void()> & convertAggregationTreeToLambda,
402 std::string functionName)
403 {
404 auto statistics =
406
407 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
408 return convertAggregationTreeToLambda();
409
410 statistics->Start();
411 convertAggregationTreeToLambda();
412 statistics->End();
413
414 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
415 }
416
419 const std::function<rvsdg::Output *()> & convertDataNodeToDelta,
420 std::string dataNodeName,
421 size_t NumInitializationThreeAddressCodes)
422 {
423 auto statistics = DataNodeToDeltaStatistics::Create(SourceFileName_, std::move(dataNodeName));
424
425 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
426 return convertDataNodeToDelta();
427
428 statistics->Start(NumInitializationThreeAddressCodes);
429 auto output = convertDataNodeToDelta();
430 statistics->End();
431
432 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
433
434 return output;
435 }
436
437 std::unique_ptr<LlvmRvsdgModule>
439 const std::function<std::unique_ptr<LlvmRvsdgModule>(InterProceduralGraphModule &)> &
440 convertInterProceduralGraphModule,
441 InterProceduralGraphModule & interProceduralGraphModule)
442 {
444
445 if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
446 return convertInterProceduralGraphModule(interProceduralGraphModule);
447
448 statistics->Start(interProceduralGraphModule);
449 auto rvsdgModule = convertInterProceduralGraphModule(interProceduralGraphModule);
450 statistics->End(rvsdgModule->Rvsdg());
451
452 StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
453
454 return rvsdgModule;
455 }
456
457private:
460};
461
462static bool
464{
465 return ipgNode.hasBody() && !isDiscardableIfUnused(ipgNode.linkage());
466}
467
468static void
470 const llvm::ThreeAddressCode & threeAddressCode,
472 llvm::VariableMap & variableMap)
473{
474 JLM_ASSERT(is<AssignmentOperation>(threeAddressCode.operation()));
475
476 auto lhs = threeAddressCode.operand(0);
477 auto rhs = threeAddressCode.operand(1);
478 variableMap.insert(lhs, variableMap.lookup(rhs));
479}
480
481static void
483 const llvm::ThreeAddressCode & threeAddressCode,
485 llvm::VariableMap & variableMap)
486{
487 JLM_ASSERT(is<SelectOperation>(threeAddressCode.operation()));
488 JLM_ASSERT(threeAddressCode.noperands() == 3 && threeAddressCode.nresults() == 1);
489
490 auto p = variableMap.lookup(threeAddressCode.operand(0));
491 auto predicate = rvsdg::MatchOperation::Create(*p, { { 1, 1 } }, 0, 2);
492
493 auto gamma = rvsdg::GammaNode::create(predicate, 2);
494 auto ev1 = gamma->AddEntryVar(variableMap.lookup(threeAddressCode.operand(2)));
495 auto ev2 = gamma->AddEntryVar(variableMap.lookup(threeAddressCode.operand(1)));
496 auto ex = gamma->AddExitVar({ ev1.branchArgument[0], ev2.branchArgument[1] });
497 variableMap.insert(threeAddressCode.result(0), ex.output);
498}
499
500static void
502{
503 JLM_ASSERT(is<BranchOperation>(threeAddressCode.operation()));
504 /*
505 * Nothing needs to be done. Branches are simply ignored.
506 */
507}
508
509template<class TNode, class TOperation>
510static void
512 const llvm::ThreeAddressCode & threeAddressCode,
513 rvsdg::Region & region,
514 llvm::VariableMap & variableMap)
515{
516 std::vector<rvsdg::Output *> operands;
517 for (size_t n = 0; n < threeAddressCode.noperands(); n++)
518 {
519 auto operand = threeAddressCode.operand(n);
520 operands.push_back(variableMap.lookup(operand));
521 }
522
523 std::unique_ptr<TOperation> operation(
524 util::assertedCast<TOperation>(threeAddressCode.operation().copy().release()));
525 auto results = TNode::Create(region, std::move(operation), operands);
526
527 JLM_ASSERT(results.size() == threeAddressCode.nresults());
528 for (size_t n = 0; n < threeAddressCode.nresults(); n++)
529 {
530 auto result = threeAddressCode.result(n);
531 variableMap.insert(result, results[n]);
532 }
533}
534
535static void
537 const llvm::ThreeAddressCode & threeAddressCode,
538 rvsdg::Region & region,
539 llvm::VariableMap & variableMap)
540{
541 if (is<AssignmentOperation>(&threeAddressCode))
542 {
543 ConvertAssignment(threeAddressCode, region, variableMap);
544 }
545 else if (is<SelectOperation>(&threeAddressCode))
546 {
547 ConvertSelect(threeAddressCode, region, variableMap);
548 }
549 else if (is<BranchOperation>(&threeAddressCode))
550 {
551 ConvertBranch(threeAddressCode, region, variableMap);
552 }
553 else
554 {
555 std::vector<rvsdg::Output *> operands;
556 for (size_t n = 0; n < threeAddressCode.noperands(); n++)
557 operands.push_back(variableMap.lookup(threeAddressCode.operand(n)));
558
559 auto results =
560 outputs(&rvsdg::SimpleNode::Create(region, threeAddressCode.operation().copy(), operands));
561
562 JLM_ASSERT(results.size() == threeAddressCode.nresults());
563 for (size_t n = 0; n < threeAddressCode.nresults(); n++)
564 variableMap.insert(threeAddressCode.result(n), results[n]);
565 }
566}
567
568static void
570 const ThreeAddressCodeList & basicBlock,
571 rvsdg::Region & region,
572 llvm::VariableMap & variableMap)
573{
574 for (const auto & threeAddressCode : basicBlock)
575 ConvertThreeAddressCode(*threeAddressCode, region, variableMap);
576}
577
578static void
580 const AggregationNode & aggregationNode,
581 const AnnotationMap & demandMap,
582 rvsdg::LambdaNode & lambdaNode,
583 RegionalizedVariableMap & regionalizedVariableMap);
584
585static void
587 const EntryAggregationNode & entryAggregationNode,
588 const AnnotationMap & demandMap,
589 rvsdg::LambdaNode & lambdaNode,
590 RegionalizedVariableMap & regionalizedVariableMap)
591{
592 auto & demandSet = demandMap.Lookup<EntryAnnotationSet>(entryAggregationNode);
593
594 regionalizedVariableMap.PushRegion(*lambdaNode.subregion());
595
596 auto & outerVariableMap =
597 regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
598 auto & topVariableMap = regionalizedVariableMap.GetTopVariableMap();
599
600 /*
601 * Add arguments
602 */
603 JLM_ASSERT(entryAggregationNode.narguments() == lambdaNode.GetFunctionArguments().size());
604 auto lambdaArgs = lambdaNode.GetFunctionArguments();
605 for (size_t n = 0; n < entryAggregationNode.narguments(); n++)
606 {
607 auto functionNodeArgument = entryAggregationNode.argument(n);
608 auto lambdaNodeArgument = lambdaArgs[n];
609
610 topVariableMap.insert(functionNodeArgument, lambdaNodeArgument);
611 dynamic_cast<llvm::LlvmLambdaOperation &>(lambdaNode.GetOperation())
612 .SetArgumentAttributes(n, functionNodeArgument->attributes());
613 }
614
615 /*
616 * Add dependencies and undefined values
617 */
618 for (auto & v : demandSet.TopSet_.Variables())
619 {
620 if (outerVariableMap.contains(&v))
621 {
622 topVariableMap.insert(&v, lambdaNode.AddContextVar(*outerVariableMap.lookup(&v)).inner);
623 }
624 else
625 {
626 auto value = UndefValueOperation::Create(*lambdaNode.subregion(), v.Type());
627 topVariableMap.insert(&v, value);
628 }
629 }
630}
631
632static void
634 const ExitAggregationNode & exitAggregationNode,
635 const AnnotationMap &,
636 rvsdg::LambdaNode & lambdaNode,
637 RegionalizedVariableMap & regionalizedVariableMap)
638{
639 std::vector<rvsdg::Output *> results;
640 for (const auto & result : exitAggregationNode)
641 {
642 JLM_ASSERT(regionalizedVariableMap.GetTopVariableMap().contains(result));
643 results.push_back(regionalizedVariableMap.GetTopVariableMap().lookup(result));
644 }
645
646 regionalizedVariableMap.PopRegion();
647 lambdaNode.finalize(results);
648}
649
650static void
652 const BasicBlockAggregationNode & blockAggregationNode,
653 const AnnotationMap &,
655 RegionalizedVariableMap & regionalizedVariableMap)
656{
658 blockAggregationNode.tacs(),
659 regionalizedVariableMap.GetTopRegion(),
660 regionalizedVariableMap.GetTopVariableMap());
661}
662
663static void
665 const LinearAggregationNode & linearAggregationNode,
666 const AnnotationMap & demandMap,
667 rvsdg::LambdaNode & lambdaNode,
668 RegionalizedVariableMap & regionalizedVariableMap)
669{
670 for (const auto & child : linearAggregationNode)
671 ConvertAggregationNode(child, demandMap, lambdaNode, regionalizedVariableMap);
672}
673
674static void
676 const BranchAggregationNode & branchAggregationNode,
677 const AnnotationMap & demandMap,
678 rvsdg::LambdaNode & lambdaNode,
679 RegionalizedVariableMap & regionalizedVariableMap)
680{
681 JLM_ASSERT(is<LinearAggregationNode>(branchAggregationNode.parent()));
682
683 /*
684 * Find predicate
685 */
686 auto split = branchAggregationNode.parent()->child(branchAggregationNode.index() - 1);
687 while (!is<BasicBlockAggregationNode>(split))
688 split = split->child(split->nchildren() - 1);
689 auto & sb = dynamic_cast<const BasicBlockAggregationNode *>(split)->tacs();
690 JLM_ASSERT(is<BranchOperation>(sb.last()->operation()));
691 auto predicate = regionalizedVariableMap.GetTopVariableMap().lookup(sb.last()->operand(0));
692
693 auto gamma = rvsdg::GammaNode::create(predicate, branchAggregationNode.nchildren());
694
695 /*
696 * Add gamma inputs.
697 */
698 auto & demandSet = demandMap.Lookup<BranchAnnotationSet>(branchAggregationNode);
699 std::unordered_map<const Variable *, rvsdg::Input *> gammaInputMap;
700 for (auto & v : demandSet.InputVariables().Variables())
701 gammaInputMap[&v] =
702 gamma->AddEntryVar(regionalizedVariableMap.GetTopVariableMap().lookup(&v)).input;
703
704 /*
705 * Convert subregions.
706 */
707 std::unordered_map<const Variable *, std::vector<rvsdg::Output *>> xvmap;
708 JLM_ASSERT(gamma->nsubregions() == branchAggregationNode.nchildren());
709 for (size_t n = 0; n < gamma->nsubregions(); n++)
710 {
711 regionalizedVariableMap.PushRegion(*gamma->subregion(n));
712 for (const auto & pair : gammaInputMap)
713 {
714 auto rolevar = gamma->MapInput(*pair.second);
715 if (auto entryvar = std::get_if<rvsdg::GammaNode::EntryVar>(&rolevar))
716 {
717 regionalizedVariableMap.GetTopVariableMap().insert(pair.first, entryvar->branchArgument[n]);
718 }
719 }
720
722 *branchAggregationNode.child(n),
723 demandMap,
724 lambdaNode,
725 regionalizedVariableMap);
726
727 for (auto & v : demandSet.OutputVariables().Variables())
728 xvmap[&v].push_back(regionalizedVariableMap.GetTopVariableMap().lookup(&v));
729 regionalizedVariableMap.PopRegion();
730 }
731
732 /*
733 * Add gamma outputs.
734 */
735 for (auto & v : demandSet.OutputVariables().Variables())
736 {
737 JLM_ASSERT(xvmap.find(&v) != xvmap.end());
738 regionalizedVariableMap.GetTopVariableMap().insert(&v, gamma->AddExitVar(xvmap[&v]).output);
739 }
740}
741
742static void
744 const LoopAggregationNode & loopAggregationNode,
745 const AnnotationMap & demandMap,
746 rvsdg::LambdaNode & lambdaNode,
747 RegionalizedVariableMap & regionalizedVariableMap)
748{
749 auto & parentRegion = regionalizedVariableMap.GetTopRegion();
750
751 auto theta = rvsdg::ThetaNode::create(&parentRegion);
752
753 regionalizedVariableMap.PushRegion(*theta->subregion());
754 auto & thetaVariableMap = regionalizedVariableMap.GetTopVariableMap();
755 auto & outerVariableMap =
756 regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
757
758 /*
759 * Add loop variables
760 */
761 auto & demandSet = demandMap.Lookup<LoopAnnotationSet>(loopAggregationNode);
762 std::unordered_map<const Variable *, rvsdg::ThetaNode::LoopVar> thetaLoopVarMap;
763 for (auto & v : demandSet.LoopVariables().Variables())
764 {
765 rvsdg::Output * value = nullptr;
766 if (!outerVariableMap.contains(&v))
767 {
768 value = UndefValueOperation::Create(parentRegion, v.Type());
769 outerVariableMap.insert(&v, value);
770 }
771 else
772 {
773 value = outerVariableMap.lookup(&v);
774 }
775 auto loopvar = theta->AddLoopVar(value);
776 thetaLoopVarMap[&v] = loopvar;
777 thetaVariableMap.insert(&v, loopvar.pre);
778 }
779
780 /*
781 * Convert loop body
782 */
783 JLM_ASSERT(loopAggregationNode.nchildren() == 1);
785 *loopAggregationNode.child(0),
786 demandMap,
787 lambdaNode,
788 regionalizedVariableMap);
789
790 /*
791 * Update loop variables
792 */
793 for (auto & v : demandSet.LoopVariables().Variables())
794 {
795 JLM_ASSERT(thetaLoopVarMap.find(&v) != thetaLoopVarMap.end());
796 thetaLoopVarMap[&v].post->divert_to(thetaVariableMap.lookup(&v));
797 }
798
799 /*
800 * Find predicate
801 */
802 auto lblock = loopAggregationNode.child(0);
803 while (lblock->nchildren() != 0)
804 lblock = lblock->child(lblock->nchildren() - 1);
805 JLM_ASSERT(is<BasicBlockAggregationNode>(lblock));
806 auto & bb = static_cast<const BasicBlockAggregationNode *>(lblock)->tacs();
807 JLM_ASSERT(is<BranchOperation>(bb.last()->operation()));
808 auto predicate = bb.last()->operand(0);
809
810 /*
811 * Update variable map
812 */
813 theta->set_predicate(thetaVariableMap.lookup(predicate));
814 regionalizedVariableMap.PopRegion();
815 for (auto & v : demandSet.LoopVariables().Variables())
816 {
817 JLM_ASSERT(outerVariableMap.contains(&v));
818 outerVariableMap.insert(&v, thetaLoopVarMap[&v].output);
819 }
820}
821
822static void
824 const AggregationNode & aggregationNode,
825 const AnnotationMap & demandMap,
826 rvsdg::LambdaNode & lambdaNode,
827 RegionalizedVariableMap & regionalizedVariableMap)
828{
829 if (auto entryNode = dynamic_cast<const EntryAggregationNode *>(&aggregationNode))
830 {
831 Convert(*entryNode, demandMap, lambdaNode, regionalizedVariableMap);
832 }
833 else if (auto exitNode = dynamic_cast<const ExitAggregationNode *>(&aggregationNode))
834 {
835 Convert(*exitNode, demandMap, lambdaNode, regionalizedVariableMap);
836 }
837 else if (auto blockNode = dynamic_cast<const BasicBlockAggregationNode *>(&aggregationNode))
838 {
839 Convert(*blockNode, demandMap, lambdaNode, regionalizedVariableMap);
840 }
841 else if (const auto linearNode = dynamic_cast<const LinearAggregationNode *>(&aggregationNode))
842 {
843 Convert(*linearNode, demandMap, lambdaNode, regionalizedVariableMap);
844 }
845 else if (auto branchNode = dynamic_cast<const BranchAggregationNode *>(&aggregationNode))
846 {
847 Convert(*branchNode, demandMap, lambdaNode, regionalizedVariableMap);
848 }
849 else if (auto loopNode = dynamic_cast<const LoopAggregationNode *>(&aggregationNode))
850 {
851 Convert(*loopNode, demandMap, lambdaNode, regionalizedVariableMap);
852 }
853 else
854 {
855 JLM_UNREACHABLE("Unhandled aggregation node type");
856 }
857}
858
859static void
861 ControlFlowGraph & controlFlowGraph,
862 const std::string & functionName,
864{
865 auto restructureControlFlowGraph = [](ControlFlowGraph * controlFlowGraph)
866 {
867 RestructureControlFlow(*controlFlowGraph);
868 straighten(*controlFlowGraph);
869 };
870
871 statisticsCollector.CollectControlFlowRestructuringStatistics(
872 restructureControlFlowGraph,
873 controlFlowGraph,
874 functionName);
875}
876
877static std::unique_ptr<AggregationNode>
879 ControlFlowGraph & controlFlowGraph,
880 const std::string & functionName,
882{
883 auto aggregateControlFlowGraph = [](ControlFlowGraph & controlFlowGraph)
884 {
885 auto aggregationTreeRoot = aggregate(controlFlowGraph);
886 AggregationNode::normalize(*aggregationTreeRoot);
887
888 return aggregationTreeRoot;
889 };
890
891 auto aggregationTreeRoot = statisticsCollector.CollectAggregationStatistics(
892 aggregateControlFlowGraph,
893 controlFlowGraph,
894 functionName);
895
896 return aggregationTreeRoot;
897}
898
899static std::unique_ptr<AnnotationMap>
901 const AggregationNode & aggregationTreeRoot,
902 const std::string & functionName,
904{
905 auto demandMap =
906 statisticsCollector.CollectAnnotationStatistics(Annotate, aggregationTreeRoot, functionName);
907
908 return demandMap;
909}
910
911static rvsdg::Output *
913 const AggregationNode & aggregationTreeRoot,
914 const AnnotationMap & demandMap,
915 RegionalizedVariableMap & scopedVariableMap,
916 const std::string & functionName,
917 std::shared_ptr<const rvsdg::FunctionType> functionType,
918 const Linkage & functionLinkage,
919 const CallingConvention & functionCallingConvention,
920 const AttributeSet & functionAttributes,
922{
923 auto lambdaNode = rvsdg::LambdaNode::Create(
924 scopedVariableMap.GetTopRegion(),
925 std::make_unique<llvm::LlvmLambdaOperation>(
926 std::move(functionType),
927 functionName,
928 functionLinkage,
929 functionCallingConvention,
930 functionAttributes));
931
932 auto convertAggregationTreeToLambda = [&]()
933 {
934 ConvertAggregationNode(aggregationTreeRoot, demandMap, *lambdaNode, scopedVariableMap);
935 };
936
937 statisticsCollector.CollectAggregationTreeToLambdaStatistics(
938 convertAggregationTreeToLambda,
939 functionName);
940
941 return lambdaNode->output();
942}
943
944static rvsdg::Output *
946 const FunctionNode & functionNode,
947 RegionalizedVariableMap & regionalizedVariableMap,
949{
950 auto & functionName = functionNode.name();
951 auto & controlFlowGraph = *functionNode.cfg();
952
953 destruct_ssa(controlFlowGraph);
954 straighten(controlFlowGraph);
955 purge(controlFlowGraph);
956
957 RestructureControlFlowGraph(controlFlowGraph, functionName, statisticsCollector);
958
959 auto aggregationTreeRoot =
960 AggregateControlFlowGraph(controlFlowGraph, functionName, statisticsCollector);
961
962 auto demandMap = AnnotateAggregationTree(*aggregationTreeRoot, functionName, statisticsCollector);
963
964 auto lambdaOutput = ConvertAggregationTreeToLambda(
965 *aggregationTreeRoot,
966 *demandMap,
967 regionalizedVariableMap,
968 functionName,
969 functionNode.GetFunctionType(),
970 functionNode.linkage(),
971 functionNode.callingConvention(),
972 functionNode.attributes(),
974
975 return lambdaOutput;
976}
977
978static rvsdg::Output *
980 const FunctionNode & functionNode,
981 RegionalizedVariableMap & regionalizedVariableMap,
983{
984 auto & region = regionalizedVariableMap.GetTopRegion();
985
986 /*
987 * It is a function declaration as there is no control flow graph attached to the function. Simply
988 * add a function import.
989 */
990 if (functionNode.cfg() == nullptr)
991 {
993 *region.graph(),
994 functionNode.GetFunctionType(),
995 functionNode.name(),
996 functionNode.linkage(),
997 functionNode.callingConvention());
998 }
999
1000 return ConvertControlFlowGraph(functionNode, regionalizedVariableMap, statisticsCollector);
1001}
1002
1003static rvsdg::Output *
1005 const DataNodeInit & init,
1006 rvsdg::Region & region,
1007 RegionalizedVariableMap & regionalizedVariableMap)
1008{
1009 auto & variableMap = regionalizedVariableMap.GetTopVariableMap();
1010 for (const auto & tac : init.tacs())
1011 ConvertThreeAddressCode(*tac, region, variableMap);
1012
1013 return variableMap.lookup(init.value());
1014}
1015
1016static rvsdg::Output *
1018 const DataNode & dataNode,
1019 RegionalizedVariableMap & regionalizedVariableMap,
1021{
1022 auto dataNodeInitialization = dataNode.initialization();
1023
1024 auto convertDataNodeToDeltaNode = [&]() -> rvsdg::Output *
1025 {
1026 auto & interProceduralGraphModule = regionalizedVariableMap.GetInterProceduralGraphModule();
1027 auto & region = regionalizedVariableMap.GetTopRegion();
1028
1029 /*
1030 * We have a data node without initialization. Simply add an RVSDG import.
1031 */
1032 if (!dataNodeInitialization)
1033 {
1035 *region.graph(),
1036 dataNode.GetValueType(),
1038 dataNode.name(),
1039 dataNode.linkage(),
1040 dataNode.constant(),
1041 dataNode.getAlignment());
1042 }
1043
1044 /*
1045 * data node with initialization
1046 */
1047 auto deltaNode = rvsdg::DeltaNode::Create(
1048 &region,
1050 dataNode.GetValueType(),
1051 dataNode.name(),
1052 dataNode.linkage(),
1053 dataNode.Section(),
1054 dataNode.constant(),
1055 dataNode.getAlignment()));
1056 auto & outerVariableMap = regionalizedVariableMap.GetTopVariableMap();
1057 regionalizedVariableMap.PushRegion(*deltaNode->subregion());
1058
1059 /*
1060 * Add dependencies
1061 */
1062 for (const auto & dependency : dataNode)
1063 {
1064 auto dependencyVariable = interProceduralGraphModule.variable(dependency);
1065 auto ctxVar = deltaNode->AddContextVar(*outerVariableMap.lookup(dependencyVariable));
1066 regionalizedVariableMap.GetTopVariableMap().insert(dependencyVariable, ctxVar.inner);
1067 }
1068
1069 auto initOutput = ConvertDataNodeInitialization(
1070 *dataNodeInitialization,
1071 *deltaNode->subregion(),
1072 regionalizedVariableMap);
1073 auto deltaOutput = &deltaNode->finalize(initOutput);
1074 regionalizedVariableMap.PopRegion();
1075
1076 return deltaOutput;
1077 };
1078
1079 auto deltaOutput = statisticsCollector.CollectDataNodeToDeltaStatistics(
1080 convertDataNodeToDeltaNode,
1081 dataNode.name(),
1082 dataNodeInitialization ? dataNodeInitialization->tacs().size() : 0);
1083
1084 return deltaOutput;
1085}
1086
1087static rvsdg::Output *
1089 const InterProceduralGraphNode & ipgNode,
1090 RegionalizedVariableMap & regionalizedVariableMap,
1092{
1093 if (auto functionNode = dynamic_cast<const FunctionNode *>(&ipgNode))
1094 return ConvertFunctionNode(*functionNode, regionalizedVariableMap, statisticsCollector);
1095
1096 if (auto dataNode = dynamic_cast<const DataNode *>(&ipgNode))
1097 return ConvertDataNode(*dataNode, regionalizedVariableMap, statisticsCollector);
1098
1099 JLM_UNREACHABLE("This should have never happened.");
1100}
1101
1102static void
1104 const std::unordered_set<const InterProceduralGraphNode *> & stronglyConnectedComponent,
1105 rvsdg::Graph & graph,
1106 RegionalizedVariableMap & regionalizedVariableMap,
1108{
1109 auto & interProceduralGraphModule = regionalizedVariableMap.GetInterProceduralGraphModule();
1110
1111 /*
1112 * It is a single node that is not self-recursive. We do not need a phi node to break any cycles.
1113 */
1114 if (stronglyConnectedComponent.size() == 1
1115 && !(*stronglyConnectedComponent.begin())->is_selfrecursive())
1116 {
1117 auto & ipgNode = *stronglyConnectedComponent.begin();
1118
1119 auto output =
1120 ConvertInterProceduralGraphNode(*ipgNode, regionalizedVariableMap, statisticsCollector);
1121
1122 auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1123 regionalizedVariableMap.GetTopVariableMap().insert(ipgNodeVariable, output);
1124
1125 if (requiresExport(*ipgNode))
1126 rvsdg::GraphExport::Create(*output, ipgNodeVariable->name());
1127
1128 return;
1129 }
1130
1132 pb.begin(&graph.GetRootRegion());
1133 regionalizedVariableMap.PushRegion(*pb.subregion());
1134
1135 auto & outerVariableMap =
1136 regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
1137 auto & phiVariableMap = regionalizedVariableMap.GetTopVariableMap();
1138
1139 /*
1140 * Add recursion variables
1141 */
1142 std::unordered_map<const Variable *, rvsdg::PhiNode::FixVar> recursionVariables;
1143 for (const auto & ipgNode : stronglyConnectedComponent)
1144 {
1145 auto recursionVariable = pb.AddFixVar(ipgNode->Type());
1146 auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1147 phiVariableMap.insert(ipgNodeVariable, recursionVariable.recref);
1148 JLM_ASSERT(recursionVariables.find(ipgNodeVariable) == recursionVariables.end());
1149 recursionVariables[ipgNodeVariable] = recursionVariable;
1150 }
1151
1152 /*
1153 * Add phi node dependencies
1154 */
1155 for (const auto & ipgNode : stronglyConnectedComponent)
1156 {
1157 for (const auto & ipgNodeDependency : *ipgNode)
1158 {
1159 auto dependencyVariable = interProceduralGraphModule.variable(ipgNodeDependency);
1160 if (recursionVariables.find(dependencyVariable) == recursionVariables.end())
1161 phiVariableMap.insert(
1162 dependencyVariable,
1163 pb.AddContextVar(*outerVariableMap.lookup(dependencyVariable)).inner);
1164 }
1165 }
1166
1167 /*
1168 * Convert SCC nodes
1169 */
1170 for (const auto & ipgNode : stronglyConnectedComponent)
1171 {
1172 auto output =
1173 ConvertInterProceduralGraphNode(*ipgNode, regionalizedVariableMap, statisticsCollector);
1174 recursionVariables[interProceduralGraphModule.variable(ipgNode)].result->divert_to(output);
1175 }
1176
1177 regionalizedVariableMap.PopRegion();
1178 pb.end();
1179
1180 /*
1181 * Add phi outputs
1182 */
1183 for (const auto & ipgNode : stronglyConnectedComponent)
1184 {
1185 auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1186 auto recursionVariable = recursionVariables[ipgNodeVariable];
1187 regionalizedVariableMap.GetTopVariableMap().insert(ipgNodeVariable, recursionVariable.output);
1188 if (requiresExport(*ipgNode))
1189 rvsdg::GraphExport::Create(*recursionVariable.output, ipgNodeVariable->name());
1190 }
1191}
1192
1193static std::unique_ptr<LlvmRvsdgModule>
1195 InterProceduralGraphModule & interProceduralGraphModule,
1197{
1198 auto rvsdgModule = LlvmRvsdgModule::Create(
1199 interProceduralGraphModule.source_filename(),
1200 interProceduralGraphModule.target_triple(),
1201 interProceduralGraphModule.data_layout());
1202 auto graph = &rvsdgModule->Rvsdg();
1203
1204 RegionalizedVariableMap regionalizedVariableMap(
1205 interProceduralGraphModule,
1206 graph->GetRootRegion());
1207
1208 auto stronglyConnectedComponents = interProceduralGraphModule.ipgraph().find_sccs();
1209 for (const auto & stronglyConnectedComponent : stronglyConnectedComponents)
1211 stronglyConnectedComponent,
1212 *graph,
1213 regionalizedVariableMap,
1215
1216 return rvsdgModule;
1217}
1218
1219std::unique_ptr<LlvmRvsdgModule>
1221 InterProceduralGraphModule & interProceduralGraphModule,
1223{
1224 InterProceduralGraphToRvsdgStatisticsCollector interProceduralGraphToRvsdgStatisticsCollector(
1226 interProceduralGraphModule.source_filename());
1227
1228 auto convertInterProceduralGraphModule =
1229 [&](InterProceduralGraphModule & interProceduralGraphModule)
1230 {
1232 interProceduralGraphModule,
1233 interProceduralGraphToRvsdgStatisticsCollector);
1234 };
1235
1236 auto rvsdgModule =
1237 interProceduralGraphToRvsdgStatisticsCollector.CollectInterProceduralGraphToRvsdgStatistics(
1238 convertInterProceduralGraphModule,
1239 interProceduralGraphModule);
1240
1241 return rvsdgModule;
1242}
1243
1244}
static jlm::util::StatisticsCollector statisticsCollector
AggregationNode * parent() noexcept
size_t nchildren() const noexcept
AggregationNode * child(size_t n) const noexcept
size_t index() const noexcept
static void normalize(AggregationNode &node)
static std::unique_ptr< AggregationStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
AggregationStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
void Start(const ControlFlowGraph &cfg) noexcept
~AggregationStatistics() override=default
static std::unique_ptr< AggregationTreeToLambdaStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
AggregationTreeToLambdaStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
T & Lookup(const AggregationNode &aggregationNode) const noexcept
~AnnotationStatistics() override=default
void Start(const AggregationNode &node) noexcept
static std::unique_ptr< AnnotationStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
AnnotationStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
const ThreeAddressCodeList & tacs() const noexcept
static std::unique_ptr< ControlFlowRestructuringStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
ControlFlowRestructuringStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
const tacsvector_t & tacs() const noexcept
Definition ipgraph.hpp:339
const Variable * value() const noexcept
Definition ipgraph.hpp:333
void Start(size_t numInitializationThreeAddressCodes) noexcept
~DataNodeToDeltaStatistics() override=default
static std::unique_ptr< DataNodeToDeltaStatistics > Create(const util::FilePath &sourceFileName, const std::string &dataNodeName)
DataNodeToDeltaStatistics(const util::FilePath &sourceFileName, const std::string &dataNodeName)
const std::string & name() const noexcept override
Definition ipgraph.cpp:192
const DataNodeInit * initialization() const noexcept
Definition ipgraph.hpp:413
size_t getAlignment() const noexcept
Definition ipgraph.hpp:395
const llvm::Linkage & linkage() const noexcept override
Definition ipgraph.cpp:211
const std::shared_ptr< const jlm::rvsdg::Type > & GetValueType() const noexcept
Definition ipgraph.hpp:380
bool constant() const noexcept
Definition ipgraph.hpp:401
const std::string & Section() const noexcept
Definition ipgraph.hpp:407
const llvm::Argument * argument(size_t index) const noexcept
size_t narguments() const noexcept
const std::string & name() const noexcept override
Definition ipgraph.cpp:149
llvm::ControlFlowGraph * cfg() const noexcept
Definition ipgraph.hpp:190
const llvm::Linkage & linkage() const noexcept override
Definition ipgraph.cpp:167
const AttributeSet & attributes() const noexcept
Definition ipgraph.hpp:229
const CallingConvention & callingConvention() const noexcept
Definition ipgraph.hpp:223
const std::shared_ptr< const rvsdg::FunctionType > & GetFunctionType() const noexcept
Definition ipgraph.hpp:208
const jlm::util::FilePath & source_filename() const noexcept
InterProceduralGraph & ipgraph() noexcept
const std::string & target_triple() const noexcept
const std::string & data_layout() const noexcept
virtual const llvm::Linkage & linkage() const noexcept=0
virtual bool hasBody() const noexcept=0
void CollectAggregationTreeToLambdaStatistics(const std::function< void()> &convertAggregationTreeToLambda, std::string functionName)
std::unique_ptr< LlvmRvsdgModule > CollectInterProceduralGraphToRvsdgStatistics(const std::function< std::unique_ptr< LlvmRvsdgModule >(InterProceduralGraphModule &)> &convertInterProceduralGraphModule, InterProceduralGraphModule &interProceduralGraphModule)
std::unique_ptr< AnnotationMap > CollectAnnotationStatistics(const std::function< std::unique_ptr< AnnotationMap >(const AggregationNode &)> &annotateAggregationTree, const AggregationNode &aggregationTreeRoot, std::string functionName)
rvsdg::Output * CollectDataNodeToDeltaStatistics(const std::function< rvsdg::Output *()> &convertDataNodeToDelta, std::string dataNodeName, size_t NumInitializationThreeAddressCodes)
std::unique_ptr< AggregationNode > CollectAggregationStatistics(const std::function< std::unique_ptr< AggregationNode >(ControlFlowGraph &)> &aggregateControlFlowGraph, ControlFlowGraph &cfg, std::string functionName)
void CollectControlFlowRestructuringStatistics(const std::function< void(ControlFlowGraph *)> &restructureControlFlowGraph, ControlFlowGraph &cfg, std::string functionName)
InterProceduralGraphToRvsdgStatisticsCollector(util::StatisticsCollector &statisticsCollector, util::FilePath sourceFileName)
static std::unique_ptr< InterProceduralGraphToRvsdgStatistics > Create(const util::FilePath &sourceFileName)
void Start(const InterProceduralGraphModule &interProceduralGraphModule) noexcept
InterProceduralGraphToRvsdgStatistics(const util::FilePath &sourceFileName)
std::vector< std::unordered_set< const InterProceduralGraphNode * > > find_sccs() const
Definition ipgraph.cpp:68
static std::unique_ptr< LlvmDeltaOperation > Create(std::shared_ptr< const rvsdg::Type > type, const std::string &name, const Linkage &linkage, std::string section, bool constant, const size_t alignment)
Definition delta.hpp:82
static LlvmGraphImport & createGlobalImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::Type > valueType, std::shared_ptr< const rvsdg::Type > importedType, std::string name, Linkage linkage, const bool isConstant, const size_t alignment)
static LlvmGraphImport & createFunctionImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::FunctionType > functionType, std::string name, Linkage linkage, CallingConvention callingConvention)
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static std::shared_ptr< const PointerType > Create()
Definition types.cpp:45
rvsdg::Region & GetRegion(size_t n) noexcept
llvm::VariableMap & VariableMap(size_t n) noexcept
std::vector< std::unique_ptr< llvm::VariableMap > > VariableMapStack_
const InterProceduralGraphModule & InterProceduralGraphModule_
RegionalizedVariableMap(const InterProceduralGraphModule &interProceduralGraphModule, rvsdg::Region &region)
const InterProceduralGraphModule & GetInterProceduralGraphModule() const noexcept
const rvsdg::SimpleOperation & operation() const noexcept
Definition tac.hpp:84
size_t nresults() const noexcept
Definition tac.hpp:103
const Variable * operand(size_t index) const noexcept
Definition tac.hpp:96
const ThreeAddressCodeVariable * result(size_t index) const noexcept
Definition tac.hpp:109
size_t noperands() const noexcept
Definition tac.hpp:90
static jlm::rvsdg::Output * Create(rvsdg::Region &region, std::shared_ptr< const jlm::rvsdg::Type > type)
bool contains(const Variable *v) const noexcept
void insert(const Variable *v, rvsdg::Output *o)
rvsdg::Output * lookup(const Variable *v) const
std::unordered_map< const Variable *, rvsdg::Output * > Map_
const jlm::rvsdg::Type & type() const noexcept
Definition variable.hpp:56
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
Definition delta.hpp:313
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
Definition gamma.hpp:161
static GraphExport & Create(Output &origin, std::string name)
Definition graph.cpp:62
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
rvsdg::Output * finalize(const std::vector< jlm::rvsdg::Output * > &results)
Definition lambda.cpp:147
std::vector< rvsdg::Output * > GetFunctionArguments() const
Definition lambda.cpp:58
ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Adds a context/free variable to the lambda node.
Definition lambda.cpp:132
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition lambda.cpp:141
rvsdg::Region * subregion() const noexcept
Definition lambda.hpp:138
LambdaOperation & GetOperation() const noexcept override
Definition lambda.cpp:52
static Output * Create(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
Definition control.hpp:236
virtual std::unique_ptr< Operation > copy() const =0
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:366
PhiNode * end()
Definition Phi.cpp:270
PhiNode::ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Definition Phi.cpp:251
PhiNode::FixVar AddFixVar(std::shared_ptr< const jlm::rvsdg::Type > type)
Definition Phi.cpp:257
void begin(rvsdg::Region *parent)
Definition Phi.hpp:355
rvsdg::Region * subregion() const noexcept
Definition Phi.hpp:349
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
static SimpleNode & Create(Region &region, std::unique_ptr< Operation > operation, const std::vector< rvsdg::Output * > &operands)
static ThetaNode * create(rvsdg::Region *parent)
Definition theta.hpp:73
bool isDemanded(Statistics::Id id) const noexcept
Checks if a statistics is demanded.
const StatisticsCollectorSettings & GetSettings() const noexcept
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
Statistics Interface.
util::Timer & GetTimer(const std::string &name)
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
util::Timer & AddTimer(std::string name)
void AddMeasurement(std::string name, T value)
void start() noexcept
Definition time.hpp:54
void stop() noexcept
Definition time.hpp:67
#define JLM_ASSERT(x)
Definition common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition common.hpp:43
Global memory state passed between functions.
static void ConvertStronglyConnectedComponent(const std::unordered_set< const InterProceduralGraphNode * > &stronglyConnectedComponent, rvsdg::Graph &graph, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static std::unique_ptr< AnnotationMap > AnnotateAggregationTree(const AggregationNode &aggregationTreeRoot, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static std::unique_ptr< LlvmRvsdgModule > ConvertInterProceduralGraphModule(InterProceduralGraphModule &interProceduralGraphModule, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
void destruct_ssa(ControlFlowGraph &cfg)
Definition ssa.cpp:18
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
static void ConvertBasicBlock(const ThreeAddressCodeList &basicBlock, rvsdg::Region &region, llvm::VariableMap &variableMap)
static void RestructureControlFlow(ControlFlowGraphNode &, ControlFlowGraphNode &, std::vector< TailControlledLoop > &)
static void RestructureControlFlowGraph(ControlFlowGraph &controlFlowGraph, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
bool isDiscardableIfUnused(const Linkage linkage)
Definition Linkage.hpp:44
static void ConvertThreeAddressCode(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &region, llvm::VariableMap &variableMap)
static void Convert(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &region, llvm::VariableMap &variableMap)
static rvsdg::Output * ConvertFunctionNode(const FunctionNode &functionNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static rvsdg::Output * ConvertDataNodeInitialization(const DataNodeInit &init, rvsdg::Region &region, RegionalizedVariableMap &regionalizedVariableMap)
static void ConvertAggregationNode(const AggregationNode &aggregationNode, const AnnotationMap &demandMap, rvsdg::LambdaNode &lambdaNode, RegionalizedVariableMap &regionalizedVariableMap)
static void ConvertSelect(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &variableMap)
static rvsdg::Output * ConvertDataNode(const DataNode &dataNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertBranch(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &)
static rvsdg::Output * ConvertAggregationTreeToLambda(const AggregationNode &aggregationTreeRoot, const AnnotationMap &demandMap, RegionalizedVariableMap &scopedVariableMap, const std::string &functionName, std::shared_ptr< const rvsdg::FunctionType > functionType, const Linkage &functionLinkage, const CallingConvention &functionCallingConvention, const AttributeSet &functionAttributes, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
void straighten(ControlFlowGraph &cfg)
static bool requiresExport(const InterProceduralGraphNode &ipgNode)
size_t ntacs(const AggregationNode &root)
std::unique_ptr< AnnotationMap > Annotate(const AggregationNode &aggregationTreeRoot)
void purge(ControlFlowGraph &cfg)
Remove all basic blocks without instructions.
static rvsdg::Output * ConvertControlFlowGraph(const FunctionNode &functionNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static rvsdg::Output * ConvertInterProceduralGraphNode(const InterProceduralGraphNode &ipgNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static std::unique_ptr< AggregationNode > AggregateControlFlowGraph(ControlFlowGraph &controlFlowGraph, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertAssignment(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &variableMap)
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
Definition region.cpp:808
rvsdg::Output * inner
Access to bound object in subregion.
Definition lambda.hpp:117
rvsdg::Output * inner
Access to bound object in subregion.
Definition Phi.hpp:89