aboutsummaryrefslogtreecommitdiffstats
path: root/libdevcore
diff options
context:
space:
mode:
authorDaniel Kirchner <daniel@ekpyron.org>2019-01-16 18:44:45 +0800
committerDaniel Kirchner <daniel@ekpyron.org>2019-01-18 03:37:43 +0800
commit6de2d92f20d48d38797a628ee35e7615170cd63f (patch)
tree7d34e8c7655b8558061fd58de1bc26f6e44f1aaa /libdevcore
parent7c07e9498664c9b9dec6f332490d51c7a920de8b (diff)
downloaddexon-solidity-6de2d92f20d48d38797a628ee35e7615170cd63f.tar.gz
dexon-solidity-6de2d92f20d48d38797a628ee35e7615170cd63f.tar.zst
dexon-solidity-6de2d92f20d48d38797a628ee35e7615170cd63f.zip
Add SSAReverser to the yul optimiser.
Diffstat (limited to 'libdevcore')
-rw-r--r--libdevcore/CommonData.h53
1 files changed, 53 insertions, 0 deletions
diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h
index 1d668f26..98331936 100644
--- a/libdevcore/CommonData.h
+++ b/libdevcore/CommonData.h
@@ -263,6 +263,59 @@ void iterateReplacing(std::vector<T>& _vector, const F& _f)
_vector = std::move(modifiedVector);
}
+
+namespace detail
+{
+template <typename T, typename F, std::size_t... I>
+void iterateReplacingWindow(std::vector<T>& _vector, F const& _f, std::index_sequence<I...>)
+{
+ // Concept: _f must be Callable, must accept sizeof...(I) parameters of type T&, must return optional<vector<T>>
+ bool useModified = false;
+ std::vector<T> modifiedVector;
+ size_t i = 0;
+ for (; i + sizeof...(I) <= _vector.size(); ++i)
+ {
+ if (boost::optional<std::vector<T>> r = _f(_vector[i + I]...))
+ {
+ if (!useModified)
+ {
+ std::move(_vector.begin(), _vector.begin() + i, back_inserter(modifiedVector));
+ useModified = true;
+ }
+ modifiedVector += std::move(*r);
+ i += sizeof...(I) - 1;
+ }
+ else if (useModified)
+ modifiedVector.emplace_back(std::move(_vector[i]));
+ }
+ if (useModified)
+ {
+ for (; i < _vector.size(); ++i)
+ modifiedVector.emplace_back(std::move(_vector[i]));
+ _vector = std::move(modifiedVector);
+ }
+}
+
+}
+
+/// Function that iterates over the vector @param _vector,
+/// calling the function @param _f on sequences of @tparam N of its
+/// elements. If @param _f returns a vector, these elements are replaced by
+/// the returned vector and the iteration continues with the next @tparam N elements.
+/// If the function does not return a vector, the iteration continues with an overlapping
+/// sequence of @tparam N elements that starts with the second element of the previous
+/// iteration.
+/// During the iteration, the original vector is only valid
+/// on the current element and after that. The actual replacement takes
+/// place at the end, but already visited elements might be invalidated.
+/// If nothing is replaced, no copy is performed.
+template <std::size_t N, typename T, typename F>
+void iterateReplacingWindow(std::vector<T>& _vector, F const& _f)
+{
+ // Concept: _f must be Callable, must accept N parameters of type T&, must return optional<vector<T>>
+ detail::iterateReplacingWindow(_vector, _f, std::make_index_sequence<N>{});
+}
+
/// @returns true iff @a _str passess the hex address checksum test.
/// @param _strict if false, hex strings with only uppercase or only lowercase letters
/// are considered valid.