v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
uniform-reducer-adapter.h
Go to the documentation of this file.
1// Copyright 2022 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_
6#define V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_
7
9
11
12// UniformReducerAdapter allows to handle all operations uniformly during a
13// reduction by wiring all ReduceInputGraphXyz and ReduceXyz calls through
14// a single ReduceInputGraphOperation and ReduceOperation, respectively.
15//
16// This is how to use the adapter with your reducer MyReducer, which can then
17// be used in a ReducerStack like any other reducer):
18//
19// template <typename Next>
20// class MyReducer : public UniformReducerAdapter<MyReducer, Next> {
21// public:
22// TURBOSHAFT_REDUCER_BOILERPLATE()
23// using Adapter = UniformReducerAdapter<MyReducer, Next>;
24//
25// OpIndex ReduceInputGraphConstant(OpIndex ig_index, const ConstantOp& op) {
26// /* Handle ConstantOps separately */
27// /* ... */
28//
29// /* Call Adapter::ReduceInputGraphConstant(index, op) to also run */
30// /* through the generic handling in ReduceInputGraphOperation */
31// return Next::ReduceInputGraphConstant(index, op);
32// }
33//
34// template <typename Op, typename Continuation>
35// OpIndex ReduceInputGraphOperation(OpIndex ig_index, const Op& op) {
36// /* Handle all (other) operations uniformly */
37// /* ... */
38//
39// /* Forward to next reducer using the Continuation object */
40// return Continuation{this}.ReduceInputGraph(ig_index, op);
41// }
42//
43// OpIndex ReduceConstant(ConstantOp::Kind kind, ConstantOp::Storage st) {
44// /* Handle Constants separately */
45// /* ... */
46//
47// /* Call Adapter::ReduceConstant(kind, st) to also run through the */
48// /* generic handling in ReduceOperation */
49// return Next::ReduceConstant(kind, st);
50// }
51//
52// template <Opcode opcode, typename Continuation, typename... Args>
53// OpIndex ReduceOperation(Args... args) {
54// /* Handle all (other) operations uniformly */
55// /* ... */
56//
57// /* Forward to next reducer using the Continuation object */
58// return Continuation{this}.Reduce(args...);
59// }
60//
61// private:
62// /* ... */
63// };
64//
65// NOTICE: Inside the ReduceXyz and ReduceInputGraphXyz callbacks of MyReducer,
66// you need to make a choice:
67//
68// A) Call Next::ReduceXyz (or Next::ReduceInputGraphXyz) to forward to the
69// next reducer in the stack. Then the uniform ReduceOperation (and
70// ReduceInputGraphOperation) of the current reducer is not visited for
71// OperationXyz.
72// B) Call Adapter::ReduceXyz (or Adapter::ReduceInputGraphXyz) to forward to
73// the uniform ReduceOperation (and ReduceInputGraphOperation) such that
74// OperationXyz is also processed by those (in addition to the special
75// handling in ReduceXyz and ReduceInputGraphXyz).
76//
77// For the above MyReducer, consider this CopyingPhase<R1, MyReducer, R2>.
78// Then the ReduceInputGraph (RIG) and Reduce (R) implementations are visited as
79// follows for Operations OpA and OpB (and all other operations that are not
80// ConstantOp), when all reducers just forward to Next. For ConstantOp, the
81// reduction is equivalent to any "normal" reducer that does not use a
82// UniformReducerAdapter.
83//
84//
85// InputGraph OpA OpB ____________________________
86// | | | ___ |
87// | | | | | |
88// v v | | v v
89// R1 RIGOpA RIGOpB | | ROpA ROpB
90// | __ __ | | | | ___ ___ |
91// | | | | | | | | | | | | | |
92// | | v v | | | | | | v v | |
93// MyReducer | | RIGOperation | | | | | | ROperation | |
94// v | v | | | | v | v | v
95// (Adapter) RIGOpA | Continuation | RIGOpB | | ROpA | Continuation | ROpB
96// |____| | | |___| | | |___| | | |___|
97// | | | | | |
98// _______| |______ | | ______| |______
99// | | | | | |
100// | | | | | |
101// v v | | v v
102// R2 RIGOpA RIGOpB | | ROpA ROpB
103// | |_____| | | |
104// |_______________________________| | |
105// v v
106// OutputGraph OpA OpB
107//
108//
109template <template <typename> typename Reducer, typename Next>
110class UniformReducerAdapter : public Next {
111 public:
112 template <Opcode opcode, typename Continuation, typename... Args>
113 auto ReduceOperation(Args... args) {
114 return Continuation{this}.Reduce(args...);
115 }
116
117 template <typename Op, typename Continuation>
118 auto ReduceInputGraphOperation(OpIndex ig_index, const Op& operation) {
119 return Continuation{this}.ReduceInputGraph(ig_index, operation);
120 }
121
122#define REDUCE(op) \
123 struct Reduce##op##Continuation final { \
124 explicit Reduce##op##Continuation(Next* _this) : this_(_this) {} \
125 using Op = op##Op; \
126 auto ReduceInputGraph(OpIndex ig_index, const op##Op& operation) { \
127 return this_->ReduceInputGraph##op(ig_index, operation); \
128 } \
129 template <typename... Args> \
130 auto Reduce(Args... args) const { \
131 return this_->Reduce##op(args...); \
132 } \
133 Next* this_; \
134 }; \
135 auto ReduceInputGraph##op(OpIndex ig_index, const op##Op& operation) { \
136 return static_cast<Reducer<Next>*>(this) \
137 ->template ReduceInputGraphOperation<op##Op, \
138 Reduce##op##Continuation>( \
139 ig_index, operation); \
140 } \
141 template <typename... Args> \
142 auto Reduce##op(Args... args) { \
143 return static_cast<Reducer<Next>*>(this) \
144 ->template ReduceOperation<Opcode::k##op, Reduce##op##Continuation>( \
145 args...); \
146 }
148#undef REDUCE
149};
150
151} // namespace v8::internal::compiler::turboshaft
152
153#endif // V8_COMPILER_TURBOSHAFT_UNIFORM_REDUCER_ADAPTER_H_
#define REDUCE(operation)
auto ReduceInputGraphOperation(OpIndex ig_index, const Op &operation)
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
#define TURBOSHAFT_OPERATION_LIST(V)
Definition operations.h:362