Jlm
Loading...
Searching...
No Matches
NodeReduction.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
17#include <jlm/rvsdg/binary.hpp>
18#include <jlm/rvsdg/gamma.hpp>
22#include <jlm/rvsdg/theta.hpp>
25
26namespace jlm::llvm
27{
28
29void
31{
32 AddMeasurement(Label::NumRvsdgNodesBefore, rvsdg::nnodes(&graph.GetRootRegion()));
33 AddMeasurement(Label::NumRvsdgInputsBefore, rvsdg::ninputs(&graph.GetRootRegion()));
34 AddTimer(Label::Timer).start();
35}
36
37void
39{
40 AddMeasurement(Label::NumRvsdgNodesAfter, rvsdg::nnodes(&graph.GetRootRegion()));
41 AddMeasurement(Label::NumRvsdgInputsAfter, rvsdg::ninputs(&graph.GetRootRegion()));
42
43 AddMeasurement(NumRegionsLabel_, getNumRegions());
44 AddMeasurement(NumTotalRegionIterationsLabel_, getTotalIterations());
45 AddMeasurement(MaxIterationsPerRegionLabel_, getMaxIterationsPerRegion());
46
47 auto & counters = getReductionCounters();
48 AddMeasurement("#LoadNonVolatileReductions", counters.numLoadNonVolatileReductions);
49 AddMeasurement("#StoreNonVolatileReductions", counters.numStoreNonVolatileReductions);
50 AddMeasurement("#MemoryStateMergeReductions", counters.numMemoryStateMergeReductions);
51 AddMeasurement("#MemoryStateJoinReductions", counters.numMemoryStateJoinReductions);
52 AddMeasurement("#MemoryStateSplitReductions", counters.numMemoryStateSplitReductions);
53 AddMeasurement(
54 "#LambdaExitMemoryStateMergeReductions",
55 counters.numLambdaExitMemoryStateMergeReductions);
56 AddMeasurement("#MatchReductions", counters.numMatchReductions);
57 AddMeasurement("#SExtReductions", counters.numSExtReductions);
58 AddMeasurement("#ZExtReductions", counters.numZExtReductions);
59 AddMeasurement("#TruncReductions", counters.numTruncReductions);
60 AddMeasurement("#FPExtReductions", counters.numFPExtReductions);
61 AddMeasurement("#FPTruncReductions", counters.numFPTruncReductions);
62 AddMeasurement("#IntegerEqReductions", counters.numIntegerEqReductions);
63 AddMeasurement("#IntegerNeReductions", counters.numIntegerNeReductions);
64 AddMeasurement("#IntegerSgeReductions", counters.numIntegerSgeReductions);
65 AddMeasurement("#IntegerSgtReductions", counters.numIntegerSgtReductions);
66 AddMeasurement("#IntegerSleReductions", counters.numIntegerSleReductions);
67 AddMeasurement("#IntegerSltReductions", counters.numIntegerSltReductions);
68 AddMeasurement("#IntegerUgeReductions", counters.numIntegerUgeReductions);
69 AddMeasurement("#IntegerUgtReductions", counters.numIntegerUgtReductions);
70 AddMeasurement("#IntegerUleReductions", counters.numIntegerUleReductions);
71 AddMeasurement("#IntegerUltReductions", counters.numIntegerUltReductions);
72
73 AddMeasurement("#IntegerAddReductions", counters.numIntegerAddReductions);
74 AddMeasurement("#IntegerSubReductions", counters.numIntegerSubReductions);
75 AddMeasurement("#IntegerMulReductions", counters.numIntegerMulReductions);
76 AddMeasurement("#IntegerSDivReductions", counters.numIntegerSDivReductions);
77 AddMeasurement("#IntegerUDivReductions", counters.numIntegerUDivReductions);
78 AddMeasurement("#IntegerSRemReductions", counters.numIntegerSRemReductions);
79 AddMeasurement("#IntegerURemReductions", counters.numIntegerURemReductions);
80 AddMeasurement("#IntegerAShrReductions", counters.numIntegerAShrReductions);
81 AddMeasurement("#IntegerShlReductions", counters.numIntegerShlReductions);
82 AddMeasurement("#IntegerLShrReductions", counters.numIntegerLShrReductions);
83 AddMeasurement("#IntegerAndReductions", counters.numIntegerAndReductions);
84 AddMeasurement("#IntegerOrReductions", counters.numIntegerOrReductions);
85 AddMeasurement("#IntegerXorReductions", counters.numIntegerXorReductions);
86
87 AddMeasurement("#FPBinaryOpReductions", counters.numFPBinaryOpReductions);
88
89 AddMeasurement("#PtrCmpReductions", counters.numPtrCmpReductions);
90 AddMeasurement("#GetElementPtrReductions", counters.numGetElementPtrReductions);
91 AddMeasurement("#FCmpReductions", counters.numFCmpReductions);
92 AddMeasurement("#MemoryHoistBarrierReductions", counters.numMemoryHoistBarrierReductions);
93 AddMeasurement("#BinaryReductions", counters.numBinaryReductions);
94
95 AddMeasurement("#GammaReductions", counters.numGammaReductions);
96 AddMeasurement("#ThetaReductions", counters.numThetaReductions);
97
98 GetTimer(Label::Timer).stop();
99}
100
101bool
102NodeReduction::Statistics::AddIteration(const rvsdg::Region & region, size_t numIterations)
103{
104 const auto it = NumIterations_.find(&region);
105 NumIterations_[&region] = numIterations;
106 return it != NumIterations_.end();
107}
108
109std::optional<size_t>
111{
112 if (const auto it = NumIterations_.find(&region); it != NumIterations_.end())
113 {
114 return it->second;
115 }
116
117 return std::nullopt;
118}
119
120size_t
122{
123 return NumIterations_.size();
124}
125
126size_t
128{
129 size_t sum = 0;
130 for (auto [_, numIterations] : NumIterations_)
131 {
132 sum += numIterations;
133 }
134
135 return sum;
136}
137
138size_t
140{
141 return std::max_element(
142 NumIterations_.begin(),
143 NumIterations_.end(),
144 [](const auto & p1, const auto & p2)
145 {
146 return p1.second < p2.second;
147 })
148 ->second;
149}
150
151static std::vector<rvsdg::NodeNormalization<rvsdg::MatchOperation>>
153
154static std::vector<rvsdg::NodeNormalization<SExtOperation>>
156
157static std::vector<rvsdg::NodeNormalization<ZExtOperation>>
159
160static std::vector<rvsdg::NodeNormalization<TruncOperation>>
162
163static std::vector<rvsdg::NodeNormalization<FPExtOperation>>
165
166static std::vector<rvsdg::NodeNormalization<FPTruncOperation>>
168
169static std::vector<rvsdg::NodeNormalization<IntegerEqOperation>> integerEqNormalizations(
171
172static std::vector<rvsdg::NodeNormalization<IntegerNeOperation>> integerNeNormalizations(
174
175static std::vector<rvsdg::NodeNormalization<IntegerSgeOperation>> integerSgeNormalizations(
177
178static std::vector<rvsdg::NodeNormalization<IntegerSgtOperation>> integerSgtNormalizations(
180
181static std::vector<rvsdg::NodeNormalization<IntegerSleOperation>> integerSleNormalizations(
183
184static std::vector<rvsdg::NodeNormalization<IntegerSltOperation>> integerSltNormalizations(
186
187static std::vector<rvsdg::NodeNormalization<IntegerUgeOperation>> integerUgeNormalizations(
189
190static std::vector<rvsdg::NodeNormalization<IntegerUgtOperation>> integerUgtNormalizations(
192
193static std::vector<rvsdg::NodeNormalization<IntegerUleOperation>> integerUleNormalizations(
195
196static std::vector<rvsdg::NodeNormalization<IntegerUltOperation>> integerUltNormalizations(
198
199static std::vector<rvsdg::NodeNormalization<IntegerAddOperation>>
201
202static std::vector<rvsdg::NodeNormalization<IntegerSubOperation>> integerSubNormalizations(
204
205static std::vector<rvsdg::NodeNormalization<IntegerMulOperation>>
207
208static std::vector<rvsdg::NodeNormalization<IntegerSDivOperation>>
210
211static std::vector<rvsdg::NodeNormalization<IntegerUDivOperation>>
213
214static std::vector<rvsdg::NodeNormalization<IntegerSRemOperation>>
216
217static std::vector<rvsdg::NodeNormalization<IntegerURemOperation>>
219
220static std::vector<rvsdg::NodeNormalization<IntegerAShrOperation>>
222
223static std::vector<rvsdg::NodeNormalization<IntegerShlOperation>>
225
226static std::vector<rvsdg::NodeNormalization<IntegerLShrOperation>>
228
229static std::vector<rvsdg::NodeNormalization<IntegerAndOperation>>
231
232static std::vector<rvsdg::NodeNormalization<IntegerOrOperation>> integerOrNormalizations(
234
235static std::vector<rvsdg::NodeNormalization<IntegerXorOperation>>
237
238static std::vector<rvsdg::NodeNormalization<FBinaryOperation>>
240
241static std::vector<rvsdg::NodeNormalization<LoadNonVolatileOperation>>
247
248static std::vector<rvsdg::NodeNormalization<StoreNonVolatileOperation>>
255
256static std::vector<rvsdg::NodeNormalization<MemoryStateMergeOperation>>
261
262static std::vector<rvsdg::NodeNormalization<MemoryStateJoinOperation>>
265
266static std::vector<rvsdg::NodeNormalization<MemoryStateSplitOperation>>
270
271static std::vector<rvsdg::NodeNormalization<LambdaExitMemoryStateMergeOperation>>
276
277static std::vector<rvsdg::NodeNormalization<PtrCmpOperation>>
280
281static std::vector<rvsdg::NodeNormalization<GetElementPtrOperation>>
283
284static std::vector<rvsdg::NodeNormalization<FCmpOperation>>
286
287static std::vector<rvsdg::NodeNormalization<MemoryHoistBarrierOperation>>
290
291static std::vector<rvsdg::NodeNormalization<rvsdg::BinaryOperation>>
293
294template<typename TOperation>
296createNormalizer(const std::vector<rvsdg::NodeNormalization<TOperation>> & nodeNormalizations)
297{
298 return [&](const TOperation & operation, const std::vector<rvsdg::Output *> & operands)
299 {
300 return rvsdg::NormalizeSequence<TOperation>(nodeNormalizations, operation, operands);
301 };
302}
303
304template<class TOperation>
305static bool
307 rvsdg::SimpleNode & simpleNode,
308 const std::vector<rvsdg::NodeNormalization<TOperation>> & normalizations,
309 size_t & counter)
310{
311 auto normalizer = createNormalizer(normalizations);
312 const bool reductionPerformed = rvsdg::ReduceNode<TOperation>(normalizer, simpleNode);
313 if (reductionPerformed)
314 counter += 1;
315 return reductionPerformed;
316}
317
318NodeReduction::~NodeReduction() noexcept = default;
319
323
324void
326 rvsdg::RvsdgModule & rvsdgModule,
328{
329 const auto & graph = rvsdgModule.Rvsdg();
330
331 Statistics_ = Statistics::Create(rvsdgModule.SourceFilePath().value());
332 Statistics_->Start(graph);
333
334 ReduceNodesInRegion(graph.GetRootRegion());
335
336 Statistics_->End(graph);
338}
339
340void
342{
343 bool reductionPerformed = false;
344 size_t numIterations = 0;
345 do
346 {
347 numIterations++;
348 reductionPerformed = false;
349
350 for (const auto node : rvsdg::TopDownTraverser(&region))
351 {
352 MatchTypeOrFail(
353 *node,
354 [this, &reductionPerformed](rvsdg::StructuralNode & structuralNode)
355 {
356 reductionPerformed |= ReduceStructuralNode(structuralNode);
357 },
358 [this, &reductionPerformed](rvsdg::SimpleNode & simpleNode)
359 {
360 reductionPerformed |= ReduceSimpleNode(simpleNode);
361 });
362 }
363
364 if (reductionPerformed)
365 {
366 // Let's remove all dead nodes in this region to avoid reductions on
367 // dead nodes in the next iteration.
368 region.prune(false);
369 }
370 } while (reductionPerformed);
371
372 Statistics_->AddIteration(region, numIterations);
373}
374
375bool
377{
378 const bool reductionPerformed = rvsdg::MatchTypeWithDefault(
379 structuralNode,
380 [this](rvsdg::GammaNode & gammaNode)
381 {
382 return ReduceGammaNode(gammaNode);
383 },
384 [this](rvsdg::ThetaNode & thetaNode)
385 {
386 return reduceThetaNode(thetaNode);
387 },
388 []()
389 {
390 return false;
391 });
392
393 if (reductionPerformed)
394 {
395 // We cannot go through the subregions as the structural node might already have been removed.
396 return true;
397 }
398
399 // Reduce all nodes in the subregions
400 for (size_t n = 0; n < structuralNode.nsubregions(); n++)
401 {
402 const auto subregion = structuralNode.subregion(n);
403 ReduceNodesInRegion(*subregion);
404 }
405
406 return false;
407}
408
409bool
411{
412 // FIXME: We can not apply the reduction below due to a bug. See github issue #303
413 // rvsdg::ReduceGammaControlConstant
414
415 const bool reductionPerformed = reduceStaticallyKnownPredicate(gammaNode);
416 if (reductionPerformed)
417 Statistics_->getReductionCounters().numGammaReductions++;
418
419 return reductionPerformed;
420}
421
422bool
424{
425 const bool reductionPerformed = rvsdg::ThetaNode::reduceStaticallyKnownPredicate(thetaNode);
426 if (reductionPerformed)
427 Statistics_->getReductionCounters().numThetaReductions++;
428
429 return reductionPerformed;
430}
431
432bool
434{
435 if (is<LoadNonVolatileOperation>(&simpleNode))
436 {
437 return reduceSimpleNode<LoadNonVolatileOperation>(
438 simpleNode,
440 Statistics_->getReductionCounters().numLoadNonVolatileReductions);
441 }
442 if (is<StoreNonVolatileOperation>(&simpleNode))
443 {
444 return reduceSimpleNode<StoreNonVolatileOperation>(
445 simpleNode,
447 Statistics_->getReductionCounters().numStoreNonVolatileReductions);
448 }
449 if (is<MemoryStateMergeOperation>(&simpleNode))
450 {
451 return reduceSimpleNode<MemoryStateMergeOperation>(
452 simpleNode,
454 Statistics_->getReductionCounters().numMemoryStateMergeReductions);
455 }
456 if (is<MemoryStateJoinOperation>(&simpleNode))
457 {
458 return reduceSimpleNode<MemoryStateJoinOperation>(
459 simpleNode,
461 Statistics_->getReductionCounters().numMemoryStateJoinReductions);
462 }
463 if (is<MemoryStateSplitOperation>(&simpleNode))
464 {
465 return reduceSimpleNode<MemoryStateSplitOperation>(
466 simpleNode,
468 Statistics_->getReductionCounters().numMemoryStateSplitReductions);
469 }
470 if (is<LambdaExitMemoryStateMergeOperation>(&simpleNode))
471 {
472 return reduceSimpleNode<LambdaExitMemoryStateMergeOperation>(
473 simpleNode,
475 Statistics_->getReductionCounters().numLambdaExitMemoryStateMergeReductions);
476 }
477 if (is<rvsdg::MatchOperation>(&simpleNode))
478 {
479 return reduceSimpleNode<rvsdg::MatchOperation>(
480 simpleNode,
482 Statistics_->getReductionCounters().numMatchReductions);
483 }
484 if (is<SExtOperation>(&simpleNode))
485 {
486 return reduceSimpleNode<SExtOperation>(
487 simpleNode,
489 Statistics_->getReductionCounters().numSExtReductions);
490 }
491 if (is<ZExtOperation>(&simpleNode))
492 {
493 return reduceSimpleNode<ZExtOperation>(
494 simpleNode,
496 Statistics_->getReductionCounters().numZExtReductions);
497 }
498 if (is<TruncOperation>(&simpleNode))
499 {
500 return reduceSimpleNode<TruncOperation>(
501 simpleNode,
503 Statistics_->getReductionCounters().numTruncReductions);
504 }
505 if (is<FPExtOperation>(&simpleNode))
506 {
507 return reduceSimpleNode<FPExtOperation>(
508 simpleNode,
510 Statistics_->getReductionCounters().numFPExtReductions);
511 }
512 if (is<FPTruncOperation>(&simpleNode))
513 {
514 return reduceSimpleNode<FPTruncOperation>(
515 simpleNode,
517 Statistics_->getReductionCounters().numFPTruncReductions);
518 }
519 if (is<IntegerEqOperation>(&simpleNode))
520 {
521 return reduceSimpleNode<IntegerEqOperation>(
522 simpleNode,
524 Statistics_->getReductionCounters().numIntegerEqReductions);
525 }
526 if (is<IntegerNeOperation>(&simpleNode))
527 {
528 return reduceSimpleNode<IntegerNeOperation>(
529 simpleNode,
531 Statistics_->getReductionCounters().numIntegerNeReductions);
532 }
533 if (is<IntegerSgeOperation>(&simpleNode))
534 {
535 return reduceSimpleNode<IntegerSgeOperation>(
536 simpleNode,
538 Statistics_->getReductionCounters().numIntegerSgeReductions);
539 }
540 if (is<IntegerSgtOperation>(&simpleNode))
541 {
542 return reduceSimpleNode<IntegerSgtOperation>(
543 simpleNode,
545 Statistics_->getReductionCounters().numIntegerSgtReductions);
546 }
547 if (is<IntegerSleOperation>(&simpleNode))
548 {
549 return reduceSimpleNode<IntegerSleOperation>(
550 simpleNode,
552 Statistics_->getReductionCounters().numIntegerSleReductions);
553 }
554 if (is<IntegerSltOperation>(&simpleNode))
555 {
556 return reduceSimpleNode<IntegerSltOperation>(
557 simpleNode,
559 Statistics_->getReductionCounters().numIntegerSltReductions);
560 }
561 if (is<IntegerUgeOperation>(&simpleNode))
562 {
563 return reduceSimpleNode<IntegerUgeOperation>(
564 simpleNode,
566 Statistics_->getReductionCounters().numIntegerUgeReductions);
567 }
568 if (is<IntegerUgtOperation>(&simpleNode))
569 {
570 return reduceSimpleNode<IntegerUgtOperation>(
571 simpleNode,
573 Statistics_->getReductionCounters().numIntegerUgtReductions);
574 }
575 if (is<IntegerUleOperation>(&simpleNode))
576 {
577 return reduceSimpleNode<IntegerUleOperation>(
578 simpleNode,
580 Statistics_->getReductionCounters().numIntegerUleReductions);
581 }
582 if (is<IntegerUltOperation>(&simpleNode))
583 {
584 return reduceSimpleNode<IntegerUltOperation>(
585 simpleNode,
587 Statistics_->getReductionCounters().numIntegerUltReductions);
588 }
589 if (is<IntegerAddOperation>(&simpleNode))
590 {
591 return reduceSimpleNode<IntegerAddOperation>(
592 simpleNode,
594 Statistics_->getReductionCounters().numIntegerAddReductions);
595 }
596 if (is<IntegerSubOperation>(&simpleNode))
597 {
598 return reduceSimpleNode<IntegerSubOperation>(
599 simpleNode,
601 Statistics_->getReductionCounters().numIntegerSubReductions);
602 }
603 if (is<IntegerMulOperation>(&simpleNode))
604 {
605 return reduceSimpleNode<IntegerMulOperation>(
606 simpleNode,
608 Statistics_->getReductionCounters().numIntegerMulReductions);
609 }
610 if (is<IntegerSDivOperation>(&simpleNode))
611 {
612 return reduceSimpleNode<IntegerSDivOperation>(
613 simpleNode,
615 Statistics_->getReductionCounters().numIntegerSDivReductions);
616 }
617 if (is<IntegerUDivOperation>(&simpleNode))
618 {
619 return reduceSimpleNode<IntegerUDivOperation>(
620 simpleNode,
622 Statistics_->getReductionCounters().numIntegerUDivReductions);
623 }
624 if (is<IntegerSRemOperation>(&simpleNode))
625 {
626 return reduceSimpleNode<IntegerSRemOperation>(
627 simpleNode,
629 Statistics_->getReductionCounters().numIntegerSRemReductions);
630 }
631 if (is<IntegerURemOperation>(&simpleNode))
632 {
633 return reduceSimpleNode<IntegerURemOperation>(
634 simpleNode,
636 Statistics_->getReductionCounters().numIntegerURemReductions);
637 }
638 if (is<IntegerAShrOperation>(&simpleNode))
639 {
640 return reduceSimpleNode<IntegerAShrOperation>(
641 simpleNode,
643 Statistics_->getReductionCounters().numIntegerAShrReductions);
644 }
645 if (is<IntegerShlOperation>(&simpleNode))
646 {
647 return reduceSimpleNode<IntegerShlOperation>(
648 simpleNode,
650 Statistics_->getReductionCounters().numIntegerShlReductions);
651 }
652 if (is<IntegerLShrOperation>(&simpleNode))
653 {
654 return reduceSimpleNode<IntegerLShrOperation>(
655 simpleNode,
657 Statistics_->getReductionCounters().numIntegerLShrReductions);
658 }
659 if (is<IntegerAndOperation>(&simpleNode))
660 {
661 return reduceSimpleNode<IntegerAndOperation>(
662 simpleNode,
664 Statistics_->getReductionCounters().numIntegerAndReductions);
665 }
666 if (is<IntegerOrOperation>(&simpleNode))
667 {
668 return reduceSimpleNode<IntegerOrOperation>(
669 simpleNode,
671 Statistics_->getReductionCounters().numIntegerOrReductions);
672 }
673 if (is<IntegerXorOperation>(&simpleNode))
674 {
675 return reduceSimpleNode<IntegerXorOperation>(
676 simpleNode,
678 Statistics_->getReductionCounters().numIntegerXorReductions);
679 }
680 if (is<FBinaryOperation>(&simpleNode))
681 {
682 return reduceSimpleNode<FBinaryOperation>(
683 simpleNode,
685 Statistics_->getReductionCounters().numFPBinaryOpReductions);
686 }
687 if (is<PtrCmpOperation>(&simpleNode))
688 {
689 return reduceSimpleNode<PtrCmpOperation>(
690 simpleNode,
692 Statistics_->getReductionCounters().numPtrCmpReductions);
693 }
694 if (is<GetElementPtrOperation>(&simpleNode))
695 {
696 return reduceSimpleNode<GetElementPtrOperation>(
697 simpleNode,
699 Statistics_->getReductionCounters().numGetElementPtrReductions);
700 }
701 if (is<FCmpOperation>(&simpleNode))
702 {
703 return reduceSimpleNode<FCmpOperation>(
704 simpleNode,
706 Statistics_->getReductionCounters().numFCmpReductions);
707 }
708 if (is<MemoryHoistBarrierOperation>(&simpleNode))
709 {
710 return reduceSimpleNode<MemoryHoistBarrierOperation>(
711 simpleNode,
713 Statistics_->getReductionCounters().numMemoryHoistBarrierReductions);
714 }
715 if (is<rvsdg::BinaryOperation>(&simpleNode))
716 {
717 return reduceSimpleNode<rvsdg::BinaryOperation>(
718 simpleNode,
720 Statistics_->getReductionCounters().numBinaryReductions);
721 }
722
723 return false;
724}
725
726}
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FBinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const FCmpOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstant(const FPExtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstant(const FPTruncOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdempotent(const GetElementPtrOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAShrOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAddOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerAndOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerEqOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerEqOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerLShrOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerMulOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerNeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerNeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerOrOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdempotent(const IntegerOrOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSDivOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSRemOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerSgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerSgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerShlOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerSleOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSleOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerSltOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSltOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerSubOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeAdditiveInverse(const IntegerSubOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUDivOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerURemOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerUgeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerUgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUgtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerUleOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUleOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const IntegerUltOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerUltOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstants(const IntegerXorOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadFromAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeStoreToAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeAlloca(const LambdaExitMemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadStoreState(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
If the producer of a load's address is an alloca operation, then we can remove all state edges origin...
Definition Load.cpp:320
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateStates(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Remove duplicated state operands.
Definition Load.cpp:331
static std::optional< std::vector< rvsdg::Output * > > normalizeMemoryHoistBarrierAddress(const LoadNonVolatileOperation &loadOperation, const std::vector< rvsdg::Output * > &operands)
Redirect the address operand of the LoadNonVolatileOperation node from an MemoryHoistBarrierOperation...
Definition Load.cpp:367
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadAlloca(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
If the producer of a load's address is an alloca operation, then we can remove all state edges origin...
Definition Load.cpp:309
static std::optional< std::vector< rvsdg::Output * > > NormalizeLoadStore(const LoadNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Forwards the value from a store operation.
Definition Load.cpp:248
static std::optional< std::vector< rvsdg::Output * > > normalizeNestedMemoryHoistBarriers(const MemoryHoistBarrierOperation &lowerMhbOp, const std::vector< rvsdg::Output * > &operands)
Definition IOBarrier.cpp:56
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateJoinOperation.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateJoinOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateJoinOperation as it has only a single operand, i.e., no joining is performed.
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedMerges(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested merges into a single merge.
static std::optional< std::vector< rvsdg::Output * > > NormalizeMergeSplit(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single merge.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleOperand(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateMergeOperation as it has only a single operand, i.e., no merging is performed.
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateOperands(const MemoryStateMergeOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes duplicated operands from the MemoryStateMergeOperation.
static std::optional< std::vector< rvsdg::Output * > > NormalizeNestedSplits(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Fuses nested splits into a single split.
static std::optional< std::vector< rvsdg::Output * > > NormalizeSingleResult(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes the MemoryStateSplitOperation as it has only a single result, i.e., no splitting is performed...
static std::optional< std::vector< rvsdg::Output * > > NormalizeSplitMerge(const MemoryStateSplitOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes an idempotent split-merge pair.
size_t getTotalIterations() const noexcept
size_t getNumRegions() const noexcept
bool AddIteration(const rvsdg::Region &region, size_t numIterations)
size_t getMaxIterationsPerRegion() const noexcept
void End(const rvsdg::Graph &graph) noexcept
std::unordered_map< const rvsdg::Region *, size_t > NumIterations_
void Start(const rvsdg::Graph &graph) noexcept
static std::unique_ptr< Statistics > Create(const util::FilePath &sourceFile)
std::optional< size_t > GetNumIterations(const rvsdg::Region &region) const noexcept
void ReduceNodesInRegion(rvsdg::Region &region)
std::unique_ptr< Statistics > Statistics_
bool reduceThetaNode(rvsdg::ThetaNode &thetaNode)
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
bool ReduceStructuralNode(rvsdg::StructuralNode &structuralNode)
bool ReduceGammaNode(rvsdg::GammaNode &gammaNode)
bool ReduceSimpleNode(rvsdg::SimpleNode &simpleNode)
~NodeReduction() noexcept override
static std::optional< std::vector< rvsdg::Output * > > normalizeIdenticalOperands(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeNullPointerComparison(const PtrCmpOperation &ptrCmpOperation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstant(const SExtOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > normalizeStoreStore(const StoreNonVolatileOperation &store2Op, const std::vector< rvsdg::Output * > &operands)
Removes a duplicated store to the same address.
Definition Store.cpp:174
static std::optional< std::vector< rvsdg::Output * > > NormalizeStoreMux(const StoreNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Swaps a memory state merge operation and a store operation.
Definition Store.cpp:163
static std::optional< std::vector< rvsdg::Output * > > normalizeMemoryHoistBarrierAddress(const StoreNonVolatileOperation &storeOperation, const std::vector< rvsdg::Output * > &operands)
Redirect the address operand of the StoreNonVolatileOperation node from an MemoryHoistBarrierOperatio...
Definition Store.cpp:279
static std::optional< std::vector< rvsdg::Output * > > normalizeStoreAllocaSingleUser(const StoreNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Definition Store.cpp:320
static std::optional< std::vector< rvsdg::Output * > > NormalizeStoreAlloca(const StoreNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Removes unnecessary state from a store node when its address originates directly from an alloca node.
Definition Store.cpp:230
static std::optional< std::vector< rvsdg::Output * > > NormalizeDuplicateStates(const StoreNonVolatileOperation &operation, const std::vector< rvsdg::Output * > &operands)
Remove duplicated state operands.
Definition Store.cpp:241
static std::optional< std::vector< rvsdg::Output * > > foldConstant(const TruncOperation &operation, const std::vector< rvsdg::Output * > &operands)
static std::optional< std::vector< rvsdg::Output * > > foldConstant(const ZExtOperation &operation, const std::vector< rvsdg::Output * > &operands)
Conditional operator / pattern matching.
Definition gamma.hpp:99
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
void prune(bool recursive)
Definition region.cpp:326
const std::optional< util::FilePath > & SourceFilePath() const noexcept
Graph & Rvsdg() noexcept
rvsdg::Region * subregion(size_t index) const noexcept
size_t nsubregions() const noexcept
static bool reduceStaticallyKnownPredicate(Node &node)
Definition theta.cpp:207
Transformation(std::string_view Name)
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
Global memory state passed between functions.
static std::vector< rvsdg::NodeNormalization< IntegerLShrOperation > > integerLShrNormalizations({ IntegerLShrOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerAndOperation > > integerAndNormalizations({ IntegerAndOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< GetElementPtrOperation > > getElementPtrNormalizations({ GetElementPtrOperation::normalizeIdempotent })
static std::vector< rvsdg::NodeNormalization< IntegerAddOperation > > integerAddNormalizations({ IntegerAddOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerXorOperation > > integerXorNormalizations({ IntegerXorOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerEqOperation > > integerEqNormalizations({ IntegerEqOperation::foldConstants, IntegerEqOperation::normalizeIdenticalOperands })
static bool reduceSimpleNode(rvsdg::SimpleNode &simpleNode, const std::vector< rvsdg::NodeNormalization< TOperation > > &normalizations, size_t &counter)
static std::vector< rvsdg::NodeNormalization< IntegerAShrOperation > > integerAShrNormalizations({ IntegerAShrOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< rvsdg::MatchOperation > > matchOperationNormalizations({ foldMatchOperationWithConstant })
static std::vector< rvsdg::NodeNormalization< IntegerSgtOperation > > integerSgtNormalizations({ IntegerSgtOperation::foldConstants, IntegerSgtOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< IntegerShlOperation > > integerShlNormalizations({ IntegerShlOperation::foldConstants })
static util::StatisticsCollector statisticsCollector
static std::vector< rvsdg::NodeNormalization< LoadNonVolatileOperation > > loadNonVolatileNormalizations({ LoadNonVolatileOperation::NormalizeLoadStore, LoadNonVolatileOperation::NormalizeLoadAlloca, LoadNonVolatileOperation::NormalizeDuplicateStates, LoadNonVolatileOperation::NormalizeLoadStoreState, LoadNonVolatileOperation::normalizeMemoryHoistBarrierAddress })
static std::vector< rvsdg::NodeNormalization< IntegerSleOperation > > integerSleNormalizations({ IntegerSleOperation::foldConstants, IntegerSleOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< IntegerSRemOperation > > integerSRemNormalizations({ IntegerSRemOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< rvsdg::BinaryOperation > > binaryOperationNormalizations({ rvsdg::NormalizeBinaryOperation })
static std::vector< rvsdg::NodeNormalization< SExtOperation > > sextOperationNormalizations({ SExtOperation::foldConstant })
static std::vector< rvsdg::NodeNormalization< IntegerSubOperation > > integerSubNormalizations({ IntegerSubOperation::normalizeAdditiveInverse, IntegerSubOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerUleOperation > > integerUleNormalizations({ IntegerUleOperation::foldConstants, IntegerUleOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< IntegerURemOperation > > integerURemNormalizations({ IntegerURemOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< MemoryHoistBarrierOperation > > memoryHoistBarrierNormalizations({ MemoryHoistBarrierOperation::normalizeNestedMemoryHoistBarriers })
static std::vector< rvsdg::NodeNormalization< MemoryStateJoinOperation > > memoryStateJoinNormalizations({ MemoryStateJoinOperation::NormalizeSingleOperand, MemoryStateJoinOperation::NormalizeDuplicateOperands })
static std::vector< rvsdg::NodeNormalization< LambdaExitMemoryStateMergeOperation > > lambdaExitMemoryStateMergeNormalizations({ LambdaExitMemoryStateMergeOperation::NormalizeLoadFromAlloca, LambdaExitMemoryStateMergeOperation::NormalizeStoreToAlloca, LambdaExitMemoryStateMergeOperation::NormalizeAlloca })
static std::vector< rvsdg::NodeNormalization< IntegerUgtOperation > > integerUgtNormalizations({ IntegerUgtOperation::foldConstants, IntegerUgtOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< IntegerMulOperation > > integerMulNormalizations({ IntegerMulOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< FCmpOperation > > fCmpNormalizations({ FCmpOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerSltOperation > > integerSltNormalizations({ IntegerSltOperation::foldConstants, IntegerSltOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< StoreNonVolatileOperation > > storeNonVolatileNormalizations({ StoreNonVolatileOperation::NormalizeStoreMux, StoreNonVolatileOperation::normalizeStoreStore, StoreNonVolatileOperation::NormalizeStoreAlloca, StoreNonVolatileOperation::NormalizeDuplicateStates, StoreNonVolatileOperation::normalizeMemoryHoistBarrierAddress, StoreNonVolatileOperation::normalizeStoreAllocaSingleUser })
static std::vector< rvsdg::NodeNormalization< FBinaryOperation > > fpBinaryOpNormalizations({ FBinaryOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerSDivOperation > > integerSDivNormalizations({ IntegerSDivOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerUgeOperation > > integerUgeNormalizations({ IntegerUgeOperation::foldConstants, IntegerUgeOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< MemoryStateMergeOperation > > memoryStateMergeNormalizations({ MemoryStateMergeOperation::NormalizeSingleOperand, MemoryStateMergeOperation::NormalizeDuplicateOperands, MemoryStateMergeOperation::NormalizeNestedMerges, MemoryStateMergeOperation::NormalizeMergeSplit })
static std::vector< rvsdg::NodeNormalization< PtrCmpOperation > > ptrCmpNormalizations({ PtrCmpOperation::normalizeNullPointerComparison, PtrCmpOperation::normalizeIdenticalOperands })
static std::vector< rvsdg::NodeNormalization< ZExtOperation > > zextOperationNormalizations({ ZExtOperation::foldConstant })
static std::vector< rvsdg::NodeNormalization< IntegerSgeOperation > > integerSgeNormalizations({ IntegerSgeOperation::foldConstants, IntegerSgeOperation::normalizeIdenticalOperands })
bool reduceStaticallyKnownPredicate(rvsdg::GammaNode &gammaNode)
Definition Gamma.cpp:15
static std::vector< rvsdg::NodeNormalization< FPTruncOperation > > fpTruncOperationNormalizations({ FPTruncOperation::foldConstant })
static std::vector< rvsdg::NodeNormalization< IntegerOrOperation > > integerOrNormalizations({ IntegerOrOperation::foldConstants, IntegerOrOperation::normalizeIdempotent })
static std::vector< rvsdg::NodeNormalization< MemoryStateSplitOperation > > memoryStateSplitNormalizations({ MemoryStateSplitOperation::NormalizeSingleResult, MemoryStateSplitOperation::NormalizeNestedSplits, MemoryStateSplitOperation::NormalizeSplitMerge })
static std::vector< rvsdg::NodeNormalization< FPExtOperation > > fpExtOperationNormalizations({ FPExtOperation::foldConstant })
static std::vector< rvsdg::NodeNormalization< IntegerUltOperation > > integerUltNormalizations({ IntegerUltOperation::foldConstants, IntegerUltOperation::normalizeIdenticalOperands })
std::optional< std::vector< rvsdg::Output * > > foldMatchOperationWithConstant(const rvsdg::MatchOperation &matchOperation, const std::vector< rvsdg::Output * > &operands)
static std::vector< rvsdg::NodeNormalization< IntegerUDivOperation > > integerUDivNormalizations({ IntegerUDivOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerNeOperation > > integerNeNormalizations({ IntegerNeOperation::foldConstants, IntegerNeOperation::normalizeIdenticalOperands })
static rvsdg::NodeNormalization< TOperation > createNormalizer(const std::vector< rvsdg::NodeNormalization< TOperation > > &nodeNormalizations)
static std::vector< rvsdg::NodeNormalization< TruncOperation > > truncOperationNormalizations({ TruncOperation::foldConstant })
void MatchTypeWithDefault(T &obj, const Fns &... fns)
Pattern match over subclass type of given object with default handler.
std::optional< std::vector< rvsdg::Output * > > NormalizeBinaryOperation(const BinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions implemented in the binary operations reduction functions.
Definition binary.cpp:112
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
Definition region.cpp:808
size_t ninputs(const rvsdg::Region *region) noexcept
Definition region.cpp:861
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872
std::function< std::optional< std::vector< Output * > >(const TOperation &, const std::vector< Output * > &)> NodeNormalization
detail::TopDownTraverserGeneric< false > TopDownTraverser
Traverser for visiting every node in a region in a top down order.