OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 Node** effect, Node** control) { | 302 Node** effect, Node** control) { |
303 // If the node needs to be wired into the effect/control chain, do this | 303 // If the node needs to be wired into the effect/control chain, do this |
304 // here. Pass current frame state for lowering to eager deoptimization. | 304 // here. Pass current frame state for lowering to eager deoptimization. |
305 if (TryWireInStateEffect(node, *frame_state, effect, control)) { | 305 if (TryWireInStateEffect(node, *frame_state, effect, control)) { |
306 return; | 306 return; |
307 } | 307 } |
308 | 308 |
309 // If the node has a visible effect, then there must be a checkpoint in the | 309 // If the node has a visible effect, then there must be a checkpoint in the |
310 // effect chain before we are allowed to place another eager deoptimization | 310 // effect chain before we are allowed to place another eager deoptimization |
311 // point. We zap the frame state to ensure this invariant is maintained. | 311 // point. We zap the frame state to ensure this invariant is maintained. |
312 if (!node->op()->HasProperty(Operator::kNoWrite)) *frame_state = nullptr; | 312 if (region_observability_ == RegionObservability::kObservable && |
| 313 !node->op()->HasProperty(Operator::kNoWrite)) { |
| 314 *frame_state = nullptr; |
| 315 } |
313 | 316 |
314 // Remove the end markers of 'atomic' allocation region because the | 317 // Remove the end markers of 'atomic' allocation region because the |
315 // region should be wired-in now. | 318 // region should be wired-in now. |
316 if (node->opcode() == IrOpcode::kFinishRegion || | 319 if (node->opcode() == IrOpcode::kFinishRegion) { |
317 node->opcode() == IrOpcode::kBeginRegion) { | 320 // Reset the current region observability. |
| 321 region_observability_ = RegionObservability::kObservable; |
318 // Update the value uses to the value input of the finish node and | 322 // Update the value uses to the value input of the finish node and |
319 // the effect uses to the effect input. | 323 // the effect uses to the effect input. |
320 return RemoveRegionNode(node); | 324 return RemoveRegionNode(node); |
| 325 } |
| 326 if (node->opcode() == IrOpcode::kBeginRegion) { |
| 327 // Determine the observability for this region and use that for all |
| 328 // nodes inside the region (i.e. ignore the absence of kNoWrite on |
| 329 // StoreField and other operators). |
| 330 DCHECK_NE(RegionObservability::kNotObservable, region_observability_); |
| 331 region_observability_ = RegionObservabilityOf(node->op()); |
| 332 // Update the value uses to the value input of the finish node and |
| 333 // the effect uses to the effect input. |
| 334 return RemoveRegionNode(node); |
321 } | 335 } |
322 | 336 |
323 // Special treatment for checkpoint nodes. | 337 // Special treatment for checkpoint nodes. |
324 if (node->opcode() == IrOpcode::kCheckpoint) { | 338 if (node->opcode() == IrOpcode::kCheckpoint) { |
325 // Unlink the check point; effect uses will be updated to the incoming | 339 // Unlink the check point; effect uses will be updated to the incoming |
326 // effect that is passed. The frame state is preserved for lowering. | 340 // effect that is passed. The frame state is preserved for lowering. |
| 341 DCHECK_EQ(RegionObservability::kObservable, region_observability_); |
327 *frame_state = NodeProperties::GetFrameStateInput(node, 0); | 342 *frame_state = NodeProperties::GetFrameStateInput(node, 0); |
328 node->TrimInputCount(0); | 343 node->TrimInputCount(0); |
329 return; | 344 return; |
330 } | 345 } |
331 | 346 |
332 if (node->opcode() == IrOpcode::kIfSuccess) { | 347 if (node->opcode() == IrOpcode::kIfSuccess) { |
333 // We always schedule IfSuccess with its call, so skip it here. | 348 // We always schedule IfSuccess with its call, so skip it here. |
334 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); | 349 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); |
335 // The IfSuccess node should not belong to an exceptional call node | 350 // The IfSuccess node should not belong to an exceptional call node |
336 // because such IfSuccess nodes should only start a basic block (and | 351 // because such IfSuccess nodes should only start a basic block (and |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 break; | 427 break; |
413 case IrOpcode::kChangeTaggedToFloat64: | 428 case IrOpcode::kChangeTaggedToFloat64: |
414 state = LowerChangeTaggedToFloat64(node, *effect, *control); | 429 state = LowerChangeTaggedToFloat64(node, *effect, *control); |
415 break; | 430 break; |
416 case IrOpcode::kTruncateTaggedToFloat64: | 431 case IrOpcode::kTruncateTaggedToFloat64: |
417 state = LowerTruncateTaggedToFloat64(node, *effect, *control); | 432 state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
418 break; | 433 break; |
419 case IrOpcode::kCheckBounds: | 434 case IrOpcode::kCheckBounds: |
420 state = LowerCheckBounds(node, frame_state, *effect, *control); | 435 state = LowerCheckBounds(node, frame_state, *effect, *control); |
421 break; | 436 break; |
| 437 case IrOpcode::kCheckTaggedPointer: |
| 438 state = LowerCheckTaggedPointer(node, frame_state, *effect, *control); |
| 439 break; |
| 440 case IrOpcode::kCheckTaggedSigned: |
| 441 state = LowerCheckTaggedSigned(node, frame_state, *effect, *control); |
| 442 break; |
422 case IrOpcode::kCheckedUint32ToInt32: | 443 case IrOpcode::kCheckedUint32ToInt32: |
423 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); | 444 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
424 break; | 445 break; |
425 case IrOpcode::kCheckedFloat64ToInt32: | 446 case IrOpcode::kCheckedFloat64ToInt32: |
426 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); | 447 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); |
427 break; | 448 break; |
428 case IrOpcode::kCheckedTaggedToInt32: | 449 case IrOpcode::kCheckedTaggedToInt32: |
429 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); | 450 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); |
430 break; | 451 break; |
431 case IrOpcode::kCheckedTaggedToFloat64: | 452 case IrOpcode::kCheckedTaggedToFloat64: |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, | 798 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, |
778 frame_state, effect, control); | 799 frame_state, effect, control); |
779 | 800 |
780 // Make sure the lowered node does not appear in any use lists. | 801 // Make sure the lowered node does not appear in any use lists. |
781 node->TrimInputCount(0); | 802 node->TrimInputCount(0); |
782 | 803 |
783 return ValueEffectControl(index, effect, control); | 804 return ValueEffectControl(index, effect, control); |
784 } | 805 } |
785 | 806 |
786 EffectControlLinearizer::ValueEffectControl | 807 EffectControlLinearizer::ValueEffectControl |
| 808 EffectControlLinearizer::LowerCheckTaggedPointer(Node* node, Node* frame_state, |
| 809 Node* effect, Node* control) { |
| 810 Node* value = node->InputAt(0); |
| 811 |
| 812 Node* check = ObjectIsSmi(value); |
| 813 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, |
| 814 frame_state, effect, control); |
| 815 |
| 816 // Make sure the lowered node does not appear in any use lists. |
| 817 node->TrimInputCount(0); |
| 818 |
| 819 return ValueEffectControl(value, effect, control); |
| 820 } |
| 821 |
| 822 EffectControlLinearizer::ValueEffectControl |
| 823 EffectControlLinearizer::LowerCheckTaggedSigned(Node* node, Node* frame_state, |
| 824 Node* effect, Node* control) { |
| 825 Node* value = node->InputAt(0); |
| 826 |
| 827 Node* check = ObjectIsSmi(value); |
| 828 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, |
| 829 frame_state, effect, control); |
| 830 |
| 831 // Make sure the lowered node does not appear in any use lists. |
| 832 node->TrimInputCount(0); |
| 833 |
| 834 return ValueEffectControl(value, effect, control); |
| 835 } |
| 836 |
| 837 EffectControlLinearizer::ValueEffectControl |
787 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, | 838 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
788 Node* frame_state, | 839 Node* frame_state, |
789 Node* effect, | 840 Node* effect, |
790 Node* control) { | 841 Node* control) { |
791 Node* value = node->InputAt(0); | 842 Node* value = node->InputAt(0); |
792 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); | 843 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
793 Node* is_safe = | 844 Node* is_safe = |
794 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); | 845 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
795 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, | 846 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, |
796 frame_state, effect, control); | 847 frame_state, effect, control); |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 1625 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
1575 Operator::kNoThrow); | 1626 Operator::kNoThrow); |
1576 to_number_operator_.set(common()->Call(desc)); | 1627 to_number_operator_.set(common()->Call(desc)); |
1577 } | 1628 } |
1578 return to_number_operator_.get(); | 1629 return to_number_operator_.get(); |
1579 } | 1630 } |
1580 | 1631 |
1581 } // namespace compiler | 1632 } // namespace compiler |
1582 } // namespace internal | 1633 } // namespace internal |
1583 } // namespace v8 | 1634 } // namespace v8 |
OLD | NEW |