summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h')
-rw-r--r--deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h b/deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h
new file mode 100644
index 0000000000..10047bba16
--- /dev/null
+++ b/deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h
@@ -0,0 +1,160 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_
+#define V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_
+
+#include "src/compiler/turboshaft/operations.h"
+
+namespace v8::internal::compiler::turboshaft {
+
+// UniformReducerAdapter allows to handle all operations uniformly during a
+// reduction by wiring all ReduceInputGraphXyz and ReduceXyz calls through
+// a single ReduceInputGraphOperation and ReduceOperation, respectively.
+//
+// This is how to use the adapter with your reducer MyReducer, which can then
+// be used in a ReducerStack like any other reducer):
+//
+// template <typename Next>
+// class MyReducer : public UniformReducerAdapter<MyReducer, Next> {
+// public:
+// TURBOSHAFT_REDUCER_BOILERPLATE()
+// using Adapter = UniformReducerAdapter<MyReducer, Next>;
+//
+// template <typename... Args>
+// explicit MyReducer(const std::tuple<Args...>& args)
+// : Adapter(args) { /* ... */ }
+//
+// OpIndex ReduceInputGraphConstant(OpIndex ig_index, const ConstantOp& op) {
+// /* Handle ConstantOps separately */
+// /* ... */
+//
+// /* Call Adapter::ReduceInputGraphConstant(index, op) to also run */
+// /* through the generic handling in ReduceInputGraphOperation */
+// return Next::ReduceInputGraphConstant(index, op);
+// }
+//
+// template <typename Op, typename Continuation>
+// OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op& op) {
+// /* Handle all (other) operations uniformly */
+// /* ... */
+//
+// /* Forward to next reducer using the Continuation object */
+// return Continuation{this}.ReduceInputGraph(ig_index, op);
+// }
+//
+// OpIndex ReduceConstant(ConstantOp::Kind kind, ConstantOp::Storage st) {
+// /* Handle Constants separately */
+// /* ... */
+//
+// /* Call Adapter::ReduceConstant(kind, st) to also run through the */
+// /* generic handling in ReduceOperation */
+// return Next::ReduceConstant(kind, st);
+// }
+//
+// template <Opcode opcode, typename Continuation, typename... Args>
+// OpIndex ReduceOperation(Args... args) {
+// /* Handle all (other) operations uniformly */
+// /* ... */
+//
+// /* Forward to next reducer using the Continuation object */
+// return Continuation{this}.Reduce(args...);
+// }
+//
+// private:
+// /* ... */
+// };
+//
+// NOTICE: Inside the ReduceOperation and ReduceInputGraphOperation callbacks,
+// you need to make a choice:
+//
+// A) Call Next::ReduceXyz (or Next::ReduceInputGraphXyz) to forward to the
+// next reducer in the stack. Then the uniform ReduceOperation (and
+// ReduceInputGraphOperation) of the current reducer is not visited for
+// OperationXyz.
+// B) Call Adapter::ReduceXyz (or Adapter::ReduceInputGraphXyz) to forward to
+// the uniform ReduceOperation (and ReduceInputGraphOperation) such that
+// OperationXyz is also processed by those (in addition to the special
+// handling in ReduceXyz and ReduceInputGraphXyz).
+//
+// For the above MyReducer, consider this OptimizationPhase<R1, MyReducer, R2>.
+// Then the ReduceInputGraph (RIG) and Reduce (R) implementations are visited as
+// follows for Operations OpA and OpB (and all other operations that are not
+// ConstantOp), when all reducers just forward to Next. For ConstantOp, the
+// reduction is equivalent to any "normal" reducer that does not use a
+// UniformReducerAdapter.
+//
+//
+// InputGraph OpA OpB ____________________________
+// | | | ___ |
+// | | | | | |
+// v v | | v v
+// R1 RIGOpA RIGOpB | | ROpA ROpB
+// | __ __ | | | | ___ ___ |
+// | | | | | | | | | | | | | |
+// | | v v | | | | | | v v | |
+// MyReducer | | RIGOperation | | | | | | ROperation | |
+// v | v | | | | v | v | v
+// (Adapter) RIGOpA | Continuation | RIGOpB | | ROpA | Continuation | ROpB
+// |____| | | |___| | | |___| | | |___|
+// | | | | | |
+// _______| |______ | | ______| |______
+// | | | | | |
+// | | | | | |
+// v v | | v v
+// R2 RIGOpA RIGOpB | | ROpA ROpB
+// | |_____| | | |
+// |_______________________________| | |
+// v v
+// OutputGraph OpA OpB
+//
+//
+template <template <typename> typename Reducer, typename Next>
+class UniformReducerAdapter : public Next {
+ public:
+ template <typename... Args>
+ explicit UniformReducerAdapter(const std::tuple<Args...>& args)
+ : Next(args) {}
+
+ template <Opcode opcode, typename Continuation, typename... Args>
+ OpIndex ReduceOperation(Args... args) {
+ return Continuation{this}.Reduce(args...);
+ }
+
+ template <typename Op, typename Continuation>
+ OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op& operation) {
+ return Continuation{this}.ReduceInputGraph(ig_index, operation);
+ }
+
+#define REDUCE(op) \
+ struct Reduce##op##Continuation final { \
+ explicit Reduce##op##Continuation(Next* _this) : this_(_this) {} \
+ OpIndex ReduceInputGraph(OpIndex ig_index, const op##Op& operation) { \
+ return this_->ReduceInputGraph##op(ig_index, operation); \
+ } \
+ template <typename... Args> \
+ OpIndex Reduce(Args... args) const { \
+ return this_->Reduce##op(args...); \
+ } \
+ Next* this_; \
+ }; \
+ OpIndex ReduceInputGraph##op(OpIndex ig_index, const op##Op& operation) { \
+ return static_cast<Reducer<Next>*>(this) \
+ ->template ReduceInputGraphOperation<op##Op, \
+ Reduce##op##Continuation>( \
+ ig_index, operation); \
+ } \
+ template <typename... Args> \
+ OpIndex Reduce##op(Args... args) { \
+ return static_cast<Reducer<Next>*>(this) \
+ ->template ReduceOperation<Opcode::k##op, Reduce##op##Continuation>( \
+ args...); \
+ }
+ TURBOSHAFT_OPERATION_LIST(REDUCE)
+#undef REDUCE
+};
+
+} // namespace v8::internal::compiler::turboshaft
+
+#endif // V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_