diff options
Diffstat (limited to 'deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h')
-rw-r--r-- | deps/v8/src/compiler/turboshaft/uniform-reducer-adapter.h | 160 |
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_ |