From 6de2d92f20d48d38797a628ee35e7615170cd63f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Wed, 16 Jan 2019 11:44:45 +0100 Subject: Add SSAReverser to the yul optimiser. --- libdevcore/CommonData.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'libdevcore/CommonData.h') 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& _vector, const F& _f) _vector = std::move(modifiedVector); } + +namespace detail +{ +template +void iterateReplacingWindow(std::vector& _vector, F const& _f, std::index_sequence) +{ + // Concept: _f must be Callable, must accept sizeof...(I) parameters of type T&, must return optional> + bool useModified = false; + std::vector modifiedVector; + size_t i = 0; + for (; i + sizeof...(I) <= _vector.size(); ++i) + { + if (boost::optional> 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 +void iterateReplacingWindow(std::vector& _vector, F const& _f) +{ + // Concept: _f must be Callable, must accept N parameters of type T&, must return optional> + detail::iterateReplacingWindow(_vector, _f, std::make_index_sequence{}); +} + /// @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. -- cgit