Jlm
Loading...
Searching...
No Matches
reduction-helpers.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Helge Bahmann <hcb@chaoticmind.net>
3 * See COPYING for terms of redistribution.
4 */
5
6#ifndef JLM_RVSDG_REDUCTION_HELPERS_HPP
7#define JLM_RVSDG_REDUCTION_HELPERS_HPP
8
9#include <jlm/rvsdg/node.hpp>
10
11#include <algorithm>
12
13namespace jlm::rvsdg
14{
15namespace base
16{
17namespace detail
18{
19
20/* Test whether any pair of adjacent elements of "args" can be reduced according
21 * to "reduction_tester". */
22template<typename Container, typename ReductionTester>
23bool
25{
26 if (args.empty())
27 {
28 return false;
29 }
30
31 auto left = args.begin();
32 auto right = std::next(left);
33
34 while (right != args.end())
35 {
37 {
38 return true;
39 }
40 left = right;
41 ++right;
42 }
43
44 return false;
45}
46
47/* Apply "reductor" to each pair of adjacent elements of "args", replace the two
48 * with the result if not nullptr. */
49template<typename Container, typename Reductor>
52{
53 if (args.empty())
54 {
55 return args;
56 }
57
58 auto left = args.begin();
59 auto right = std::next(left);
60
61 while (right != args.end())
62 {
63 auto res = reductor(*left, *right);
64 if (res)
65 {
66 *left = res;
67 ++right;
68 }
69 else
70 {
71 ++left;
72 *left = *right;
73 ++right;
74 }
75 }
76 args.erase(std::next(left), args.end());
77
78 return args;
79}
80
81/* Test whether any pair of elements of "args" can be reduced according
82 * to "reduction_tester". */
83template<typename Container, typename ReductionTester>
84bool
86 const Container & args,
87 const ReductionTester & reduction_tester) noexcept
88{
89 auto left = args.begin();
90 while (left != args.end())
91 {
92 auto right = std::next(left);
93 while (right != args.end())
94 {
96 {
97 return true;
98 }
99 else
100 {
101 ++right;
102 }
103 }
104 ++left;
105 }
106
107 return false;
108}
109
110/* Apply "reductor" to each pair of elements of "args", replace the two
111 * with the result if not nullptr. */
112template<typename Container, typename Reductor>
115{
116 auto left = args.begin();
117 while (left != args.end())
118 {
119 auto right = std::next(left);
120 while (right != args.end())
121 {
122 auto result = reductor(*left, *right);
123 if (result)
124 {
125 *left = result;
126 *right = args.back();
127 args.pop_back();
128 /* Start over and compare with everything */
129 left = args.begin();
130 right = std::next(left);
131 }
132 else
133 {
134 ++right;
135 }
136 }
137 ++left;
138 }
139
140 return args;
141}
142
143/* Test whether "flatten_tester" applies to any element of "args". */
144template<typename Container, typename FlattenTester>
145bool
147{
148 return std::any_of(args.begin(), args.end(), flatten_tester);
149}
150
151/* Replace each argument of "args" with the arguments of its defining node
152 * for each where "flatten_tester" returns true. */
153template<typename FlattenTester>
154std::vector<jlm::rvsdg::Output *>
155associative_flatten(std::vector<jlm::rvsdg::Output *> args, const FlattenTester & flatten_tester)
156{
157 size_t n = 0;
158 while (n < args.size())
159 {
160 if (flatten_tester(args[n]))
161 {
162 auto arg = args[n];
165 args[n] = sub_args[0];
166 args.insert(args.begin() + n + 1, sub_args.begin() + 1, sub_args.end());
167 }
168 else
169 {
170 ++n;
171 }
172 }
173 return args;
174}
175
176}
177}
178}
179
180#endif
#define JLM_ASSERT(x)
Definition common.hpp:16
Container pairwise_reduce(Container args, const Reductor &reductor)
bool associative_test_flatten(const Container &args, const FlattenTester &flatten_tester)
bool commutative_pairwise_test_reduce(const Container &args, const ReductionTester &reduction_tester) noexcept
std::vector< jlm::rvsdg::Output * > associative_flatten(std::vector< jlm::rvsdg::Output * > args, const FlattenTester &flatten_tester)
Container commutative_pairwise_reduce(Container args, const Reductor &reductor)
bool pairwise_test_reduce(const Container &args, const ReductionTester &reduction_tester) noexcept
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition node.hpp:1049
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872