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

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

Issue 802353003: [turbofan] Cache conversions inserted during typed lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Use temp zone. Add missing ToNumber conversion. Created 6 years 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-typed-lowering.h ('k') | src/compiler/pipeline.cc » ('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/compiler/access-builder.h" 5 #include "src/compiler/access-builder.h"
6 #include "src/compiler/graph-inl.h" 6 #include "src/compiler/graph-inl.h"
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/node-aux-data-inl.h" 9 #include "src/compiler/node-aux-data-inl.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 11 matching lines...) Expand all
22 22
23 // Relax the effects of {node} by immediately replacing effect uses of {node} 23 // Relax the effects of {node} by immediately replacing effect uses of {node}
24 // with the effect input to {node}. 24 // with the effect input to {node}.
25 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. 25 // TODO(turbofan): replace the effect input to {node} with {graph->start()}.
26 // TODO(titzer): move into a GraphEditor? 26 // TODO(titzer): move into a GraphEditor?
27 static void RelaxEffects(Node* node) { 27 static void RelaxEffects(Node* node) {
28 NodeProperties::ReplaceWithValue(node, node, NULL); 28 NodeProperties::ReplaceWithValue(node, node, NULL);
29 } 29 }
30 30
31 31
32 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph) 32 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone)
33 : jsgraph_(jsgraph), simplified_(jsgraph->zone()) { 33 : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) {
34 Handle<Object> zero = factory()->NewNumber(0.0); 34 Handle<Object> zero = factory()->NewNumber(0.0);
35 Handle<Object> one = factory()->NewNumber(1.0); 35 Handle<Object> one = factory()->NewNumber(1.0);
36 zero_range_ = Type::Range(zero, zero, graph()->zone()); 36 zero_range_ = Type::Range(zero, zero, graph()->zone());
37 one_range_ = Type::Range(one, one, graph()->zone()); 37 one_range_ = Type::Range(one, one, graph()->zone());
38 Handle<Object> thirtyone = factory()->NewNumber(31.0); 38 Handle<Object> thirtyone = factory()->NewNumber(31.0);
39 zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone()); 39 zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone());
40 // TODO(jarin): Can we have a correctification of the stupid type system? 40 // TODO(jarin): Can we have a correctification of the stupid type system?
41 // These stupid work-arounds are just stupid! 41 // These stupid work-arounds are just stupid!
42 shifted_int32_ranges_[0] = Type::Signed32(); 42 shifted_int32_ranges_[0] = Type::Signed32();
43 if (SmiValuesAre31Bits()) { 43 if (SmiValuesAre31Bits()) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 // Avoid introducing too many eager ToString() operations. 188 // Avoid introducing too many eager ToString() operations.
189 Reduction reduced = lowering_->ReduceJSToStringInput(node); 189 Reduction reduced = lowering_->ReduceJSToStringInput(node);
190 if (reduced.Changed()) return reduced.replacement(); 190 if (reduced.Changed()) return reduced.replacement();
191 Node* n = graph()->NewNode(javascript()->ToString(), node, context(), 191 Node* n = graph()->NewNode(javascript()->ToString(), node, context(),
192 effect(), control()); 192 effect(), control());
193 update_effect(n); 193 update_effect(n);
194 return n; 194 return n;
195 } 195 }
196 196
197 Node* ConvertToNumber(Node* node) { 197 Node* ConvertToNumber(Node* node) {
198 // Avoid introducing too many eager ToNumber() operations. 198 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) {
199 Reduction reduced = lowering_->ReduceJSToNumberInput(node); 199 return lowering_->ConvertToNumber(node);
200 if (reduced.Changed()) return reduced.replacement(); 200 }
201 Node* n = graph()->NewNode(javascript()->ToNumber(), node, context(), 201 Node* n = graph()->NewNode(javascript()->ToNumber(), node, context(),
202 effect(), control()); 202 effect(), control());
203 update_effect(n); 203 update_effect(n);
204 return n; 204 return n;
205 } 205 }
206 206
207 Node* ConvertToUI32(Node* node, Signedness signedness) { 207 Node* ConvertToUI32(Node* node, Signedness signedness) {
208 // Avoid introducing too many eager NumberToXXnt32() operations. 208 // Avoid introducing too many eager NumberToXXnt32() operations.
209 node = ConvertToNumber(node); 209 node = ConvertToNumber(node);
210 Type* type = NodeProperties::GetBounds(node).upper; 210 Type* type = NodeProperties::GetBounds(node).upper;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 } 490 }
491 491
492 492
493 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { 493 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
494 if (input->opcode() == IrOpcode::kJSToBoolean) { 494 if (input->opcode() == IrOpcode::kJSToBoolean) {
495 // Recursively try to reduce the input first. 495 // Recursively try to reduce the input first.
496 Reduction result = ReduceJSToBoolean(input); 496 Reduction result = ReduceJSToBoolean(input);
497 if (result.Changed()) return result; 497 if (result.Changed()) return result;
498 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) 498 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x)
499 } 499 }
500 // Check if we have a cached conversion.
501 Node* conversion = FindConversion<IrOpcode::kJSToBoolean>(input);
502 if (conversion) return Replace(conversion);
500 Type* input_type = NodeProperties::GetBounds(input).upper; 503 Type* input_type = NodeProperties::GetBounds(input).upper;
501 if (input_type->Is(Type::Boolean())) { 504 if (input_type->Is(Type::Boolean())) {
502 return Changed(input); // JSToBoolean(x:boolean) => x 505 return Changed(input); // JSToBoolean(x:boolean) => x
503 } 506 }
504 if (input_type->Is(Type::Undefined())) { 507 if (input_type->Is(Type::Undefined())) {
505 // JSToBoolean(undefined) => #false 508 // JSToBoolean(undefined) => #false
506 return Replace(jsgraph()->FalseConstant()); 509 return Replace(jsgraph()->FalseConstant());
507 } 510 }
508 if (input_type->Is(Type::Null())) { 511 if (input_type->Is(Type::Null())) {
509 // JSToBoolean(null) => #false 512 // JSToBoolean(null) => #false
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 // JSToBoolean(phi(x1,...,xn,control),context) 550 // JSToBoolean(phi(x1,...,xn,control),context)
548 // => phi(JSToBoolean(x1,no-context),...,JSToBoolean(xn,no-context)) 551 // => phi(JSToBoolean(x1,no-context),...,JSToBoolean(xn,no-context))
549 int const input_count = input->InputCount() - 1; 552 int const input_count = input->InputCount() - 1;
550 Node* const control = input->InputAt(input_count); 553 Node* const control = input->InputAt(input_count);
551 DCHECK_LE(0, input_count); 554 DCHECK_LE(0, input_count);
552 DCHECK(NodeProperties::IsControl(control)); 555 DCHECK(NodeProperties::IsControl(control));
553 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean())); 556 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
554 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean())); 557 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
555 node->set_op(common()->Phi(kMachAnyTagged, input_count)); 558 node->set_op(common()->Phi(kMachAnyTagged, input_count));
556 for (int i = 0; i < input_count; ++i) { 559 for (int i = 0; i < input_count; ++i) {
557 Node* value = input->InputAt(i); 560 // We must be very careful not to introduce cycles when pushing
558 // Recursively try to reduce the value first. 561 // operations into phis. It is safe for {value}, since it appears
559 Reduction reduction = ReduceJSToBooleanInput(value); 562 // as input to the phi that we are replacing, but it's not safe
560 if (reduction.Changed()) { 563 // to simply reuse the context of the {node}. However, ToBoolean()
561 value = reduction.replacement(); 564 // does not require a context anyways, so it's safe to discard it
562 } else { 565 // here and pass the dummy context.
563 // We must be very careful not to introduce cycles when pushing 566 Node* const value = ConvertToBoolean(input->InputAt(i));
564 // operations into phis. It is safe for {value}, since it appears
565 // as input to the phi that we are replacing, but it's not safe
566 // to simply reuse the context of the {node}. However, ToBoolean()
567 // does not require a context anyways, so it's safe to discard it
568 // here and pass the dummy context.
569 value = graph()->NewNode(javascript()->ToBoolean(), value,
570 jsgraph()->NoContextConstant());
571 }
572 if (i < node->InputCount()) { 567 if (i < node->InputCount()) {
573 node->ReplaceInput(i, value); 568 node->ReplaceInput(i, value);
574 } else { 569 } else {
575 node->AppendInput(graph()->zone(), value); 570 node->AppendInput(graph()->zone(), value);
576 } 571 }
577 } 572 }
578 if (input_count < node->InputCount()) { 573 if (input_count < node->InputCount()) {
579 node->ReplaceInput(input_count, control); 574 node->ReplaceInput(input_count, control);
580 } else { 575 } else {
581 node->AppendInput(graph()->zone(), control); 576 node->AppendInput(graph()->zone(), control);
582 } 577 }
583 node->TrimInputCount(input_count + 1); 578 node->TrimInputCount(input_count + 1);
584 return Changed(node); 579 return Changed(node);
585 } 580 }
586 if (input->opcode() == IrOpcode::kSelect) { 581 if (input->opcode() == IrOpcode::kSelect) {
587 // JSToBoolean(select(c,x1,x2),context) 582 // JSToBoolean(select(c,x1,x2),context)
588 // => select(c,JSToBoolean(x1,no-context),...,JSToBoolean(x2,no-context)) 583 // => select(c,JSToBoolean(x1,no-context),...,JSToBoolean(x2,no-context))
589 int const input_count = input->InputCount(); 584 int const input_count = input->InputCount();
590 BranchHint const input_hint = SelectParametersOf(input->op()).hint(); 585 BranchHint const input_hint = SelectParametersOf(input->op()).hint();
591 DCHECK_EQ(3, input_count); 586 DCHECK_EQ(3, input_count);
592 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean())); 587 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
593 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean())); 588 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
594 node->set_op(common()->Select(kMachAnyTagged, input_hint)); 589 node->set_op(common()->Select(kMachAnyTagged, input_hint));
595 node->InsertInput(graph()->zone(), 0, input->InputAt(0)); 590 node->InsertInput(graph()->zone(), 0, input->InputAt(0));
596 for (int i = 1; i < input_count; ++i) { 591 for (int i = 1; i < input_count; ++i) {
597 Node* value = input->InputAt(i); 592 // We must be very careful not to introduce cycles when pushing
598 // Recursively try to reduce the value first. 593 // operations into selects. It is safe for {value}, since it appears
599 Reduction reduction = ReduceJSToBooleanInput(value); 594 // as input to the select that we are replacing, but it's not safe
600 if (reduction.Changed()) { 595 // to simply reuse the context of the {node}. However, ToBoolean()
601 value = reduction.replacement(); 596 // does not require a context anyways, so it's safe to discard it
602 } else { 597 // here and pass the dummy context.
603 // We must be very careful not to introduce cycles when pushing 598 Node* const value = ConvertToBoolean(input->InputAt(i));
604 // operations into selects. It is safe for {value}, since it appears
605 // as input to the select that we are replacing, but it's not safe
606 // to simply reuse the context of the {node}. However, ToBoolean()
607 // does not require a context anyways, so it's safe to discard it
608 // here and pass the dummy context.
609 value = graph()->NewNode(javascript()->ToBoolean(), value,
610 jsgraph()->NoContextConstant());
611 }
612 node->ReplaceInput(i, value); 599 node->ReplaceInput(i, value);
613 } 600 }
614 DCHECK_EQ(3, node->InputCount()); 601 DCHECK_EQ(3, node->InputCount());
615 return Changed(node); 602 return Changed(node);
616 } 603 }
604 InsertConversion(node);
605 if (node->InputAt(1) != jsgraph()->NoContextConstant()) {
606 // JSToBoolean(x,context) => JSToBoolean(x,no-context)
607 node->ReplaceInput(1, jsgraph()->NoContextConstant());
608 return Changed(node);
609 }
617 return NoChange(); 610 return NoChange();
618 } 611 }
619 612
620 613
621 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { 614 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
622 if (input->opcode() == IrOpcode::kJSToNumber) { 615 if (input->opcode() == IrOpcode::kJSToNumber) {
623 // Recursively try to reduce the input first. 616 // Recursively try to reduce the input first.
624 Reduction result = ReduceJSToNumber(input); 617 Reduction result = ReduceJSToNumber(input);
625 if (result.Changed()) return result; 618 if (result.Changed()) return result;
626 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x) 619 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x)
627 } 620 }
621 // Check if we have a cached conversion.
622 Node* conversion = FindConversion<IrOpcode::kJSToNumber>(input);
623 if (conversion) return Replace(conversion);
628 Type* input_type = NodeProperties::GetBounds(input).upper; 624 Type* input_type = NodeProperties::GetBounds(input).upper;
629 if (input_type->Is(Type::Number())) { 625 if (input_type->Is(Type::Number())) {
630 // JSToNumber(x:number) => x 626 // JSToNumber(x:number) => x
631 return Changed(input); 627 return Changed(input);
632 } 628 }
633 if (input_type->Is(Type::Undefined())) { 629 if (input_type->Is(Type::Undefined())) {
634 // JSToNumber(undefined) => #NaN 630 // JSToNumber(undefined) => #NaN
635 return Replace(jsgraph()->NaNConstant()); 631 return Replace(jsgraph()->NaNConstant());
636 } 632 }
637 if (input_type->Is(Type::Null())) { 633 if (input_type->Is(Type::Null())) {
(...skipping 26 matching lines...) Expand all
664 // JSToNumber(xn,no-context),control) 660 // JSToNumber(xn,no-context),control)
665 int const input_count = input->InputCount() - 1; 661 int const input_count = input->InputCount() - 1;
666 Node* const control = input->InputAt(input_count); 662 Node* const control = input->InputAt(input_count);
667 DCHECK_LE(0, input_count); 663 DCHECK_LE(0, input_count);
668 DCHECK(NodeProperties::IsControl(control)); 664 DCHECK(NodeProperties::IsControl(control));
669 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number())); 665 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
670 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number())); 666 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
671 RelaxEffects(node); 667 RelaxEffects(node);
672 node->set_op(common()->Phi(kMachAnyTagged, input_count)); 668 node->set_op(common()->Phi(kMachAnyTagged, input_count));
673 for (int i = 0; i < input_count; ++i) { 669 for (int i = 0; i < input_count; ++i) {
674 Node* value = input->InputAt(i); 670 // We must be very careful not to introduce cycles when pushing
675 // Recursively try to reduce the value first. 671 // operations into phis. It is safe for {value}, since it appears
676 Reduction reduction = ReduceJSToNumberInput(value); 672 // as input to the phi that we are replacing, but it's not safe
677 if (reduction.Changed()) { 673 // to simply reuse the context of the {node}. However, ToNumber()
678 value = reduction.replacement(); 674 // does not require a context anyways, so it's safe to discard it
679 } else { 675 // here and pass the dummy context.
680 // We must be very careful not to introduce cycles when pushing 676 Node* const value = ConvertToNumber(input->InputAt(i));
681 // operations into phis. It is safe for {value}, since it appears
682 // as input to the phi that we are replacing, but it's not safe
683 // to simply reuse the context of the {node}. However, ToNumber()
684 // does not require a context anyways, so it's safe to discard it
685 // here and pass the dummy context.
686 value = graph()->NewNode(javascript()->ToNumber(), value,
687 jsgraph()->NoContextConstant(),
688 graph()->start(), graph()->start());
689 }
690 if (i < node->InputCount()) { 677 if (i < node->InputCount()) {
691 node->ReplaceInput(i, value); 678 node->ReplaceInput(i, value);
692 } else { 679 } else {
693 node->AppendInput(graph()->zone(), value); 680 node->AppendInput(graph()->zone(), value);
694 } 681 }
695 } 682 }
696 if (input_count < node->InputCount()) { 683 if (input_count < node->InputCount()) {
697 node->ReplaceInput(input_count, control); 684 node->ReplaceInput(input_count, control);
698 } else { 685 } else {
699 node->AppendInput(graph()->zone(), control); 686 node->AppendInput(graph()->zone(), control);
700 } 687 }
701 node->TrimInputCount(input_count + 1); 688 node->TrimInputCount(input_count + 1);
702 return Changed(node); 689 return Changed(node);
703 } 690 }
704 if (input->opcode() == IrOpcode::kSelect) { 691 if (input->opcode() == IrOpcode::kSelect) {
705 // JSToNumber(select(c,x1,x2):plain-primitive,context) 692 // JSToNumber(select(c,x1,x2):plain-primitive,context)
706 // => select(c,JSToNumber(x1,no-context),JSToNumber(x2,no-context)) 693 // => select(c,JSToNumber(x1,no-context),JSToNumber(x2,no-context))
707 int const input_count = input->InputCount(); 694 int const input_count = input->InputCount();
708 BranchHint const input_hint = SelectParametersOf(input->op()).hint(); 695 BranchHint const input_hint = SelectParametersOf(input->op()).hint();
709 DCHECK_EQ(3, input_count); 696 DCHECK_EQ(3, input_count);
710 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number())); 697 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
711 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number())); 698 DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
712 RelaxEffects(node); 699 RelaxEffects(node);
713 node->set_op(common()->Select(kMachAnyTagged, input_hint)); 700 node->set_op(common()->Select(kMachAnyTagged, input_hint));
714 node->ReplaceInput(0, input->InputAt(0)); 701 node->ReplaceInput(0, input->InputAt(0));
715 for (int i = 1; i < input_count; ++i) { 702 for (int i = 1; i < input_count; ++i) {
716 Node* value = input->InputAt(i); 703 // We must be very careful not to introduce cycles when pushing
717 // Recursively try to reduce the value first. 704 // operations into selects. It is safe for {value}, since it appears
718 Reduction reduction = ReduceJSToNumberInput(value); 705 // as input to the select that we are replacing, but it's not safe
719 if (reduction.Changed()) { 706 // to simply reuse the context of the {node}. However, ToNumber()
720 value = reduction.replacement(); 707 // does not require a context anyways, so it's safe to discard it
721 } else { 708 // here and pass the dummy context.
722 // We must be very careful not to introduce cycles when pushing 709 Node* const value = ConvertToNumber(input->InputAt(i));
723 // operations into selects. It is safe for {value}, since it appears
724 // as input to the select that we are replacing, but it's not safe
725 // to simply reuse the context of the {node}. However, ToNumber()
726 // does not require a context anyways, so it's safe to discard it
727 // here and pass the dummy context.
728 value = graph()->NewNode(javascript()->ToNumber(), value,
729 jsgraph()->NoContextConstant(),
730 graph()->start(), graph()->start());
731 }
732 node->ReplaceInput(i, value); 710 node->ReplaceInput(i, value);
733 } 711 }
734 node->TrimInputCount(input_count); 712 node->TrimInputCount(input_count);
735 return Changed(node); 713 return Changed(node);
736 } 714 }
715 // Remember this conversion.
716 InsertConversion(node);
737 if (node->InputAt(1) != jsgraph()->NoContextConstant() || 717 if (node->InputAt(1) != jsgraph()->NoContextConstant() ||
738 node->InputAt(2) != graph()->start()) { 718 node->InputAt(2) != graph()->start() ||
739 // JSToNumber(x:plain-primitive,context) => JSToNumber(x,no-context) 719 node->InputAt(3) != graph()->start()) {
720 // JSToNumber(x:plain-primitive,context,effect,control)
721 // => JSToNumber(x,no-context,start,start)
722 RelaxEffects(node);
740 node->ReplaceInput(1, jsgraph()->NoContextConstant()); 723 node->ReplaceInput(1, jsgraph()->NoContextConstant());
741 RelaxEffects(node); 724 node->ReplaceInput(2, graph()->start());
725 node->ReplaceInput(3, graph()->start());
742 return Changed(node); 726 return Changed(node);
743 } 727 }
744 } 728 }
745 return NoChange(); 729 return NoChange();
746 } 730 }
747 731
748 732
749 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { 733 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
750 if (input->opcode() == IrOpcode::kJSToString) { 734 if (input->opcode() == IrOpcode::kJSToString) {
751 // Recursively try to reduce the input first. 735 // Recursively try to reduce the input first.
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 return ReduceJSLoadContext(node); 999 return ReduceJSLoadContext(node);
1016 case IrOpcode::kJSStoreContext: 1000 case IrOpcode::kJSStoreContext:
1017 return ReduceJSStoreContext(node); 1001 return ReduceJSStoreContext(node);
1018 default: 1002 default:
1019 break; 1003 break;
1020 } 1004 }
1021 return NoChange(); 1005 return NoChange();
1022 } 1006 }
1023 1007
1024 1008
1009 Node* JSTypedLowering::ConvertToBoolean(Node* input) {
1010 // Avoid inserting too many eager ToBoolean() operations.
1011 Reduction const reduction = ReduceJSToBooleanInput(input);
1012 if (reduction.Changed()) return reduction.replacement();
1013 Node* const conversion = graph()->NewNode(javascript()->ToBoolean(), input,
1014 jsgraph()->NoContextConstant());
1015 InsertConversion(conversion);
1016 return conversion;
1017 }
1018
1019
1020 Node* JSTypedLowering::ConvertToNumber(Node* input) {
1021 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive()));
1022 // Avoid inserting too many eager ToNumber() operations.
1023 Reduction const reduction = ReduceJSToNumberInput(input);
1024 if (reduction.Changed()) return reduction.replacement();
1025 Node* const conversion = graph()->NewNode(javascript()->ToNumber(), input,
1026 jsgraph()->NoContextConstant(),
1027 graph()->start(), graph()->start());
1028 InsertConversion(conversion);
1029 return conversion;
1030 }
1031
1032
1033 template <IrOpcode::Value kOpcode>
1034 Node* JSTypedLowering::FindConversion(Node* input) {
1035 size_t const input_id = input->id();
1036 if (input_id < conversions_.size()) {
1037 Node* const conversion = conversions_[input_id];
1038 if (conversion && conversion->opcode() == kOpcode) {
1039 return conversion;
1040 }
1041 }
1042 return nullptr;
1043 }
1044
1045
1046 void JSTypedLowering::InsertConversion(Node* conversion) {
1047 DCHECK(conversion->opcode() == IrOpcode::kJSToBoolean ||
1048 conversion->opcode() == IrOpcode::kJSToNumber);
1049 size_t const input_id = conversion->InputAt(0)->id();
1050 if (input_id >= conversions_.size()) {
1051 conversions_.resize(2 * input_id + 1);
1052 }
1053 conversions_[input_id] = conversion;
1054 }
1055
1056
1025 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { 1057 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) {
1026 if (rhs == 0) return lhs; 1058 if (rhs == 0) return lhs;
1027 return graph()->NewNode(machine()->Word32Shl(), lhs, 1059 return graph()->NewNode(machine()->Word32Shl(), lhs,
1028 jsgraph()->Int32Constant(rhs)); 1060 jsgraph()->Int32Constant(rhs));
1029 } 1061 }
1030 1062
1031 1063
1032 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } 1064 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
1033 1065
1034 1066
(...skipping 10 matching lines...) Expand all
1045 } 1077 }
1046 1078
1047 1079
1048 MachineOperatorBuilder* JSTypedLowering::machine() const { 1080 MachineOperatorBuilder* JSTypedLowering::machine() const {
1049 return jsgraph()->machine(); 1081 return jsgraph()->machine();
1050 } 1082 }
1051 1083
1052 } // namespace compiler 1084 } // namespace compiler
1053 } // namespace internal 1085 } // namespace internal
1054 } // namespace v8 1086 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698