v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
required-optimization-reducer.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_REQUIRED_OPTIMIZATION_REDUCER_H_
6#define V8_COMPILER_TURBOSHAFT_REQUIRED_OPTIMIZATION_REDUCER_H_
7
10
12
14
15// The RequiredOptimizationReducer performs reductions that might be needed for
16// correctness, because instruction selection or other reducers rely on it. In
17// particular, we have the following dependencies:
18// - VariableReducer can introduce phi nodes for call target constants, which
19// have to be reduced in order for instruction selection to detect the call
20// target. So we have to run RequiredOptimizationReducer at least once after
21// every occurence of VariableReducer.
22// - Loop peeling/unrolling can introduce phi nodes for RttCanons, which have
23// to be reduced to aid `WasmGCTypedOptimizationReducer` resolve type
24// indices corresponding to RttCanons.
25template <class Next>
26class RequiredOptimizationReducer : public Next {
27 public:
28 TURBOSHAFT_REDUCER_BOILERPLATE(RequiredOptimization)
29
30 OpIndex REDUCE(Phi)(base::Vector<const OpIndex> inputs,
32 LABEL_BLOCK(no_change) { return Next::ReducePhi(inputs, rep); }
33 if (inputs.size() == 0) goto no_change;
34 OpIndex first = inputs.first();
35 bool same_inputs = true;
36 for (const OpIndex& input : inputs.SubVectorFrom(1)) {
37 if (input != first) {
38 same_inputs = false;
39 break;
40 }
41 }
42 if (same_inputs) {
43 return first;
44 }
45 if (const ConstantOp* first_constant =
46 __ Get(first).template TryCast<ConstantOp>()) {
47 for (const OpIndex& input : inputs.SubVectorFrom(1)) {
48 const ConstantOp* maybe_constant =
49 __ Get(input).template TryCast<ConstantOp>();
50 if (!(maybe_constant && *maybe_constant == *first_constant)) {
51 goto no_change;
52 }
53 }
54 // If all of the predecessors are the same Constant, then we re-emit
55 // this Constant rather than emitting a Phi. This is a good idea in
56 // general, but is in particular needed for Constant that are used as
57 // call target: if they were merged into a Phi, this would result in an
58 // indirect call rather than a direct one, which:
59 // - is probably slower than a direct call in general
60 // - is probably not supported for builtins on 32-bit architectures.
61 return __ ReduceConstant(first_constant->kind, first_constant->storage);
62 }
63#if V8_ENABLE_WEBASSEMBLY
64 if (const RttCanonOp* first_rtt =
65 __ Get(first).template TryCast<RttCanonOp>()) {
66 for (const OpIndex& input : inputs.SubVectorFrom(1)) {
67 const RttCanonOp* maybe_rtt =
68 __ Get(input).template TryCast<RttCanonOp>();
69 if (!(maybe_rtt && maybe_rtt->rtts() == first_rtt->rtts() &&
70 maybe_rtt->type_index == first_rtt->type_index)) {
71 goto no_change;
72 }
73 }
74 // If all of the predecessors are the same RttCanon, then we re-emit this
75 // RttCanon rather than emitting a Phi. This helps the subsequent
76 // phases (in particular, `WasmGCTypedOptimizationReducer`) to resolve the
77 // type index corresponding to an RttCanon.
78 // Note: this relies on all RttCanons having the same `rtts()` input,
79 // which is the case due to instance field caching during graph
80 // generation.
81 // TODO(manoskouk): Can we generalize these two (and possibly more) cases?
82 return __ ReduceRttCanon(first_rtt->rtts(), first_rtt->type_index);
83 }
84#endif
85 goto no_change;
86 }
87};
88
90
91} // namespace v8::internal::compiler::turboshaft
92
93#endif // V8_COMPILER_TURBOSHAFT_REQUIRED_OPTIMIZATION_REDUCER_H_
#define REDUCE(operation)
OpIndex REDUCE Phi(base::Vector< const OpIndex > inputs, RegisterRepresentation rep)
#define TURBOSHAFT_REDUCER_BOILERPLATE(Name)
Definition assembler.h:823
#define LABEL_BLOCK(label)
Definition assembler.h:910
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
Definition graph.h:1231
bool TryCast(Tagged< From > value, Tagged< To > *out)
Definition casting.h:77