Reactor: Add support for specifying and modifying default configuration settings.
rr::Config holds the full reactor configuration state.
rr::Config::Edit holds edits on a config, which can be applied on top of the current defaults.
Default configurations are updated atomically, preventing modifications to the default state from tearing.
Bug: b/137167988
Change-Id: Ib05f2cfc31ab22fb9a891a267fffe33c18691028
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33768
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index bb94cf5..60ee656 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -21,8 +21,59 @@
#define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION 0
#endif
+namespace
+{
+ // Introduced in C++20.
+ template <class ForwardIterator, class UnaryPredicate>
+ ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
+ UnaryPredicate pred)
+ {
+ ForwardIterator result = first;
+ while (first!=last) {
+ if (!pred(*first)) {
+ *result = std::move(*first);
+ ++result;
+ }
+ ++first;
+ }
+ return result;
+ }
+}
+
namespace rr
{
+ const Config::Edit Config::Edit::None = {};
+
+ Config Config::Edit::apply(const Config &cfg) const
+ {
+ if (this == &None) { return cfg; }
+
+ auto level = optLevelChanged ? optLevel : cfg.optimization.getLevel();
+ auto passes = cfg.optimization.getPasses();
+ apply(optPassEdits, passes);
+ return Config{ Optimization{level, passes} };
+ }
+
+ template <typename T>
+ void rr::Config::Edit::apply(const std::vector<std::pair<ListEdit, T>> & edits, std::vector<T>& list) const
+ {
+ for (auto & edit : edits)
+ {
+ switch (edit.first)
+ {
+ case ListEdit::Add:
+ list.push_back(edit.second);
+ break;
+ case ListEdit::Remove:
+ ::remove_if(list.begin(), list.end(), [&](T item) { return item == edit.second; });
+ break;
+ case ListEdit::Clear:
+ list.clear();
+ break;
+ }
+ }
+ }
+
// Set of variables that do not have a stack location yet.
std::unordered_set<Variable*> Variable::unmaterializedVariables;