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
16#include <jlm/rvsdg/binary.hpp>
17#include <jlm/rvsdg/gamma.hpp>
23
24namespace jlm::llvm
25{
26
27void
29{
30 AddMeasurement(Label::NumRvsdgNodesBefore, rvsdg::nnodes(&graph.GetRootRegion()));
31 AddMeasurement(Label::NumRvsdgInputsBefore, rvsdg::ninputs(&graph.GetRootRegion()));
32 AddTimer(Label::Timer).start();
33}
34
35void
37{
38 AddMeasurement(Label::NumRvsdgNodesAfter, rvsdg::nnodes(&graph.GetRootRegion()));
39 AddMeasurement(Label::NumRvsdgInputsAfter, rvsdg::ninputs(&graph.GetRootRegion()));
40
41 AddMeasurement(NumRegionsLabel_, getNumRegions());
42 AddMeasurement(NumTotalRegionIterationsLabel_, getTotalIterations());
43 AddMeasurement(MaxIterationsPerRegionLabel_, getMaxIterationsPerRegion());
44
45 auto & counters = getReductionCounters();
46 AddMeasurement("#LoadNonVolatileReductions", counters.numLoadNonVolatileReductions);
47 AddMeasurement("#StoreNonVolatileReductions", counters.numStoreNonVolatileReductions);
48 AddMeasurement("#MemoryStateMergeReductions", counters.numMemoryStateMergeReductions);
49 AddMeasurement("#MemoryStateJoinReductions", counters.numMemoryStateJoinReductions);
50 AddMeasurement("#MemoryStateSplitReductions", counters.numMemoryStateSplitReductions);
51 AddMeasurement(
52 "#LambdaExitMemoryStateMergeReductions",
53 counters.numLambdaExitMemoryStateMergeReductions);
54 AddMeasurement("#MatchReductions", counters.numMatchReductions);
55 AddMeasurement("#SExtReductions", counters.numSExtReductions);
56 AddMeasurement("#ZExtReductions", counters.numZExtReductions);
57 AddMeasurement("#TruncReductions", counters.numTruncReductions);
58 AddMeasurement("#IntegerEqReductions", counters.numIntegerEqReductions);
59 AddMeasurement("#IntegerNeReductions", counters.numIntegerNeReductions);
60 AddMeasurement("#IntegerSgeReductions", counters.numIntegerSgeReductions);
61 AddMeasurement("#IntegerSgtReductions", counters.numIntegerSgtReductions);
62 AddMeasurement("#IntegerSleReductions", counters.numIntegerSleReductions);
63 AddMeasurement("#IntegerSltReductions", counters.numIntegerSltReductions);
64 AddMeasurement("#IntegerUgeReductions", counters.numIntegerUgeReductions);
65 AddMeasurement("#IntegerUgtReductions", counters.numIntegerUgtReductions);
66 AddMeasurement("#IntegerUleReductions", counters.numIntegerUleReductions);
67 AddMeasurement("#IntegerUltReductions", counters.numIntegerUltReductions);
68
69 AddMeasurement("#IntegerAddReductions", counters.numIntegerAddReductions);
70 AddMeasurement("#IntegerSubReductions", counters.numIntegerSubReductions);
71 AddMeasurement("#IntegerMulReductions", counters.numIntegerMulReductions);
72 AddMeasurement("#IntegerSDivReductions", counters.numIntegerSDivReductions);
73 AddMeasurement("#IntegerUDivReductions", counters.numIntegerUDivReductions);
74 AddMeasurement("#IntegerSRemReductions", counters.numIntegerSRemReductions);
75 AddMeasurement("#IntegerURemReductions", counters.numIntegerURemReductions);
76 AddMeasurement("#IntegerAShrReductions", counters.numIntegerAShrReductions);
77 AddMeasurement("#IntegerShlReductions", counters.numIntegerShlReductions);
78 AddMeasurement("#IntegerLShrReductions", counters.numIntegerLShrReductions);
79 AddMeasurement("#IntegerAndReductions", counters.numIntegerAndReductions);
80 AddMeasurement("#IntegerOrReductions", counters.numIntegerOrReductions);
81 AddMeasurement("#IntegerXorReductions", counters.numIntegerXorReductions);
82
83 AddMeasurement("#PtrCmpReductions", counters.numPtrCmpReductions);
84 AddMeasurement("#GetElementPtrReductions", counters.numGetElementPtrReductions);
85 AddMeasurement("#BinaryReductions", counters.numBinaryReductions);
86 AddMeasurement("#GammaReductions", counters.numGammaReductions);
87
88 GetTimer(Label::Timer).stop();
89}
90
91bool
92NodeReduction::Statistics::AddIteration(const rvsdg::Region & region, size_t numIterations)
93{
94 const auto it = NumIterations_.find(&region);
95 NumIterations_[&region] = numIterations;
96 return it != NumIterations_.end();
97}
98
99std::optional<size_t>
101{
102 if (const auto it = NumIterations_.find(&region); it != NumIterations_.end())
103 {
104 return it->second;
105 }
106
107 return std::nullopt;
108}
109
110size_t
112{
113 return NumIterations_.size();
114}
115
116size_t
118{
119 size_t sum = 0;
120 for (auto [_, numIterations] : NumIterations_)
121 {
122 sum += numIterations;
123 }
124
125 return sum;
126}
127
128size_t
130{
131 return std::max_element(
132 NumIterations_.begin(),
133 NumIterations_.end(),
134 [](const auto & p1, const auto & p2)
135 {
136 return p1.second < p2.second;
137 })
138 ->second;
139}
140
141static std::vector<rvsdg::NodeNormalization<rvsdg::MatchOperation>>
143
144static std::vector<rvsdg::NodeNormalization<SExtOperation>>
146
147static std::vector<rvsdg::NodeNormalization<ZExtOperation>>
149
150static std::vector<rvsdg::NodeNormalization<TruncOperation>>
152
153static std::vector<rvsdg::NodeNormalization<IntegerEqOperation>>
155
156static std::vector<rvsdg::NodeNormalization<IntegerNeOperation>>
158
159static std::vector<rvsdg::NodeNormalization<IntegerSgeOperation>>
161
162static std::vector<rvsdg::NodeNormalization<IntegerSgtOperation>>
164
165static std::vector<rvsdg::NodeNormalization<IntegerSleOperation>>
167
168static std::vector<rvsdg::NodeNormalization<IntegerSltOperation>>
170
171static std::vector<rvsdg::NodeNormalization<IntegerUgeOperation>>
173
174static std::vector<rvsdg::NodeNormalization<IntegerUgtOperation>>
176
177static std::vector<rvsdg::NodeNormalization<IntegerUleOperation>>
179
180static std::vector<rvsdg::NodeNormalization<IntegerUltOperation>>
182
183static std::vector<rvsdg::NodeNormalization<IntegerAddOperation>>
185
186static std::vector<rvsdg::NodeNormalization<IntegerSubOperation>> integerSubNormalizations(
188
189static std::vector<rvsdg::NodeNormalization<IntegerMulOperation>>
191
192static std::vector<rvsdg::NodeNormalization<IntegerSDivOperation>>
194
195static std::vector<rvsdg::NodeNormalization<IntegerUDivOperation>>
197
198static std::vector<rvsdg::NodeNormalization<IntegerSRemOperation>>
200
201static std::vector<rvsdg::NodeNormalization<IntegerURemOperation>>
203
204static std::vector<rvsdg::NodeNormalization<IntegerAShrOperation>>
206
207static std::vector<rvsdg::NodeNormalization<IntegerShlOperation>>
209
210static std::vector<rvsdg::NodeNormalization<IntegerLShrOperation>>
212
213static std::vector<rvsdg::NodeNormalization<IntegerAndOperation>>
215
216static std::vector<rvsdg::NodeNormalization<IntegerOrOperation>>
218
219static std::vector<rvsdg::NodeNormalization<IntegerXorOperation>>
221
222static std::vector<rvsdg::NodeNormalization<LoadNonVolatileOperation>>
228
229static std::vector<rvsdg::NodeNormalization<StoreNonVolatileOperation>>
236
237static std::vector<rvsdg::NodeNormalization<MemoryStateMergeOperation>>
242
243static std::vector<rvsdg::NodeNormalization<MemoryStateJoinOperation>>
246
247static std::vector<rvsdg::NodeNormalization<MemoryStateSplitOperation>>
251
252static std::vector<rvsdg::NodeNormalization<LambdaExitMemoryStateMergeOperation>>
257
258static std::vector<rvsdg::NodeNormalization<PtrCmpOperation>>
260
261static std::vector<rvsdg::NodeNormalization<GetElementPtrOperation>>
263
264static std::vector<rvsdg::NodeNormalization<rvsdg::BinaryOperation>>
266
267template<typename TOperation>
269createNormalizer(const std::vector<rvsdg::NodeNormalization<TOperation>> & nodeNormalizations)
270{
271 return [&](const TOperation & operation, const std::vector<rvsdg::Output *> & operands)
272 {
273 return rvsdg::NormalizeSequence<TOperation>(nodeNormalizations, operation, operands);
274 };
275}
276
277template<class TOperation>
278static bool
280 rvsdg::SimpleNode & simpleNode,
281 const std::vector<rvsdg::NodeNormalization<TOperation>> & normalizations,
282 size_t & counter)
283{
284 auto normalizer = createNormalizer(normalizations);
285 const bool reductionPerformed = rvsdg::ReduceNode<TOperation>(normalizer, simpleNode);
286 if (reductionPerformed)
287 counter += 1;
288 return reductionPerformed;
289}
290
291NodeReduction::~NodeReduction() noexcept = default;
292
296
297void
299 rvsdg::RvsdgModule & rvsdgModule,
301{
302 const auto & graph = rvsdgModule.Rvsdg();
303
304 Statistics_ = Statistics::Create(rvsdgModule.SourceFilePath().value());
305 Statistics_->Start(graph);
306
307 ReduceNodesInRegion(graph.GetRootRegion());
308
309 Statistics_->End(graph);
311}
312
313void
315{
316 bool reductionPerformed = false;
317 size_t numIterations = 0;
318 do
319 {
320 numIterations++;
321 reductionPerformed = false;
322
323 for (const auto node : rvsdg::TopDownTraverser(&region))
324 {
325 MatchTypeOrFail(
326 *node,
327 [this, &reductionPerformed](rvsdg::StructuralNode & structuralNode)
328 {
329 reductionPerformed |= ReduceStructuralNode(structuralNode);
330 },
331 [this, &reductionPerformed](rvsdg::SimpleNode & simpleNode)
332 {
333 reductionPerformed |= ReduceSimpleNode(simpleNode);
334 });
335 }
336
337 if (reductionPerformed)
338 {
339 // Let's remove all dead nodes in this region to avoid reductions on
340 // dead nodes in the next iteration.
341 region.prune(false);
342 }
343 } while (reductionPerformed);
344
345 Statistics_->AddIteration(region, numIterations);
346}
347
348bool
350{
351 bool reductionPerformed = false;
352
353 // Reduce structural nodes
354 if (const auto gammaNode = dynamic_cast<rvsdg::GammaNode *>(&structuralNode))
355 {
356 reductionPerformed |= ReduceGammaNode(*gammaNode);
357 }
358
359 if (reductionPerformed)
360 {
361 // We cannot go through the subregions as the structural node might already have been removed.
362 return true;
363 }
364
365 // Reduce all nodes in the subregions
366 for (size_t n = 0; n < structuralNode.nsubregions(); n++)
367 {
368 const auto subregion = structuralNode.subregion(n);
369 ReduceNodesInRegion(*subregion);
370 }
371
372 return false;
373}
374
375bool
377{
378 // FIXME: We can not apply the reduction below due to a bug. See github issue #303
379 // rvsdg::ReduceGammaControlConstant
380
381 const bool reductionPerformed = reduceStaticallyKnownPredicate(gammaNode);
382 if (reductionPerformed)
383 Statistics_->getReductionCounters().numGammaReductions++;
384
385 return reductionPerformed;
386}
387
388bool
390{
391 if (is<LoadNonVolatileOperation>(&simpleNode))
392 {
393 return reduceSimpleNode<LoadNonVolatileOperation>(
394 simpleNode,
396 Statistics_->getReductionCounters().numLoadNonVolatileReductions);
397 }
398 if (is<StoreNonVolatileOperation>(&simpleNode))
399 {
400 return reduceSimpleNode<StoreNonVolatileOperation>(
401 simpleNode,
403 Statistics_->getReductionCounters().numStoreNonVolatileReductions);
404 }
405 if (is<MemoryStateMergeOperation>(&simpleNode))
406 {
407 return reduceSimpleNode<MemoryStateMergeOperation>(
408 simpleNode,
410 Statistics_->getReductionCounters().numMemoryStateMergeReductions);
411 }
412 if (is<MemoryStateJoinOperation>(&simpleNode))
413 {
414 return reduceSimpleNode<MemoryStateJoinOperation>(
415 simpleNode,
417 Statistics_->getReductionCounters().numMemoryStateJoinReductions);
418 }
419 if (is<MemoryStateSplitOperation>(&simpleNode))
420 {
421 return reduceSimpleNode<MemoryStateSplitOperation>(
422 simpleNode,
424 Statistics_->getReductionCounters().numMemoryStateSplitReductions);
425 }
426 if (is<LambdaExitMemoryStateMergeOperation>(&simpleNode))
427 {
428 return reduceSimpleNode<LambdaExitMemoryStateMergeOperation>(
429 simpleNode,
431 Statistics_->getReductionCounters().numLambdaExitMemoryStateMergeReductions);
432 }
433 if (is<rvsdg::MatchOperation>(&simpleNode))
434 {
435 return reduceSimpleNode<rvsdg::MatchOperation>(
436 simpleNode,
438 Statistics_->getReductionCounters().numMatchReductions);
439 }
440 if (is<SExtOperation>(&simpleNode))
441 {
442 return reduceSimpleNode<SExtOperation>(
443 simpleNode,
445 Statistics_->getReductionCounters().numSExtReductions);
446 }
447 if (is<ZExtOperation>(&simpleNode))
448 {
449 return reduceSimpleNode<ZExtOperation>(
450 simpleNode,
452 Statistics_->getReductionCounters().numZExtReductions);
453 }
454 if (is<TruncOperation>(&simpleNode))
455 {
456 return reduceSimpleNode<TruncOperation>(
457 simpleNode,
459 Statistics_->getReductionCounters().numTruncReductions);
460 }
461 if (is<IntegerEqOperation>(&simpleNode))
462 {
463 return reduceSimpleNode<IntegerEqOperation>(
464 simpleNode,
466 Statistics_->getReductionCounters().numIntegerEqReductions);
467 }
468 if (is<IntegerNeOperation>(&simpleNode))
469 {
470 return reduceSimpleNode<IntegerNeOperation>(
471 simpleNode,
473 Statistics_->getReductionCounters().numIntegerNeReductions);
474 }
475 if (is<IntegerSgeOperation>(&simpleNode))
476 {
477 return reduceSimpleNode<IntegerSgeOperation>(
478 simpleNode,
480 Statistics_->getReductionCounters().numIntegerSgeReductions);
481 }
482 if (is<IntegerSgtOperation>(&simpleNode))
483 {
484 return reduceSimpleNode<IntegerSgtOperation>(
485 simpleNode,
487 Statistics_->getReductionCounters().numIntegerSgtReductions);
488 }
489 if (is<IntegerSleOperation>(&simpleNode))
490 {
491 return reduceSimpleNode<IntegerSleOperation>(
492 simpleNode,
494 Statistics_->getReductionCounters().numIntegerSleReductions);
495 }
496 if (is<IntegerSltOperation>(&simpleNode))
497 {
498 return reduceSimpleNode<IntegerSltOperation>(
499 simpleNode,
501 Statistics_->getReductionCounters().numIntegerSltReductions);
502 }
503 if (is<IntegerUgeOperation>(&simpleNode))
504 {
505 return reduceSimpleNode<IntegerUgeOperation>(
506 simpleNode,
508 Statistics_->getReductionCounters().numIntegerUgeReductions);
509 }
510 if (is<IntegerUgtOperation>(&simpleNode))
511 {
512 return reduceSimpleNode<IntegerUgtOperation>(
513 simpleNode,
515 Statistics_->getReductionCounters().numIntegerUgtReductions);
516 }
517 if (is<IntegerUleOperation>(&simpleNode))
518 {
519 return reduceSimpleNode<IntegerUleOperation>(
520 simpleNode,
522 Statistics_->getReductionCounters().numIntegerUleReductions);
523 }
524 if (is<IntegerUltOperation>(&simpleNode))
525 {
526 return reduceSimpleNode<IntegerUltOperation>(
527 simpleNode,
529 Statistics_->getReductionCounters().numIntegerUltReductions);
530 }
531 if (is<IntegerAddOperation>(&simpleNode))
532 {
533 return reduceSimpleNode<IntegerAddOperation>(
534 simpleNode,
536 Statistics_->getReductionCounters().numIntegerAddReductions);
537 }
538 if (is<IntegerSubOperation>(&simpleNode))
539 {
540 return reduceSimpleNode<IntegerSubOperation>(
541 simpleNode,
543 Statistics_->getReductionCounters().numIntegerSubReductions);
544 }
545 if (is<IntegerMulOperation>(&simpleNode))
546 {
547 return reduceSimpleNode<IntegerMulOperation>(
548 simpleNode,
550 Statistics_->getReductionCounters().numIntegerMulReductions);
551 }
552 if (is<IntegerSDivOperation>(&simpleNode))
553 {
554 return reduceSimpleNode<IntegerSDivOperation>(
555 simpleNode,
557 Statistics_->getReductionCounters().numIntegerSDivReductions);
558 }
559 if (is<IntegerUDivOperation>(&simpleNode))
560 {
561 return reduceSimpleNode<IntegerUDivOperation>(
562 simpleNode,
564 Statistics_->getReductionCounters().numIntegerUDivReductions);
565 }
566 if (is<IntegerSRemOperation>(&simpleNode))
567 {
568 return reduceSimpleNode<IntegerSRemOperation>(
569 simpleNode,
571 Statistics_->getReductionCounters().numIntegerSRemReductions);
572 }
573 if (is<IntegerURemOperation>(&simpleNode))
574 {
575 return reduceSimpleNode<IntegerURemOperation>(
576 simpleNode,
578 Statistics_->getReductionCounters().numIntegerURemReductions);
579 }
580 if (is<IntegerAShrOperation>(&simpleNode))
581 {
582 return reduceSimpleNode<IntegerAShrOperation>(
583 simpleNode,
585 Statistics_->getReductionCounters().numIntegerAShrReductions);
586 }
587 if (is<IntegerShlOperation>(&simpleNode))
588 {
589 return reduceSimpleNode<IntegerShlOperation>(
590 simpleNode,
592 Statistics_->getReductionCounters().numIntegerShlReductions);
593 }
594 if (is<IntegerLShrOperation>(&simpleNode))
595 {
596 return reduceSimpleNode<IntegerLShrOperation>(
597 simpleNode,
599 Statistics_->getReductionCounters().numIntegerLShrReductions);
600 }
601 if (is<IntegerAndOperation>(&simpleNode))
602 {
603 return reduceSimpleNode<IntegerAndOperation>(
604 simpleNode,
606 Statistics_->getReductionCounters().numIntegerAndReductions);
607 }
608 if (is<IntegerOrOperation>(&simpleNode))
609 {
610 return reduceSimpleNode<IntegerOrOperation>(
611 simpleNode,
613 Statistics_->getReductionCounters().numIntegerOrReductions);
614 }
615 if (is<IntegerXorOperation>(&simpleNode))
616 {
617 return reduceSimpleNode<IntegerXorOperation>(
618 simpleNode,
620 Statistics_->getReductionCounters().numIntegerXorReductions);
621 }
622 if (is<PtrCmpOperation>(&simpleNode))
623 {
624 return reduceSimpleNode<PtrCmpOperation>(
625 simpleNode,
627 Statistics_->getReductionCounters().numPtrCmpReductions);
628 }
629 if (is<GetElementPtrOperation>(&simpleNode))
630 {
631 return reduceSimpleNode<GetElementPtrOperation>(
632 simpleNode,
634 Statistics_->getReductionCounters().numGetElementPtrReductions);
635 }
636 if (is<rvsdg::BinaryOperation>(&simpleNode))
637 {
638 return reduceSimpleNode<rvsdg::BinaryOperation>(
639 simpleNode,
641 Statistics_->getReductionCounters().numBinaryReductions);
642 }
643
644 return false;
645}
646
647}
static jlm::util::StatisticsCollector statisticsCollector
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 * > > 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 * > > foldConstants(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 * > > foldConstants(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 * > > foldConstants(const IntegerSleOperation &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 * > > foldConstants(const IntegerUgtOperation &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 * > > 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 * > > normalizeIOBarrierAddress(const LoadNonVolatileOperation &loadOperation, const std::vector< rvsdg::Output * > &operands)
Redirect the address operand of the LoadNonVolatileOperation node from an IOBarrierOperation node whe...
Definition Load.cpp:367
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 * > > 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 * > > 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_
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 * > > 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 * > > normalizeIOBarrierAddress(const StoreNonVolatileOperation &storeOperation, const std::vector< rvsdg::Output * > &operands)
Redirect the address operand of the StoreNonVolatileOperation node from an IOBarrierOperation node wh...
Definition Store.cpp:279
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 * > > 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
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 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< LoadNonVolatileOperation > > loadNonVolatileNormalizations({ LoadNonVolatileOperation::NormalizeLoadStore, LoadNonVolatileOperation::NormalizeLoadAlloca, LoadNonVolatileOperation::NormalizeDuplicateStates, LoadNonVolatileOperation::NormalizeLoadStoreState, LoadNonVolatileOperation::normalizeIOBarrierAddress })
static std::vector< rvsdg::NodeNormalization< IntegerEqOperation > > integerEqNormalizations({ IntegerEqOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< rvsdg::MatchOperation > > matchOperationNormalizations({ foldMatchOperationWithConstant })
static std::vector< rvsdg::NodeNormalization< IntegerShlOperation > > integerShlNormalizations({ IntegerShlOperation::foldConstants })
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< IntegerURemOperation > > integerURemNormalizations({ IntegerURemOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerUleOperation > > integerUleNormalizations({ IntegerUleOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< MemoryStateJoinOperation > > memoryStateJoinNormalizations({ MemoryStateJoinOperation::NormalizeSingleOperand, MemoryStateJoinOperation::NormalizeDuplicateOperands })
static std::vector< rvsdg::NodeNormalization< IntegerSltOperation > > integerSltNormalizations({ IntegerSltOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< LambdaExitMemoryStateMergeOperation > > lambdaExitMemoryStateMergeNormalizations({ LambdaExitMemoryStateMergeOperation::NormalizeLoadFromAlloca, LambdaExitMemoryStateMergeOperation::NormalizeStoreToAlloca, LambdaExitMemoryStateMergeOperation::NormalizeAlloca })
static std::vector< rvsdg::NodeNormalization< IntegerMulOperation > > integerMulNormalizations({ IntegerMulOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerNeOperation > > integerNeNormalizations({ IntegerNeOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerUgeOperation > > integerUgeNormalizations({ IntegerUgeOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerSDivOperation > > integerSDivNormalizations({ IntegerSDivOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< IntegerSgtOperation > > integerSgtNormalizations({ IntegerSgtOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< MemoryStateMergeOperation > > memoryStateMergeNormalizations({ MemoryStateMergeOperation::NormalizeSingleOperand, MemoryStateMergeOperation::NormalizeDuplicateOperands, MemoryStateMergeOperation::NormalizeNestedMerges, MemoryStateMergeOperation::NormalizeMergeSplit })
static std::vector< rvsdg::NodeNormalization< IntegerSgeOperation > > integerSgeNormalizations({ IntegerSgeOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< PtrCmpOperation > > ptrCmpNormalizations({ PtrCmpOperation::normalizeNullPointerComparison })
static std::vector< rvsdg::NodeNormalization< ZExtOperation > > zextOperationNormalizations({ ZExtOperation::foldConstant })
static std::vector< rvsdg::NodeNormalization< IntegerUltOperation > > integerUltNormalizations({ IntegerUltOperation::foldConstants })
bool reduceStaticallyKnownPredicate(rvsdg::GammaNode &gammaNode)
Definition Gamma.cpp:15
static std::vector< rvsdg::NodeNormalization< MemoryStateSplitOperation > > memoryStateSplitNormalizations({ MemoryStateSplitOperation::NormalizeSingleResult, MemoryStateSplitOperation::NormalizeNestedSplits, MemoryStateSplitOperation::NormalizeSplitMerge })
static std::vector< rvsdg::NodeNormalization< IntegerOrOperation > > integerOrNormalizations({ IntegerOrOperation::foldConstants })
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< IntegerUgtOperation > > integerUgtNormalizations({ IntegerUgtOperation::foldConstants })
static std::vector< rvsdg::NodeNormalization< StoreNonVolatileOperation > > storeNonVolatileNormalizations({ StoreNonVolatileOperation::NormalizeStoreMux, StoreNonVolatileOperation::normalizeStoreStore, StoreNonVolatileOperation::NormalizeStoreAlloca, StoreNonVolatileOperation::NormalizeDuplicateStates, StoreNonVolatileOperation::normalizeIOBarrierAddress, StoreNonVolatileOperation::normalizeStoreAllocaSingleUser })
static std::vector< rvsdg::NodeNormalization< IntegerSleOperation > > integerSleNormalizations({ IntegerSleOperation::foldConstants })
static rvsdg::NodeNormalization< TOperation > createNormalizer(const std::vector< rvsdg::NodeNormalization< TOperation > > &nodeNormalizations)
static std::vector< rvsdg::NodeNormalization< TruncOperation > > truncOperationNormalizations({ TruncOperation::foldConstant })
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.