Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 2020323004: [turbofan] Remove eager frame state from all nodes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_turbofan-checkpoint-3
Patch Set: Rebased. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-native-context-specialization.cc ('k') | src/compiler/node-properties.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/compilation-dependencies.h" 6 #include "src/compilation-dependencies.h"
7 #include "src/compiler/access-builder.h" 7 #include "src/compiler/access-builder.h"
8 #include "src/compiler/js-graph.h" 8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/js-typed-lowering.h" 9 #include "src/compiler/js-typed-lowering.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 13 matching lines...) Expand all
24 // functions for matching the types of inputs to an operation. 24 // functions for matching the types of inputs to an operation.
25 class JSBinopReduction final { 25 class JSBinopReduction final {
26 public: 26 public:
27 JSBinopReduction(JSTypedLowering* lowering, Node* node) 27 JSBinopReduction(JSTypedLowering* lowering, Node* node)
28 : lowering_(lowering), node_(node) {} 28 : lowering_(lowering), node_(node) {}
29 29
30 BinaryOperationHints::Hint GetNumberBinaryOperationFeedback() { 30 BinaryOperationHints::Hint GetNumberBinaryOperationFeedback() {
31 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 31 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
32 DCHECK_NE(0, node_->op()->ControlOutputCount()); 32 DCHECK_NE(0, node_->op()->ControlOutputCount());
33 DCHECK_EQ(1, node_->op()->EffectOutputCount()); 33 DCHECK_EQ(1, node_->op()->EffectOutputCount());
34 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); 34 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
35 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); 35 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
36 BinaryOperationHints::Hint combined = hints.combined(); 36 BinaryOperationHints::Hint combined = hints.combined();
37 if (combined == BinaryOperationHints::kSignedSmall || 37 if (combined == BinaryOperationHints::kSignedSmall ||
38 combined == BinaryOperationHints::kSigned32 || 38 combined == BinaryOperationHints::kSigned32 ||
39 combined == BinaryOperationHints::kNumberOrOddball) { 39 combined == BinaryOperationHints::kNumberOrOddball) {
40 return combined; 40 return combined;
41 } 41 }
42 } 42 }
43 return BinaryOperationHints::kAny; 43 return BinaryOperationHints::kAny;
44 } 44 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 144 DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
145 DCHECK_EQ(1, op->ControlInputCount()); 145 DCHECK_EQ(1, op->ControlInputCount());
146 DCHECK_EQ(0, op->ControlOutputCount()); 146 DCHECK_EQ(0, op->ControlOutputCount());
147 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); 147 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
148 DCHECK_EQ(2, op->ValueInputCount()); 148 DCHECK_EQ(2, op->ValueInputCount());
149 149
150 DCHECK_EQ(1, node_->op()->EffectInputCount()); 150 DCHECK_EQ(1, node_->op()->EffectInputCount());
151 DCHECK_EQ(1, node_->op()->EffectOutputCount()); 151 DCHECK_EQ(1, node_->op()->EffectOutputCount());
152 DCHECK_EQ(1, node_->op()->ControlInputCount()); 152 DCHECK_EQ(1, node_->op()->ControlInputCount());
153 DCHECK_LT(1, node_->op()->ControlOutputCount()); 153 DCHECK_LT(1, node_->op()->ControlOutputCount());
154 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); 154 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
155 DCHECK_EQ(2, node_->op()->ValueInputCount()); 155 DCHECK_EQ(2, node_->op()->ValueInputCount());
156 156
157 // Reconnect the control output to bypass the IfSuccess node and 157 // Reconnect the control output to bypass the IfSuccess node and
158 // possibly disconnect from the IfException node. 158 // possibly disconnect from the IfException node.
159 for (Edge edge : node_->use_edges()) { 159 for (Edge edge : node_->use_edges()) {
160 Node* const user = edge.from(); 160 Node* const user = edge.from();
161 DCHECK(!user->IsDead()); 161 DCHECK(!user->IsDead());
162 if (NodeProperties::IsControlEdge(edge)) { 162 if (NodeProperties::IsControlEdge(edge)) {
163 if (user->opcode() == IrOpcode::kIfSuccess) { 163 if (user->opcode() == IrOpcode::kIfSuccess) {
164 user->ReplaceUses(NodeProperties::GetControlInput(node_)); 164 user->ReplaceUses(NodeProperties::GetControlInput(node_));
165 user->Kill(); 165 user->Kill();
166 } else { 166 } else {
167 DCHECK_EQ(user->opcode(), IrOpcode::kIfException); 167 DCHECK_EQ(user->opcode(), IrOpcode::kIfException);
168 edge.UpdateTo(jsgraph()->Dead()); 168 edge.UpdateTo(jsgraph()->Dead());
169 } 169 }
170 } 170 }
171 } 171 }
172 172
173 // Remove both bailout frame states and the context. 173 // Remove the frame state and the context.
174 if (OperatorProperties::GetFrameStateInputCount(node_->op()) == 2) {
175 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_) + 1);
176 }
177 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); 174 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
178 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); 175 node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
179 176
180 NodeProperties::ChangeOp(node_, op); 177 NodeProperties::ChangeOp(node_, op);
181 178
182 // Update the type to number. 179 // Update the type to number.
183 Type* node_type = NodeProperties::GetType(node_); 180 Type* node_type = NodeProperties::GetType(node_);
184 NodeProperties::SetType(node_, 181 NodeProperties::SetType(node_,
185 Type::Intersect(node_type, upper_bound, zone())); 182 Type::Intersect(node_type, upper_bound, zone()));
186 183
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 JSGraph* jsgraph() { return lowering_->jsgraph(); } 217 JSGraph* jsgraph() { return lowering_->jsgraph(); }
221 JSOperatorBuilder* javascript() { return lowering_->javascript(); } 218 JSOperatorBuilder* javascript() { return lowering_->javascript(); }
222 CommonOperatorBuilder* common() { return jsgraph()->common(); } 219 CommonOperatorBuilder* common() { return jsgraph()->common(); }
223 Zone* zone() const { return graph()->zone(); } 220 Zone* zone() const { return graph()->zone(); }
224 221
225 private: 222 private:
226 JSTypedLowering* lowering_; // The containing lowering instance. 223 JSTypedLowering* lowering_; // The containing lowering instance.
227 Node* node_; // The original node. 224 Node* node_; // The original node.
228 225
229 Node* CreateFrameStateForLeftInput() { 226 Node* CreateFrameStateForLeftInput() {
230 if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) { 227 // Deoptimization is disabled => return dummy frame state instead.
231 // Deoptimization is disabled => return dummy frame state instead. 228 Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
232 Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0); 229 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
233 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 230 return dummy_state;
234 return dummy_state;
235 }
236
237 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1);
238 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
239
240 if (state_info.bailout_id() == BailoutId::None()) {
241 // Dummy frame state => just leave it as is.
242 return frame_state;
243 }
244
245 // If the frame state is already the right one, just return it.
246 if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt &&
247 state_info.state_combine().GetOffsetToPokeAt() == 1) {
248 return frame_state;
249 }
250
251 // Here, we smash the result of the conversion into the slot just below
252 // the stack top. This is the slot that full code uses to store the
253 // left operand.
254 const Operator* op = jsgraph()->common()->FrameState(
255 state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1),
256 state_info.function_info());
257
258 return graph()->NewNode(op,
259 frame_state->InputAt(kFrameStateParametersInput),
260 frame_state->InputAt(kFrameStateLocalsInput),
261 frame_state->InputAt(kFrameStateStackInput),
262 frame_state->InputAt(kFrameStateContextInput),
263 frame_state->InputAt(kFrameStateFunctionInput),
264 frame_state->InputAt(kFrameStateOuterStateInput));
265 } 231 }
266 232
267 Node* CreateFrameStateForRightInput(Node* converted_left) { 233 Node* CreateFrameStateForRightInput(Node* converted_left) {
268 if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) { 234 // Deoptimization is disabled => return dummy frame state instead.
269 // Deoptimization is disabled => return dummy frame state instead. 235 Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
270 Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0); 236 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
271 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); 237 return dummy_state;
272 return dummy_state;
273 }
274
275 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1);
276 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
277
278 if (state_info.bailout_id() == BailoutId::None()) {
279 // Dummy frame state => just leave it as is.
280 return frame_state;
281 }
282
283 // Create a frame state that stores the result of the operation to the
284 // top of the stack (i.e., the slot used for the right operand).
285 const Operator* op = jsgraph()->common()->FrameState(
286 state_info.bailout_id(), OutputFrameStateCombine::PokeAt(0),
287 state_info.function_info());
288
289 // Change the left operand {converted_left} on the expression stack.
290 Node* stack = frame_state->InputAt(2);
291 DCHECK_EQ(stack->opcode(), IrOpcode::kStateValues);
292 DCHECK_GE(stack->InputCount(), 2);
293
294 // TODO(jarin) Allocate in a local zone or a reusable buffer.
295 NodeVector new_values(stack->InputCount(), zone());
296 for (int i = 0; i < stack->InputCount(); i++) {
297 if (i == stack->InputCount() - 2) {
298 new_values[i] = converted_left;
299 } else {
300 new_values[i] = stack->InputAt(i);
301 }
302 }
303 Node* new_stack =
304 graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front());
305
306 return graph()->NewNode(
307 op, frame_state->InputAt(kFrameStateParametersInput),
308 frame_state->InputAt(kFrameStateLocalsInput), new_stack,
309 frame_state->InputAt(kFrameStateContextInput),
310 frame_state->InputAt(kFrameStateFunctionInput),
311 frame_state->InputAt(kFrameStateOuterStateInput));
312 } 238 }
313 239
314 Node* ConvertPlainPrimitiveToNumber(Node* node) { 240 Node* ConvertPlainPrimitiveToNumber(Node* node) {
315 DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive())); 241 DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
316 // Avoid inserting too many eager ToNumber() operations. 242 // Avoid inserting too many eager ToNumber() operations.
317 Reduction const reduction = lowering_->ReduceJSToNumberInput(node); 243 Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
318 if (reduction.Changed()) return reduction.replacement(); 244 if (reduction.Changed()) return reduction.replacement();
319 if (NodeProperties::GetType(node)->Is(Type::Number())) { 245 if (NodeProperties::GetType(node)->Is(Type::Number())) {
320 return node; 246 return node;
321 } 247 }
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 } 953 }
1028 return NoChange(); 954 return NoChange();
1029 } 955 }
1030 956
1031 957
1032 Reduction JSTypedLowering::ReduceJSToObject(Node* node) { 958 Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
1033 DCHECK_EQ(IrOpcode::kJSToObject, node->opcode()); 959 DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
1034 Node* receiver = NodeProperties::GetValueInput(node, 0); 960 Node* receiver = NodeProperties::GetValueInput(node, 0);
1035 Type* receiver_type = NodeProperties::GetType(receiver); 961 Type* receiver_type = NodeProperties::GetType(receiver);
1036 Node* context = NodeProperties::GetContextInput(node); 962 Node* context = NodeProperties::GetContextInput(node);
1037 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); 963 Node* frame_state = NodeProperties::GetFrameStateInput(node);
1038 Node* effect = NodeProperties::GetEffectInput(node); 964 Node* effect = NodeProperties::GetEffectInput(node);
1039 Node* control = NodeProperties::GetControlInput(node); 965 Node* control = NodeProperties::GetControlInput(node);
1040 if (receiver_type->Is(Type::Receiver())) { 966 if (receiver_type->Is(Type::Receiver())) {
1041 ReplaceWithValue(node, receiver, effect, control); 967 ReplaceWithValue(node, receiver, effect, control);
1042 return Replace(receiver); 968 return Replace(receiver);
1043 } 969 }
1044 970
1045 // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks. 971 // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
1046 if (receiver_type->Maybe(Type::NullOrUndefined()) && 972 if (receiver_type->Maybe(Type::NullOrUndefined()) &&
1047 NodeProperties::IsExceptionalCall(node)) { 973 NodeProperties::IsExceptionalCall(node)) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 } 1155 }
1230 } 1156 }
1231 } 1157 }
1232 return NoChange(); 1158 return NoChange();
1233 } 1159 }
1234 1160
1235 1161
1236 Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { 1162 Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) {
1237 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode()); 1163 DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
1238 Node* const context = NodeProperties::GetContextInput(node); 1164 Node* const context = NodeProperties::GetContextInput(node);
1239 Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0); 1165 Node* const frame_state = NodeProperties::GetFrameStateInput(node);
1240 1166
1241 // If deoptimization is disabled, we cannot optimize. 1167 // If deoptimization is disabled, we cannot optimize.
1242 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 1168 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
1243 1169
1244 // If we are in a try block, don't optimize since the runtime call 1170 // If we are in a try block, don't optimize since the runtime call
1245 // in the proxy case can throw. 1171 // in the proxy case can throw.
1246 if (NodeProperties::IsExceptionalCall(node)) return NoChange(); 1172 if (NodeProperties::IsExceptionalCall(node)) return NoChange();
1247 1173
1248 JSBinopReduction r(this, node); 1174 JSBinopReduction r(this, node);
1249 Node* effect = r.effect(); 1175 Node* effect = r.effect();
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 } 1376 }
1451 1377
1452 1378
1453 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { 1379 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
1454 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); 1380 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
1455 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); 1381 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
1456 Node* receiver = NodeProperties::GetValueInput(node, 0); 1382 Node* receiver = NodeProperties::GetValueInput(node, 0);
1457 Type* receiver_type = NodeProperties::GetType(receiver); 1383 Type* receiver_type = NodeProperties::GetType(receiver);
1458 Node* context = NodeProperties::GetContextInput(node); 1384 Node* context = NodeProperties::GetContextInput(node);
1459 Type* context_type = NodeProperties::GetType(context); 1385 Type* context_type = NodeProperties::GetType(context);
1460 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); 1386 Node* frame_state = NodeProperties::GetFrameStateInput(node);
1461 Node* effect = NodeProperties::GetEffectInput(node); 1387 Node* effect = NodeProperties::GetEffectInput(node);
1462 Node* control = NodeProperties::GetControlInput(node); 1388 Node* control = NodeProperties::GetControlInput(node);
1463 if (!receiver_type->Is(Type::Receiver())) { 1389 if (!receiver_type->Is(Type::Receiver())) {
1464 if (receiver_type->Is(Type::NullOrUndefined()) || 1390 if (receiver_type->Is(Type::NullOrUndefined()) ||
1465 mode == ConvertReceiverMode::kNullOrUndefined) { 1391 mode == ConvertReceiverMode::kNullOrUndefined) {
1466 if (context_type->IsConstant()) { 1392 if (context_type->IsConstant()) {
1467 Handle<JSObject> global_proxy( 1393 Handle<JSObject> global_proxy(
1468 Handle<Context>::cast(context_type->AsConstant()->Value()) 1394 Handle<Context>::cast(context_type->AsConstant()->Value())
1469 ->global_proxy(), 1395 ->global_proxy(),
1470 isolate()); 1396 isolate());
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 } 1650 }
1725 1651
1726 1652
1727 Reduction JSTypedLowering::ReduceJSForInNext(Node* node) { 1653 Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
1728 DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode()); 1654 DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
1729 Node* receiver = NodeProperties::GetValueInput(node, 0); 1655 Node* receiver = NodeProperties::GetValueInput(node, 0);
1730 Node* cache_array = NodeProperties::GetValueInput(node, 1); 1656 Node* cache_array = NodeProperties::GetValueInput(node, 1);
1731 Node* cache_type = NodeProperties::GetValueInput(node, 2); 1657 Node* cache_type = NodeProperties::GetValueInput(node, 2);
1732 Node* index = NodeProperties::GetValueInput(node, 3); 1658 Node* index = NodeProperties::GetValueInput(node, 3);
1733 Node* context = NodeProperties::GetContextInput(node); 1659 Node* context = NodeProperties::GetContextInput(node);
1734 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); 1660 Node* frame_state = NodeProperties::GetFrameStateInput(node);
1735 Node* effect = NodeProperties::GetEffectInput(node); 1661 Node* effect = NodeProperties::GetEffectInput(node);
1736 Node* control = NodeProperties::GetControlInput(node); 1662 Node* control = NodeProperties::GetControlInput(node);
1737 1663
1738 // Load the next {key} from the {cache_array}. 1664 // Load the next {key} from the {cache_array}.
1739 Node* key = effect = graph()->NewNode( 1665 Node* key = effect = graph()->NewNode(
1740 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), 1666 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
1741 cache_array, index, effect, control); 1667 cache_array, index, effect, control);
1742 1668
1743 // Load the map of the {receiver}. 1669 // Load the map of the {receiver}.
1744 Node* receiver_map = effect = 1670 Node* receiver_map = effect =
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 } 2096 }
2171 2097
2172 2098
2173 CompilationDependencies* JSTypedLowering::dependencies() const { 2099 CompilationDependencies* JSTypedLowering::dependencies() const {
2174 return dependencies_; 2100 return dependencies_;
2175 } 2101 }
2176 2102
2177 } // namespace compiler 2103 } // namespace compiler
2178 } // namespace internal 2104 } // namespace internal
2179 } // namespace v8 2105 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.cc ('k') | src/compiler/node-properties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698