OLD | NEW |
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 16 matching lines...) Expand all Loading... |
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 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { | 32 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { |
33 return BinaryOperationHints::kAny; | 33 return BinaryOperationHints::kAny; |
34 } | 34 } |
35 DCHECK_NE(0, node_->op()->ControlOutputCount()); | 35 DCHECK_NE(0, node_->op()->ControlOutputCount()); |
36 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 36 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
37 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op())); | 37 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); |
38 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); | 38 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); |
39 BinaryOperationHints::Hint combined = hints.combined(); | 39 BinaryOperationHints::Hint combined = hints.combined(); |
40 if (combined == BinaryOperationHints::kSignedSmall || | 40 if (combined == BinaryOperationHints::kSignedSmall || |
41 combined == BinaryOperationHints::kSigned32 || | 41 combined == BinaryOperationHints::kSigned32 || |
42 combined == BinaryOperationHints::kNumberOrUndefined) { | 42 combined == BinaryOperationHints::kNumberOrUndefined) { |
43 return combined; | 43 return combined; |
44 } | 44 } |
45 return BinaryOperationHints::kAny; | 45 return BinaryOperationHints::kAny; |
46 } | 46 } |
47 | 47 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); | 148 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); |
149 DCHECK_EQ(1, op->ControlInputCount()); | 149 DCHECK_EQ(1, op->ControlInputCount()); |
150 DCHECK_EQ(0, op->ControlOutputCount()); | 150 DCHECK_EQ(0, op->ControlOutputCount()); |
151 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); | 151 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); |
152 DCHECK_EQ(2, op->ValueInputCount()); | 152 DCHECK_EQ(2, op->ValueInputCount()); |
153 | 153 |
154 DCHECK_EQ(1, node_->op()->EffectInputCount()); | 154 DCHECK_EQ(1, node_->op()->EffectInputCount()); |
155 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 155 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
156 DCHECK_EQ(1, node_->op()->ControlInputCount()); | 156 DCHECK_EQ(1, node_->op()->ControlInputCount()); |
157 DCHECK_LT(1, node_->op()->ControlOutputCount()); | 157 DCHECK_LT(1, node_->op()->ControlOutputCount()); |
158 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op())); | 158 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); |
159 DCHECK_EQ(2, node_->op()->ValueInputCount()); | 159 DCHECK_EQ(2, node_->op()->ValueInputCount()); |
160 | 160 |
161 // Reconnect the control output to bypass the IfSuccess node and | 161 // Reconnect the control output to bypass the IfSuccess node and |
162 // possibly disconnect from the IfException node. | 162 // possibly disconnect from the IfException node. |
163 for (Edge edge : node_->use_edges()) { | 163 for (Edge edge : node_->use_edges()) { |
164 Node* const user = edge.from(); | 164 Node* const user = edge.from(); |
165 DCHECK(!user->IsDead()); | 165 DCHECK(!user->IsDead()); |
166 if (NodeProperties::IsControlEdge(edge)) { | 166 if (NodeProperties::IsControlEdge(edge)) { |
167 if (user->opcode() == IrOpcode::kIfSuccess) { | 167 if (user->opcode() == IrOpcode::kIfSuccess) { |
168 user->ReplaceUses(NodeProperties::GetControlInput(node_)); | 168 user->ReplaceUses(NodeProperties::GetControlInput(node_)); |
169 user->Kill(); | 169 user->Kill(); |
170 } else { | 170 } else { |
171 DCHECK_EQ(user->opcode(), IrOpcode::kIfException); | 171 DCHECK_EQ(user->opcode(), IrOpcode::kIfException); |
172 edge.UpdateTo(jsgraph()->Dead()); | 172 edge.UpdateTo(jsgraph()->Dead()); |
173 } | 173 } |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
177 // Remove both bailout frame states and the context. | 177 // Remove both bailout frame states and the context. |
178 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_) + 1); | 178 if (OperatorProperties::GetFrameStateInputCount(node_->op()) == 2) { |
| 179 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_) + 1); |
| 180 } |
179 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); | 181 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); |
180 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); | 182 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); |
181 | 183 |
182 NodeProperties::ChangeOp(node_, op); | 184 NodeProperties::ChangeOp(node_, op); |
183 | 185 |
184 // Update the type to number. | 186 // Update the type to number. |
185 Type* node_type = NodeProperties::GetType(node_); | 187 Type* node_type = NodeProperties::GetType(node_); |
186 NodeProperties::SetType(node_, | 188 NodeProperties::SetType(node_, |
187 Type::Intersect(node_type, upper_bound, zone())); | 189 Type::Intersect(node_type, upper_bound, zone())); |
188 | 190 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 JSOperatorBuilder* javascript() { return lowering_->javascript(); } | 225 JSOperatorBuilder* javascript() { return lowering_->javascript(); } |
224 MachineOperatorBuilder* machine() { return lowering_->machine(); } | 226 MachineOperatorBuilder* machine() { return lowering_->machine(); } |
225 CommonOperatorBuilder* common() { return jsgraph()->common(); } | 227 CommonOperatorBuilder* common() { return jsgraph()->common(); } |
226 Zone* zone() const { return graph()->zone(); } | 228 Zone* zone() const { return graph()->zone(); } |
227 | 229 |
228 private: | 230 private: |
229 JSTypedLowering* lowering_; // The containing lowering instance. | 231 JSTypedLowering* lowering_; // The containing lowering instance. |
230 Node* node_; // The original node. | 232 Node* node_; // The original node. |
231 | 233 |
232 Node* CreateFrameStateForLeftInput() { | 234 Node* CreateFrameStateForLeftInput() { |
| 235 if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) { |
| 236 // Deoptimization is disabled => return dummy frame state instead. |
| 237 Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0); |
| 238 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); |
| 239 return dummy_state; |
| 240 } |
| 241 |
233 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); | 242 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); |
234 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 243 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
235 | 244 |
236 if (state_info.bailout_id() == BailoutId::None()) { | 245 if (state_info.bailout_id() == BailoutId::None()) { |
237 // Dummy frame state => just leave it as is. | 246 // Dummy frame state => just leave it as is. |
238 return frame_state; | 247 return frame_state; |
239 } | 248 } |
240 | 249 |
241 // If the frame state is already the right one, just return it. | 250 // If the frame state is already the right one, just return it. |
242 if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt && | 251 if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt && |
(...skipping 11 matching lines...) Expand all Loading... |
254 return graph()->NewNode(op, | 263 return graph()->NewNode(op, |
255 frame_state->InputAt(kFrameStateParametersInput), | 264 frame_state->InputAt(kFrameStateParametersInput), |
256 frame_state->InputAt(kFrameStateLocalsInput), | 265 frame_state->InputAt(kFrameStateLocalsInput), |
257 frame_state->InputAt(kFrameStateStackInput), | 266 frame_state->InputAt(kFrameStateStackInput), |
258 frame_state->InputAt(kFrameStateContextInput), | 267 frame_state->InputAt(kFrameStateContextInput), |
259 frame_state->InputAt(kFrameStateFunctionInput), | 268 frame_state->InputAt(kFrameStateFunctionInput), |
260 frame_state->InputAt(kFrameStateOuterStateInput)); | 269 frame_state->InputAt(kFrameStateOuterStateInput)); |
261 } | 270 } |
262 | 271 |
263 Node* CreateFrameStateForRightInput(Node* converted_left) { | 272 Node* CreateFrameStateForRightInput(Node* converted_left) { |
| 273 if (OperatorProperties::GetFrameStateInputCount(node_->op()) < 2) { |
| 274 // Deoptimization is disabled => return dummy frame state instead. |
| 275 Node* dummy_state = NodeProperties::GetFrameStateInput(node_, 0); |
| 276 DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone()); |
| 277 return dummy_state; |
| 278 } |
| 279 |
264 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); | 280 Node* frame_state = NodeProperties::GetFrameStateInput(node_, 1); |
265 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 281 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
266 | 282 |
267 if (state_info.bailout_id() == BailoutId::None()) { | 283 if (state_info.bailout_id() == BailoutId::None()) { |
268 // Dummy frame state => just leave it as is. | 284 // Dummy frame state => just leave it as is. |
269 return frame_state; | 285 return frame_state; |
270 } | 286 } |
271 | 287 |
272 // Create a frame state that stores the result of the operation to the | 288 // Create a frame state that stores the result of the operation to the |
273 // top of the stack (i.e., the slot used for the right operand). | 289 // top of the stack (i.e., the slot used for the right operand). |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { | 525 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { |
510 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 526 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
511 JSBinopReduction r(this, node); | 527 JSBinopReduction r(this, node); |
512 | 528 |
513 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 529 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
514 if (feedback != BinaryOperationHints::kAny) { | 530 if (feedback != BinaryOperationHints::kAny) { |
515 return r.ChangeToSpeculativeOperator( | 531 return r.ChangeToSpeculativeOperator( |
516 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); | 532 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); |
517 } | 533 } |
518 | 534 |
519 r.ConvertInputsToNumber(); | 535 // If deoptimization is enabled we rely on type feedback. |
520 return r.ChangeToPureOperator(simplified()->NumberMultiply(), Type::Number()); | 536 if (r.BothInputsAre(Type::PlainPrimitive()) || |
| 537 !(flags() & kDeoptimizationEnabled)) { |
| 538 r.ConvertInputsToNumber(); |
| 539 return r.ChangeToPureOperator(simplified()->NumberMultiply(), |
| 540 Type::Number()); |
| 541 } |
| 542 |
| 543 return NoChange(); |
521 } | 544 } |
522 | 545 |
523 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { | 546 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { |
524 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 547 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
525 JSBinopReduction r(this, node); | 548 JSBinopReduction r(this, node); |
526 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 549 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
527 if (feedback != BinaryOperationHints::kAny) { | 550 if (feedback != BinaryOperationHints::kAny) { |
528 return r.ChangeToSpeculativeOperator( | 551 return r.ChangeToSpeculativeOperator( |
529 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); | 552 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); |
530 } | 553 } |
(...skipping 1486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 } | 2040 } |
2018 | 2041 |
2019 | 2042 |
2020 CompilationDependencies* JSTypedLowering::dependencies() const { | 2043 CompilationDependencies* JSTypedLowering::dependencies() const { |
2021 return dependencies_; | 2044 return dependencies_; |
2022 } | 2045 } |
2023 | 2046 |
2024 } // namespace compiler | 2047 } // namespace compiler |
2025 } // namespace internal | 2048 } // namespace internal |
2026 } // namespace v8 | 2049 } // namespace v8 |
OLD | NEW |