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 |