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 : typedef base::Flags<Flag> Flags;
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 789677 : : 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 binary (arithmetic, logical, shift and relational
103 : // comparison) operations.
104 : LoweringResult ReduceBinaryOperation(const Operator* op, Node* left,
105 : Node* right, Node* effect, Node* control,
106 : FeedbackSlot slot) const;
107 :
108 : // Potential reduction to for..in operations
109 : LoweringResult ReduceForInNextOperation(Node* receiver, Node* cache_array,
110 : Node* cache_type, Node* index,
111 : Node* effect, Node* control,
112 : FeedbackSlot slot) const;
113 : LoweringResult ReduceForInPrepareOperation(Node* enumerator, Node* effect,
114 : Node* control,
115 : FeedbackSlot slot) const;
116 :
117 : // Potential reduction to ToNumber operations
118 : LoweringResult ReduceToNumberOperation(Node* value, Node* effect,
119 : Node* control,
120 : FeedbackSlot slot) const;
121 :
122 : // Potential reduction of call operations.
123 : LoweringResult ReduceCallOperation(const Operator* op, Node* const* args,
124 : int arg_count, Node* effect, Node* control,
125 : FeedbackSlot slot) const;
126 :
127 : // Potential reduction of construct operations.
128 : LoweringResult ReduceConstructOperation(const Operator* op, Node* const* args,
129 : int arg_count, Node* effect,
130 : Node* control,
131 : FeedbackSlot slot) const;
132 : // Potential reduction of property access operations.
133 : LoweringResult ReduceLoadNamedOperation(const Operator* op, Node* obj,
134 : Node* effect, Node* control,
135 : FeedbackSlot slot) const;
136 : LoweringResult ReduceLoadKeyedOperation(const Operator* op, Node* obj,
137 : Node* key, Node* effect,
138 : Node* control,
139 : FeedbackSlot slot) const;
140 : LoweringResult ReduceStoreNamedOperation(const Operator* op, Node* obj,
141 : Node* val, Node* effect,
142 : Node* control,
143 : FeedbackSlot slot) const;
144 : LoweringResult ReduceStoreKeyedOperation(const Operator* op, Node* obj,
145 : Node* key, Node* val, Node* effect,
146 : Node* control,
147 : FeedbackSlot slot) const;
148 :
149 : private:
150 : friend class JSSpeculativeBinopBuilder;
151 : Node* TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect, Node* control,
152 : DeoptimizeReason reson) const;
153 :
154 : JSGraph* jsgraph() const { return jsgraph_; }
155 : Flags flags() const { return flags_; }
156 : const Handle<FeedbackVector>& feedback_vector() const {
157 : return feedback_vector_;
158 : }
159 :
160 : JSGraph* jsgraph_;
161 : Flags const flags_;
162 : Handle<FeedbackVector> feedback_vector_;
163 :
164 : DISALLOW_COPY_AND_ASSIGN(JSTypeHintLowering);
165 : };
166 :
167 : } // namespace compiler
168 : } // namespace internal
169 : } // namespace v8
170 :
171 : #endif // V8_COMPILER_JS_TYPE_HINT_LOWERING_H_
|