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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1580353003: [turbofan] Avoid using the typer's types in representation inference for phis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove dead code Created 4 years, 11 months 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/representation-change.cc ('k') | test/cctest/compiler/test-simplified-lowering.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/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 type = Type::Any(); 493 type = Type::Any();
494 break; 494 break;
495 } 495 }
496 return SetOutput(node, NodeOutputInfo(machine_type.representation(), type)); 496 return SetOutput(node, NodeOutputInfo(machine_type.representation(), type));
497 } 497 }
498 498
499 void SetOutput(Node* node, NodeOutputInfo output_info) { 499 void SetOutput(Node* node, NodeOutputInfo output_info) {
500 // Every node should have at most one output representation. Note that 500 // Every node should have at most one output representation. Note that
501 // phis can have 0, if they have not been used in a representation-inducing 501 // phis can have 0, if they have not been used in a representation-inducing
502 // instruction. 502 // instruction.
503 Type* output_type = output_info.type();
504 if (NodeProperties::IsTyped(node)) {
505 output_type = Type::Intersect(NodeProperties::GetType(node),
506 output_info.type(), jsgraph_->zone());
507 }
503 NodeInfo* info = GetInfo(node); 508 NodeInfo* info = GetInfo(node);
509 DCHECK(info->output_type()->Is(output_type));
504 DCHECK(MachineRepresentationIsSubtype(info->representation(), 510 DCHECK(MachineRepresentationIsSubtype(info->representation(),
505 output_info.representation())); 511 output_info.representation()));
506 DCHECK(info->output_type()->Is(output_info.type())); 512 if (!output_type->Is(info->output_type()) ||
507 if (!output_info.type()->Is(info->output_type()) ||
508 output_info.representation() != info->representation()) { 513 output_info.representation() != info->representation()) {
509 EnqueueUses(node); 514 EnqueueUses(node);
510 } 515 }
511 info->set_output_type(output_info); 516 info->set_output_type(
517 NodeOutputInfo(output_info.representation(), output_type));
512 } 518 }
513 519
514 bool BothInputsAreSigned32(Node* node) { 520 bool BothInputsAreSigned32(Node* node) {
515 DCHECK_EQ(2, node->InputCount()); 521 DCHECK_EQ(2, node->InputCount());
516 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Signed32()) || 522 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32()) &&
517 GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32())) && 523 GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32());
518 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Signed32()) ||
519 GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32()));
520 } 524 }
521 525
522 bool BothInputsAreUnsigned32(Node* node) { 526 bool BothInputsAreUnsigned32(Node* node) {
523 DCHECK_EQ(2, node->InputCount()); 527 DCHECK_EQ(2, node->InputCount());
524 return (NodeProperties::GetType(node->InputAt(0))->Is(Type::Unsigned32()) || 528 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32()) &&
525 GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32())) && 529 GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32());
526 (NodeProperties::GetType(node->InputAt(1))->Is(Type::Unsigned32()) ||
527 GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32()));
528 } 530 }
529 531
530 bool BothInputsAre(Node* node, Type* type) { 532 bool BothInputsAre(Node* node, Type* type) {
531 DCHECK_EQ(2, node->InputCount()); 533 DCHECK_EQ(2, node->InputCount());
532 return NodeProperties::GetType(node->InputAt(0))->Is(type) && 534 return GetInfo(node->InputAt(0))->output_type()->Is(type) &&
533 NodeProperties::GetType(node->InputAt(1))->Is(type); 535 GetInfo(node->InputAt(1))->output_type()->Is(type);
534 } 536 }
535 537
536 void ConvertInput(Node* node, int index, UseInfo use) { 538 void ConvertInput(Node* node, int index, UseInfo use) {
537 Node* input = node->InputAt(index); 539 Node* input = node->InputAt(index);
538 // In the change phase, insert a change before the use if necessary. 540 // In the change phase, insert a change before the use if necessary.
539 if (use.preferred() == MachineRepresentation::kNone) 541 if (use.preferred() == MachineRepresentation::kNone)
540 return; // No input requirement on the use. 542 return; // No input requirement on the use.
541 NodeInfo* input_info = GetInfo(input); 543 NodeInfo* input_info = GetInfo(input);
542 MachineRepresentation input_rep = input_info->representation(); 544 MachineRepresentation input_rep = input_info->representation();
543 if (input_rep != use.preferred()) { 545 if (input_rep != use.preferred()) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool()); 656 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool());
655 } 657 }
656 void VisitInt64Cmp(Node* node) { 658 void VisitInt64Cmp(Node* node) {
657 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); 659 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
658 } 660 }
659 void VisitUint64Cmp(Node* node) { 661 void VisitUint64Cmp(Node* node) {
660 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); 662 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
661 } 663 }
662 664
663 // Infer representation for phi-like nodes. 665 // Infer representation for phi-like nodes.
664 static MachineRepresentation GetRepresentationForPhi(Node* node, 666 NodeOutputInfo GetOutputInfoForPhi(Node* node, Truncation use) {
665 Truncation use) { 667 // Compute the type.
666 // Phis adapt to the output representation their uses demand. 668 Type* type = GetInfo(node->InputAt(0))->output_type();
667 Type* type = NodeProperties::GetType(node); 669 for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
668 if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { 670 type = Type::Union(type, GetInfo(node->InputAt(i))->output_type(),
669 // We are within 32 bits range => pick kRepWord32. 671 jsgraph_->zone());
670 return MachineRepresentation::kWord32; 672 }
673
674 // Compute the representation.
675 MachineRepresentation rep = MachineRepresentation::kTagged;
676 if (type->Is(Type::None())) {
677 rep = MachineRepresentation::kNone;
678 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
679 rep = MachineRepresentation::kWord32;
671 } else if (use.TruncatesToWord32()) { 680 } else if (use.TruncatesToWord32()) {
672 // We only use 32 bits. 681 rep = MachineRepresentation::kWord32;
673 return MachineRepresentation::kWord32;
674 } else if (type->Is(Type::Boolean())) { 682 } else if (type->Is(Type::Boolean())) {
675 // multiple uses => pick kRepBit. 683 rep = MachineRepresentation::kBit;
676 return MachineRepresentation::kBit;
677 } else if (type->Is(Type::Number())) { 684 } else if (type->Is(Type::Number())) {
678 // multiple uses => pick kRepFloat64. 685 rep = MachineRepresentation::kFloat64;
679 return MachineRepresentation::kFloat64;
680 } else if (type->Is(Type::Internal())) { 686 } else if (type->Is(Type::Internal())) {
681 return MachineType::PointerRepresentation(); 687 // We mark (u)int64 as Type::Internal.
688 // TODO(jarin) This is a workaround for our lack of (u)int64
689 // types. This can be removed once we can represent (u)int64
690 // unambiguously. (At the moment internal objects, such as the hole,
691 // are also Type::Internal()).
692 bool is_word64 = GetInfo(node->InputAt(0))->representation() ==
693 MachineRepresentation::kWord64;
694 #ifdef DEBUG
695 // Check that all the inputs agree on being Word64.
696 for (int i = 1; i < node->op()->ValueInputCount(); i++) {
697 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() ==
698 MachineRepresentation::kWord64);
699 }
700 #endif
701 rep = is_word64 ? MachineRepresentation::kWord64
702 : MachineRepresentation::kTagged;
682 } 703 }
683 return MachineRepresentation::kTagged; 704 return NodeOutputInfo(rep, type);
684 } 705 }
685 706
686 // Helper for handling selects. 707 // Helper for handling selects.
687 void VisitSelect(Node* node, Truncation truncation, 708 void VisitSelect(Node* node, Truncation truncation,
688 SimplifiedLowering* lowering) { 709 SimplifiedLowering* lowering) {
689 ProcessInput(node, 0, UseInfo::Bool()); 710 ProcessInput(node, 0, UseInfo::Bool());
690 MachineRepresentation output = GetRepresentationForPhi(node, truncation);
691 711
692 Type* type = NodeProperties::GetType(node); 712 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
693 SetOutput(node, NodeOutputInfo(output, type)); 713 SetOutput(node, output);
694 714
695 if (lower()) { 715 if (lower()) {
696 // Update the select operator. 716 // Update the select operator.
697 SelectParameters p = SelectParametersOf(node->op()); 717 SelectParameters p = SelectParametersOf(node->op());
698 if (output != p.representation()) { 718 if (output.representation() != p.representation()) {
699 NodeProperties::ChangeOp(node, 719 NodeProperties::ChangeOp(node, lowering->common()->Select(
700 lowering->common()->Select(output, p.hint())); 720 output.representation(), p.hint()));
701 } 721 }
702 } 722 }
703 // Convert inputs to the output representation of this phi, pass the 723 // Convert inputs to the output representation of this phi, pass the
704 // truncation truncation along. 724 // truncation truncation along.
705 UseInfo input_use(output, truncation); 725 UseInfo input_use(output.representation(), truncation);
706 ProcessInput(node, 1, input_use); 726 ProcessInput(node, 1, input_use);
707 ProcessInput(node, 2, input_use); 727 ProcessInput(node, 2, input_use);
708 } 728 }
709 729
710 // Helper for handling phis. 730 // Helper for handling phis.
711 void VisitPhi(Node* node, Truncation truncation, 731 void VisitPhi(Node* node, Truncation truncation,
712 SimplifiedLowering* lowering) { 732 SimplifiedLowering* lowering) {
713 MachineRepresentation output = GetRepresentationForPhi(node, truncation); 733 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
714 734 SetOutput(node, output);
715 Type* type = NodeProperties::GetType(node);
716 SetOutput(node, NodeOutputInfo(output, type));
717 735
718 int values = node->op()->ValueInputCount(); 736 int values = node->op()->ValueInputCount();
719
720 if (lower()) { 737 if (lower()) {
721 // Update the phi operator. 738 // Update the phi operator.
722 if (output != PhiRepresentationOf(node->op())) { 739 if (output.representation() != PhiRepresentationOf(node->op())) {
723 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); 740 NodeProperties::ChangeOp(
741 node, lowering->common()->Phi(output.representation(), values));
724 } 742 }
725 } 743 }
726 744
727 // Convert inputs to the output representation of this phi, pass the 745 // Convert inputs to the output representation of this phi, pass the
728 // truncation truncation along. 746 // truncation truncation along.
729 UseInfo input_use(output, truncation); 747 UseInfo input_use(output.representation(), truncation);
730 for (int i = 0; i < node->InputCount(); i++) { 748 for (int i = 0; i < node->InputCount(); i++) {
731 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); 749 ProcessInput(node, i, i < values ? input_use : UseInfo::None());
732 } 750 }
733 } 751 }
734 752
735 void VisitCall(Node* node, SimplifiedLowering* lowering) { 753 void VisitCall(Node* node, SimplifiedLowering* lowering) {
736 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); 754 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op());
737 const MachineSignature* sig = desc->GetMachineSignature(); 755 const MachineSignature* sig = desc->GetMachineSignature();
738 int params = static_cast<int>(sig->parameter_count()); 756 int params = static_cast<int>(sig->parameter_count());
739 // Propagate representation information from call descriptor. 757 // Propagate representation information from call descriptor.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 for (int i = 0; i < node->InputCount(); i++) { 791 for (int i = 0; i < node->InputCount(); i++) {
774 EnqueueInput(node, i, UseInfo::Any()); 792 EnqueueInput(node, i, UseInfo::Any());
775 } 793 }
776 } else { 794 } else {
777 Zone* zone = jsgraph_->zone(); 795 Zone* zone = jsgraph_->zone();
778 ZoneVector<MachineType>* types = 796 ZoneVector<MachineType>* types =
779 new (zone->New(sizeof(ZoneVector<MachineType>))) 797 new (zone->New(sizeof(ZoneVector<MachineType>)))
780 ZoneVector<MachineType>(node->InputCount(), zone); 798 ZoneVector<MachineType>(node->InputCount(), zone);
781 for (int i = 0; i < node->InputCount(); i++) { 799 for (int i = 0; i < node->InputCount(); i++) {
782 NodeInfo* input_info = GetInfo(node->InputAt(i)); 800 NodeInfo* input_info = GetInfo(node->InputAt(i));
783 (*types)[i] = 801 MachineType machine_type(
784 MachineType(input_info->representation(), 802 input_info->representation(),
785 DeoptValueSemanticOf(input_info->output_type())); 803 DeoptValueSemanticOf(input_info->output_type()));
804 DCHECK(machine_type.representation() !=
805 MachineRepresentation::kWord32 ||
806 machine_type.semantic() == MachineSemantic::kInt32 ||
807 machine_type.semantic() == MachineSemantic::kUint32);
808 (*types)[i] = machine_type;
786 } 809 }
787 NodeProperties::ChangeOp(node, 810 NodeProperties::ChangeOp(node,
788 jsgraph_->common()->TypedStateValues(types)); 811 jsgraph_->common()->TypedStateValues(types));
789 } 812 }
790 SetOutput(node, NodeOutputInfo::AnyTagged()); 813 SetOutput(node, NodeOutputInfo::AnyTagged());
791 } 814 }
792 815
793 const Operator* Int32Op(Node* node) { 816 const Operator* Int32Op(Node* node) {
794 return changer_->Int32OperatorFor(node->opcode()); 817 return changer_->Int32OperatorFor(node->opcode());
795 } 818 }
796 819
797 const Operator* Uint32Op(Node* node) { 820 const Operator* Uint32Op(Node* node) {
798 return changer_->Uint32OperatorFor(node->opcode()); 821 return changer_->Uint32OperatorFor(node->opcode());
799 } 822 }
800 823
801 const Operator* Float64Op(Node* node) { 824 const Operator* Float64Op(Node* node) {
802 return changer_->Float64OperatorFor(node->opcode()); 825 return changer_->Float64OperatorFor(node->opcode());
803 } 826 }
804 827
805 bool CanLowerToInt32Binop(Node* node, Truncation use) {
806 return BothInputsAreSigned32(node) &&
807 NodeProperties::GetType(node)->Is(Type::Signed32());
808 }
809
810 bool CanLowerToInt32AdditiveBinop(Node* node, Truncation use) {
811 // It is safe to lower to word32 operation if:
812 // - the inputs are safe integers (so the low bits are not discarded), and
813 // - the uses can only observe the lowest 32 bits.
814 // TODO(jarin): we could support the uint32 case here, but that would
815 // require setting kTypeUint32 as the output type. Eventually, we will want
816 // to use only the big types, then this should work automatically.
817 return BothInputsAre(node, type_cache_.kAdditiveSafeInteger) &&
818 use.TruncatesToWord32();
819 }
820
821 bool CanLowerToInt32MultiplicativeBinop(Node* node, Truncation use) {
822 return BothInputsAreSigned32(node) && use.TruncatesToWord32() &&
823 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger);
824 }
825
826 // Dispatching routine for visiting the node {node} with the usage {use}. 828 // Dispatching routine for visiting the node {node} with the usage {use}.
827 // Depending on the operator, propagate new usage info to the inputs. 829 // Depending on the operator, propagate new usage info to the inputs.
828 void VisitNode(Node* node, Truncation truncation, 830 void VisitNode(Node* node, Truncation truncation,
829 SimplifiedLowering* lowering) { 831 SimplifiedLowering* lowering) {
830 switch (node->opcode()) { 832 switch (node->opcode()) {
831 //------------------------------------------------------------------ 833 //------------------------------------------------------------------
832 // Common operators. 834 // Common operators.
833 //------------------------------------------------------------------ 835 //------------------------------------------------------------------
834 case IrOpcode::kStart: 836 case IrOpcode::kStart:
835 case IrOpcode::kDead: 837 case IrOpcode::kDead:
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 ReplaceEffectUses(node, comparison); 1921 ReplaceEffectUses(node, comparison);
1920 node->ReplaceInput(0, comparison); 1922 node->ReplaceInput(0, comparison);
1921 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1923 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1922 node->TrimInputCount(2); 1924 node->TrimInputCount(2);
1923 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); 1925 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
1924 } 1926 }
1925 1927
1926 } // namespace compiler 1928 } // namespace compiler
1927 } // namespace internal 1929 } // namespace internal
1928 } // namespace v8 1930 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.cc ('k') | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698