| 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/js-intrinsic-lowering.h" | 5 #include "src/compiler/js-intrinsic-lowering.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "src/code-factory.h" |
| 9 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| 10 #include "src/compiler/js-graph.h" | 11 #include "src/compiler/js-graph.h" |
| 12 #include "src/compiler/linkage.h" |
| 11 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
| 12 #include "src/compiler/node-properties.h" | 14 #include "src/compiler/node-properties.h" |
| 13 #include "src/compiler/operator-properties.h" | 15 #include "src/compiler/operator-properties.h" |
| 14 #include "src/counters.h" | 16 #include "src/counters.h" |
| 15 #include "src/objects-inl.h" | 17 #include "src/objects-inl.h" |
| 18 #include "src/type-cache.h" |
| 16 | 19 |
| 17 namespace v8 { | 20 namespace v8 { |
| 18 namespace internal { | 21 namespace internal { |
| 19 namespace compiler { | 22 namespace compiler { |
| 20 | 23 |
| 21 JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph, | 24 JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph, |
| 22 DeoptimizationMode mode) | 25 DeoptimizationMode mode) |
| 23 : AdvancedReducer(editor), jsgraph_(jsgraph), mode_(mode) {} | 26 : AdvancedReducer(editor), |
| 27 jsgraph_(jsgraph), |
| 28 mode_(mode), |
| 29 type_cache_(TypeCache::Get()) {} |
| 24 | 30 |
| 25 | 31 |
| 26 Reduction JSIntrinsicLowering::Reduce(Node* node) { | 32 Reduction JSIntrinsicLowering::Reduce(Node* node) { |
| 27 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); | 33 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); |
| 28 const Runtime::Function* const f = | 34 const Runtime::Function* const f = |
| 29 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); | 35 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); |
| 30 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); | 36 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); |
| 31 switch (f->function_id) { | 37 switch (f->function_id) { |
| 32 case Runtime::kInlineConstructDouble: | 38 case Runtime::kInlineConstructDouble: |
| 33 return ReduceConstructDouble(node); | 39 return ReduceConstructDouble(node); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 case Runtime::kInlineIsMinusZero: | 90 case Runtime::kInlineIsMinusZero: |
| 85 return ReduceIsMinusZero(node); | 91 return ReduceIsMinusZero(node); |
| 86 case Runtime::kInlineFixedArrayGet: | 92 case Runtime::kInlineFixedArrayGet: |
| 87 return ReduceFixedArrayGet(node); | 93 return ReduceFixedArrayGet(node); |
| 88 case Runtime::kInlineFixedArraySet: | 94 case Runtime::kInlineFixedArraySet: |
| 89 return ReduceFixedArraySet(node); | 95 return ReduceFixedArraySet(node); |
| 90 case Runtime::kInlineGetTypeFeedbackVector: | 96 case Runtime::kInlineGetTypeFeedbackVector: |
| 91 return ReduceGetTypeFeedbackVector(node); | 97 return ReduceGetTypeFeedbackVector(node); |
| 92 case Runtime::kInlineGetCallerJSFunction: | 98 case Runtime::kInlineGetCallerJSFunction: |
| 93 return ReduceGetCallerJSFunction(node); | 99 return ReduceGetCallerJSFunction(node); |
| 100 case Runtime::kInlineToInteger: |
| 101 return ReduceToInteger(node); |
| 102 case Runtime::kInlineToLength: |
| 103 return ReduceToLength(node); |
| 104 case Runtime::kInlineToName: |
| 105 return ReduceToName(node); |
| 106 case Runtime::kInlineToNumber: |
| 107 return ReduceToNumber(node); |
| 94 case Runtime::kInlineToObject: | 108 case Runtime::kInlineToObject: |
| 95 return ReduceToObject(node); | 109 return ReduceToObject(node); |
| 110 case Runtime::kInlineToPrimitive: |
| 111 return ReduceToPrimitive(node); |
| 112 case Runtime::kInlineToString: |
| 113 return ReduceToString(node); |
| 96 case Runtime::kInlineThrowNotDateError: | 114 case Runtime::kInlineThrowNotDateError: |
| 97 return ReduceThrowNotDateError(node); | 115 return ReduceThrowNotDateError(node); |
| 98 case Runtime::kInlineCallFunction: | 116 case Runtime::kInlineCallFunction: |
| 99 return ReduceCallFunction(node); | 117 return ReduceCallFunction(node); |
| 100 default: | 118 default: |
| 101 break; | 119 break; |
| 102 } | 120 } |
| 103 return NoChange(); | 121 return NoChange(); |
| 104 } | 122 } |
| 105 | 123 |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 Node* deoptimize = | 534 Node* deoptimize = |
| 517 graph()->NewNode(common()->Deoptimize(), frame_state, effect, control); | 535 graph()->NewNode(common()->Deoptimize(), frame_state, effect, control); |
| 518 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | 536 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
| 519 | 537 |
| 520 node->TrimInputCount(0); | 538 node->TrimInputCount(0); |
| 521 NodeProperties::ChangeOp(node, common()->Dead()); | 539 NodeProperties::ChangeOp(node, common()->Dead()); |
| 522 return Changed(node); | 540 return Changed(node); |
| 523 } | 541 } |
| 524 | 542 |
| 525 | 543 |
| 544 Reduction JSIntrinsicLowering::ReduceToInteger(Node* node) { |
| 545 Node* value = NodeProperties::GetValueInput(node, 0); |
| 546 Type* value_type = NodeProperties::GetType(value); |
| 547 if (value_type->Is(type_cache().kIntegerOrMinusZero)) { |
| 548 ReplaceWithValue(node, value); |
| 549 return Replace(value); |
| 550 } |
| 551 return NoChange(); |
| 552 } |
| 553 |
| 554 |
| 555 Reduction JSIntrinsicLowering::ReduceToName(Node* node) { |
| 556 NodeProperties::ChangeOp(node, javascript()->ToName()); |
| 557 return Changed(node); |
| 558 } |
| 559 |
| 560 |
| 561 Reduction JSIntrinsicLowering::ReduceToNumber(Node* node) { |
| 562 NodeProperties::ChangeOp(node, javascript()->ToNumber()); |
| 563 return Changed(node); |
| 564 } |
| 565 |
| 566 |
| 567 Reduction JSIntrinsicLowering::ReduceToLength(Node* node) { |
| 568 Node* value = NodeProperties::GetValueInput(node, 0); |
| 569 Type* value_type = NodeProperties::GetType(value); |
| 570 if (value_type->Is(type_cache().kIntegerOrMinusZero)) { |
| 571 if (value_type->Max() <= 0.0) { |
| 572 value = jsgraph()->ZeroConstant(); |
| 573 } else if (value_type->Min() >= kMaxSafeInteger) { |
| 574 value = jsgraph()->Constant(kMaxSafeInteger); |
| 575 } else { |
| 576 if (value_type->Min() <= 0.0) { |
| 577 value = graph()->NewNode( |
| 578 common()->Select(kMachAnyTagged), |
| 579 graph()->NewNode(simplified()->NumberLessThanOrEqual(), value, |
| 580 jsgraph()->ZeroConstant()), |
| 581 jsgraph()->ZeroConstant(), value); |
| 582 value_type = Type::Range(0.0, value_type->Max(), graph()->zone()); |
| 583 NodeProperties::SetType(value, value_type); |
| 584 } |
| 585 if (value_type->Max() > kMaxSafeInteger) { |
| 586 value = graph()->NewNode( |
| 587 common()->Select(kMachAnyTagged), |
| 588 graph()->NewNode(simplified()->NumberLessThanOrEqual(), |
| 589 jsgraph()->Constant(kMaxSafeInteger), value), |
| 590 jsgraph()->Constant(kMaxSafeInteger), value); |
| 591 value_type = |
| 592 Type::Range(value_type->Min(), kMaxSafeInteger, graph()->zone()); |
| 593 NodeProperties::SetType(value, value_type); |
| 594 } |
| 595 } |
| 596 ReplaceWithValue(node, value); |
| 597 return Replace(value); |
| 598 } |
| 599 Callable callable = CodeFactory::ToLength(isolate()); |
| 600 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
| 601 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 602 CallDescriptor::kNeedsFrameState, node->op()->properties()); |
| 603 node->InsertInput(graph()->zone(), 0, |
| 604 jsgraph()->HeapConstant(callable.code())); |
| 605 NodeProperties::ChangeOp(node, common()->Call(desc)); |
| 606 return Changed(node); |
| 607 } |
| 608 |
| 609 |
| 526 Reduction JSIntrinsicLowering::ReduceToObject(Node* node) { | 610 Reduction JSIntrinsicLowering::ReduceToObject(Node* node) { |
| 527 NodeProperties::ChangeOp(node, javascript()->ToObject()); | 611 NodeProperties::ChangeOp(node, javascript()->ToObject()); |
| 528 return Changed(node); | 612 return Changed(node); |
| 529 } | 613 } |
| 530 | 614 |
| 531 | 615 |
| 616 Reduction JSIntrinsicLowering::ReduceToPrimitive(Node* node) { |
| 617 Node* value = NodeProperties::GetValueInput(node, 0); |
| 618 Type* value_type = NodeProperties::GetType(value); |
| 619 if (value_type->Is(Type::Primitive())) { |
| 620 ReplaceWithValue(node, value); |
| 621 return Replace(value); |
| 622 } |
| 623 return NoChange(); |
| 624 } |
| 625 |
| 626 |
| 627 Reduction JSIntrinsicLowering::ReduceToString(Node* node) { |
| 628 NodeProperties::ChangeOp(node, javascript()->ToString()); |
| 629 return Changed(node); |
| 630 } |
| 631 |
| 632 |
| 532 Reduction JSIntrinsicLowering::ReduceCallFunction(Node* node) { | 633 Reduction JSIntrinsicLowering::ReduceCallFunction(Node* node) { |
| 533 CallRuntimeParameters params = CallRuntimeParametersOf(node->op()); | 634 CallRuntimeParameters params = CallRuntimeParametersOf(node->op()); |
| 534 size_t arity = params.arity(); | 635 size_t arity = params.arity(); |
| 535 Node* function = node->InputAt(static_cast<int>(arity - 1)); | 636 Node* function = node->InputAt(static_cast<int>(arity - 1)); |
| 536 while (--arity != 0) { | 637 while (--arity != 0) { |
| 537 node->ReplaceInput(static_cast<int>(arity), | 638 node->ReplaceInput(static_cast<int>(arity), |
| 538 node->InputAt(static_cast<int>(arity - 1))); | 639 node->InputAt(static_cast<int>(arity - 1))); |
| 539 } | 640 } |
| 540 node->ReplaceInput(0, function); | 641 node->ReplaceInput(0, function); |
| 541 NodeProperties::ChangeOp( | 642 NodeProperties::ChangeOp( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 | 685 |
| 585 Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) { | 686 Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) { |
| 586 ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect); | 687 ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect); |
| 587 return Changed(node); | 688 return Changed(node); |
| 588 } | 689 } |
| 589 | 690 |
| 590 | 691 |
| 591 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); } | 692 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); } |
| 592 | 693 |
| 593 | 694 |
| 695 Isolate* JSIntrinsicLowering::isolate() const { return jsgraph()->isolate(); } |
| 696 |
| 697 |
| 594 CommonOperatorBuilder* JSIntrinsicLowering::common() const { | 698 CommonOperatorBuilder* JSIntrinsicLowering::common() const { |
| 595 return jsgraph()->common(); | 699 return jsgraph()->common(); |
| 596 } | 700 } |
| 597 | 701 |
| 598 JSOperatorBuilder* JSIntrinsicLowering::javascript() const { | 702 JSOperatorBuilder* JSIntrinsicLowering::javascript() const { |
| 599 return jsgraph_->javascript(); | 703 return jsgraph_->javascript(); |
| 600 } | 704 } |
| 601 | 705 |
| 602 | 706 |
| 603 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { | 707 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { |
| 604 return jsgraph()->machine(); | 708 return jsgraph()->machine(); |
| 605 } | 709 } |
| 606 | 710 |
| 607 | 711 |
| 608 SimplifiedOperatorBuilder* JSIntrinsicLowering::simplified() const { | 712 SimplifiedOperatorBuilder* JSIntrinsicLowering::simplified() const { |
| 609 return jsgraph()->simplified(); | 713 return jsgraph()->simplified(); |
| 610 } | 714 } |
| 611 | 715 |
| 612 } // namespace compiler | 716 } // namespace compiler |
| 613 } // namespace internal | 717 } // namespace internal |
| 614 } // namespace v8 | 718 } // namespace v8 |
| OLD | NEW |