Line data Source code
1 : // Copyright 2017 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_JS_TYPE_HINT_LOWERING_H_
6 : #define V8_COMPILER_JS_TYPE_HINT_LOWERING_H_
7 :
8 : #include "src/base/flags.h"
9 : #include "src/compiler/graph-reducer.h"
10 : #include "src/deoptimize-reason.h"
11 : #include "src/handles.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // Forward declarations.
17 : class FeedbackNexus;
18 : class FeedbackSlot;
19 :
20 : namespace compiler {
21 :
22 : // Forward declarations.
23 : class JSGraph;
24 : class Node;
25 : class Operator;
26 :
27 : // The type-hint lowering consumes feedback about high-level operations in order
28 : // to potentially emit nodes using speculative simplified operators in favor of
29 : // the generic JavaScript operators.
30 : //
31 : // This lowering is implemented as an early reduction and can be applied before
32 : // nodes are placed into the initial graph. It provides the ability to shortcut
33 : // the JavaScript-level operators and directly emit simplified-level operators
34 : // even during initial graph building. This is the reason this lowering doesn't
35 : // follow the interface of the reducer framework used after graph construction.
36 : // The result of the lowering is encapsulated in
37 : // {the JSTypeHintLowering::LoweringResult} class.
38 : class JSTypeHintLowering {
39 : public:
40 : // Flags that control the mode of operation.
41 : enum Flag { kNoFlags = 0u, kBailoutOnUninitialized = 1u << 1 };
42 : using Flags = base::Flags<Flag>;
43 :
44 : JSTypeHintLowering(JSGraph* jsgraph, Handle<FeedbackVector> feedback_vector,
45 : Flags flags);
46 :
47 : // {LoweringResult} describes the result of lowering. The following outcomes
48 : // are possible:
49 : //
50 : // - operation was lowered to a side-effect-free operation, the resulting
51 : // value, effect and control can be obtained by the {value}, {effect} and
52 : // {control} methods.
53 : //
54 : // - operation was lowered to a graph exit (deoptimization). The caller
55 : // should connect {effect} and {control} nodes to the end.
56 : //
57 : // - no lowering happened. The caller needs to create the generic version
58 : // of the operation.
59 : class LoweringResult {
60 : public:
61 : Node* value() const { return value_; }
62 : Node* effect() const { return effect_; }
63 : Node* control() const { return control_; }
64 :
65 : bool Changed() const { return kind_ != LoweringResultKind::kNoChange; }
66 : bool IsExit() const { return kind_ == LoweringResultKind::kExit; }
67 : bool IsSideEffectFree() const {
68 : return kind_ == LoweringResultKind::kSideEffectFree;
69 : }
70 :
71 : static LoweringResult SideEffectFree(Node* value, Node* effect,
72 : Node* control) {
73 : DCHECK_NOT_NULL(effect);
74 : DCHECK_NOT_NULL(control);
75 : return LoweringResult(LoweringResultKind::kSideEffectFree, value, effect,
76 : control);
77 : }
78 :
79 : static LoweringResult NoChange() {
80 : return LoweringResult(LoweringResultKind::kNoChange, nullptr, nullptr,
81 : nullptr);
82 : }
83 :
84 : static LoweringResult Exit(Node* control) {
85 : return LoweringResult(LoweringResultKind::kExit, nullptr, nullptr,
86 : control);
87 : }
88 :
89 : private:
90 : enum class LoweringResultKind { kNoChange, kSideEffectFree, kExit };
91 :
92 : LoweringResult(LoweringResultKind kind, Node* value, Node* effect,
93 : Node* control)
94 725729 : : kind_(kind), value_(value), effect_(effect), control_(control) {}
95 :
96 : LoweringResultKind kind_;
97 : Node* value_;
98 : Node* effect_;
99 : Node* control_;
100 : };
101 :
102 : // Potential reduction of unary operations (e.g. negation).
103 : LoweringResult ReduceUnaryOperation(const Operator* op, Node* operand,
104 : Node* effect, Node* control,
105 : FeedbackSlot slot) const;
106 :
107 : // Potential reduction of binary (arithmetic, logical, shift and relational
108 : // comparison) operations.
109 : LoweringResult ReduceBinaryOperation(const Operator* op, Node* left,
110 : Node* right, Node* effect, Node* control,
111 : FeedbackSlot slot) const;
112 :
113 : // Potential reduction to for..in operations
114 : LoweringResult ReduceForInNextOperation(Node* receiver, Node* cache_array,
115 : Node* cache_type, Node* index,
116 : Node* effect, Node* control,
117 : FeedbackSlot slot) const;
118 : LoweringResult ReduceForInPrepareOperation(Node* enumerator, Node* effect,
119 : Node* control,
120 : FeedbackSlot slot) const;
121 :
122 : // Potential reduction to ToNumber operations
123 : LoweringResult ReduceToNumberOperation(Node* value, Node* effect,
124 : Node* control,
125 : FeedbackSlot slot) const;
126 :
127 : // Potential reduction of call operations.
128 : LoweringResult ReduceCallOperation(const Operator* op, Node* const* args,
129 : int arg_count, Node* effect, Node* control,
130 : FeedbackSlot slot) const;
131 :
132 : // Potential reduction of construct operations.
133 : LoweringResult ReduceConstructOperation(const Operator* op, Node* const* args,
134 : int arg_count, Node* effect,
135 : Node* control,
136 : FeedbackSlot slot) const;
137 : // Potential reduction of property access operations.
138 : LoweringResult ReduceLoadNamedOperation(const Operator* op, Node* obj,
139 : Node* effect, Node* control,
140 : FeedbackSlot slot) const;
141 : LoweringResult ReduceLoadKeyedOperation(const Operator* op, Node* obj,
142 : Node* key, Node* effect,
143 : Node* control,
144 : FeedbackSlot slot) const;
145 : LoweringResult ReduceStoreNamedOperation(const Operator* op, Node* obj,
146 : Node* val, Node* effect,
147 : Node* control,
148 : FeedbackSlot slot) const;
149 : LoweringResult ReduceStoreKeyedOperation(const Operator* op, Node* obj,
150 : Node* key, Node* val, Node* effect,
151 : Node* control,
152 : FeedbackSlot slot) const;
153 :
154 : private:
155 : friend class JSSpeculativeBinopBuilder;
156 : Node* TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect, Node* control,
157 : DeoptimizeReason reson) const;
158 :
159 : JSGraph* jsgraph() const { return jsgraph_; }
160 : Isolate* isolate() const;
161 : Flags flags() const { return flags_; }
162 : const Handle<FeedbackVector>& feedback_vector() const {
163 : return feedback_vector_;
164 : }
165 :
166 : JSGraph* jsgraph_;
167 : Flags const flags_;
168 : Handle<FeedbackVector> feedback_vector_;
169 :
170 : DISALLOW_COPY_AND_ASSIGN(JSTypeHintLowering);
171 : };
172 :
173 : } // namespace compiler
174 : } // namespace internal
175 : } // namespace v8
176 :
177 : #endif // V8_COMPILER_JS_TYPE_HINT_LOWERING_H_
|