OLD | NEW |
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 "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/representation-change.h" | 10 #include "src/compiler/representation-change.h" |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 jsgraph()->Int32Constant(kSmiTagMask)); | 719 jsgraph()->Int32Constant(kSmiTagMask)); |
720 } | 720 } |
721 | 721 |
722 | 722 |
723 void SimplifiedLowering::LowerAllNodes() { | 723 void SimplifiedLowering::LowerAllNodes() { |
724 SimplifiedOperatorBuilder simplified(graph()->zone()); | 724 SimplifiedOperatorBuilder simplified(graph()->zone()); |
725 RepresentationChanger changer(jsgraph(), &simplified, machine(), | 725 RepresentationChanger changer(jsgraph(), &simplified, machine(), |
726 graph()->zone()->isolate()); | 726 graph()->zone()->isolate()); |
727 RepresentationSelector selector(jsgraph(), zone(), &changer); | 727 RepresentationSelector selector(jsgraph(), zone(), &changer); |
728 selector.Run(this); | 728 selector.Run(this); |
729 | |
730 GraphReducer graph_reducer(graph()); | |
731 graph_reducer.AddReducer(this); | |
732 graph_reducer.ReduceGraph(); | |
733 } | 729 } |
734 | 730 |
735 | 731 |
736 Node* SimplifiedLowering::Untag(Node* node) { | 732 Node* SimplifiedLowering::Untag(Node* node) { |
737 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 733 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
738 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); | 734 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); |
739 return graph()->NewNode(machine()->WordSar(), node, shift_amount); | 735 return graph()->NewNode(machine()->WordSar(), node, shift_amount); |
740 } | 736 } |
741 | 737 |
742 | 738 |
743 Node* SimplifiedLowering::SmiTag(Node* node) { | 739 Node* SimplifiedLowering::SmiTag(Node* node) { |
744 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 740 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
745 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); | 741 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); |
746 return graph()->NewNode(machine()->WordShl(), node, shift_amount); | 742 return graph()->NewNode(machine()->WordShl(), node, shift_amount); |
747 } | 743 } |
748 | 744 |
749 | 745 |
750 Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) { | 746 Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) { |
751 return jsgraph()->Int32Constant(offset - kHeapObjectTag); | 747 return jsgraph()->Int32Constant(offset - kHeapObjectTag); |
752 } | 748 } |
753 | 749 |
754 | 750 |
755 static void UpdateControlSuccessors(Node* before, Node* node) { | |
756 DCHECK(IrOpcode::IsControlOpcode(before->opcode())); | |
757 UseIter iter = before->uses().begin(); | |
758 while (iter != before->uses().end()) { | |
759 if (IrOpcode::IsControlOpcode((*iter)->opcode()) && | |
760 NodeProperties::IsControlEdge(iter.edge())) { | |
761 iter = iter.UpdateToAndIncrement(node); | |
762 continue; | |
763 } | |
764 ++iter; | |
765 } | |
766 } | |
767 | |
768 | |
769 void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect, | |
770 Node* control, bool is_signed) { | |
771 // if (IsTagged(val)) | |
772 // ConvertFloat64To(Int32|Uint32)(Load[kMachFloat64](input, #value_offset)) | |
773 // else Untag(val) | |
774 Node* val = node->InputAt(0); | |
775 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control); | |
776 | |
777 // true branch. | |
778 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); | |
779 Node* loaded = graph()->NewNode( | |
780 machine()->Load(kMachFloat64), val, | |
781 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect); | |
782 Operator* op = is_signed ? machine()->ChangeFloat64ToInt32() | |
783 : machine()->ChangeFloat64ToUint32(); | |
784 Node* converted = graph()->NewNode(op, loaded); | |
785 | |
786 // false branch. | |
787 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); | |
788 Node* untagged = Untag(val); | |
789 | |
790 // merge. | |
791 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); | |
792 Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge); | |
793 UpdateControlSuccessors(control, merge); | |
794 branch->ReplaceInput(1, control); | |
795 node->ReplaceUses(phi); | |
796 } | |
797 | |
798 | |
799 void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect, | |
800 Node* control) { | |
801 // if (IsTagged(input)) Load[kMachFloat64](input, #value_offset) | |
802 // else ConvertFloat64(Untag(input)) | |
803 Node* val = node->InputAt(0); | |
804 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control); | |
805 | |
806 // true branch. | |
807 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); | |
808 Node* loaded = graph()->NewNode( | |
809 machine()->Load(kMachFloat64), val, | |
810 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect); | |
811 | |
812 // false branch. | |
813 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); | |
814 Node* untagged = Untag(val); | |
815 Node* converted = | |
816 graph()->NewNode(machine()->ChangeInt32ToFloat64(), untagged); | |
817 | |
818 // merge. | |
819 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); | |
820 Node* phi = graph()->NewNode(common()->Phi(2), loaded, converted, merge); | |
821 UpdateControlSuccessors(control, merge); | |
822 branch->ReplaceInput(1, control); | |
823 node->ReplaceUses(phi); | |
824 } | |
825 | |
826 | |
827 void SimplifiedLowering::DoChangeUI32ToTagged(Node* node, Node* effect, | |
828 Node* control, bool is_signed) { | |
829 Node* val = node->InputAt(0); | |
830 Node* is_smi = NULL; | |
831 if (is_signed) { | |
832 if (SmiValuesAre32Bits()) { | |
833 // All int32s fit in this case. | |
834 DCHECK(kPointerSize == 8); | |
835 return node->ReplaceUses(SmiTag(val)); | |
836 } else { | |
837 // TODO(turbofan): use an Int32AddWithOverflow to tag and check here. | |
838 Node* lt = graph()->NewNode(machine()->Int32LessThanOrEqual(), val, | |
839 jsgraph()->Int32Constant(Smi::kMaxValue)); | |
840 Node* gt = | |
841 graph()->NewNode(machine()->Int32LessThanOrEqual(), | |
842 jsgraph()->Int32Constant(Smi::kMinValue), val); | |
843 is_smi = graph()->NewNode(machine()->Word32And(), lt, gt); | |
844 } | |
845 } else { | |
846 // Check if Uint32 value is in the smi range. | |
847 is_smi = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val, | |
848 jsgraph()->Int32Constant(Smi::kMaxValue)); | |
849 } | |
850 | |
851 // TODO(turbofan): fold smi test branch eagerly. | |
852 // if (IsSmi(input)) SmiTag(input); | |
853 // else InlineAllocAndInitHeapNumber(ConvertToFloat64(input))) | |
854 Node* branch = graph()->NewNode(common()->Branch(), is_smi, control); | |
855 | |
856 // true branch. | |
857 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); | |
858 Node* smi_tagged = SmiTag(val); | |
859 | |
860 // false branch. | |
861 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); | |
862 Node* heap_num = jsgraph()->Constant(0.0); // TODO(titzer): alloc and init | |
863 | |
864 // merge. | |
865 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); | |
866 Node* phi = graph()->NewNode(common()->Phi(2), smi_tagged, heap_num, merge); | |
867 UpdateControlSuccessors(control, merge); | |
868 branch->ReplaceInput(1, control); | |
869 node->ReplaceUses(phi); | |
870 } | |
871 | |
872 | |
873 void SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect, | |
874 Node* control) { | |
875 return; // TODO(titzer): need to call runtime to allocate in one branch | |
876 } | |
877 | |
878 | |
879 void SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect, | |
880 Node* control) { | |
881 Node* cmp = graph()->NewNode(machine()->WordEqual(), node->InputAt(0), | |
882 jsgraph()->TrueConstant()); | |
883 node->ReplaceUses(cmp); | |
884 } | |
885 | |
886 | |
887 void SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect, | |
888 Node* control) { | |
889 Node* val = node->InputAt(0); | |
890 Node* branch = graph()->NewNode(common()->Branch(), val, control); | |
891 | |
892 // true branch. | |
893 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); | |
894 // false branch. | |
895 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); | |
896 // merge. | |
897 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); | |
898 Node* phi = graph()->NewNode(common()->Phi(2), jsgraph()->TrueConstant(), | |
899 jsgraph()->FalseConstant(), merge); | |
900 UpdateControlSuccessors(control, merge); | |
901 branch->ReplaceInput(1, control); | |
902 node->ReplaceUses(phi); | |
903 } | |
904 | |
905 | |
906 static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged, | 751 static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged, |
907 MachineType representation, | 752 MachineType representation, |
908 Type* type) { | 753 Type* type) { |
909 // TODO(turbofan): skip write barriers for Smis, etc. | 754 // TODO(turbofan): skip write barriers for Smis, etc. |
910 if (base_is_tagged == kTaggedBase && | 755 if (base_is_tagged == kTaggedBase && |
911 RepresentationOf(representation) == kRepTagged) { | 756 RepresentationOf(representation) == kRepTagged) { |
912 // Write barriers are only for writes into heap objects (i.e. tagged base). | 757 // Write barriers are only for writes into heap objects (i.e. tagged base). |
913 return kFullWriteBarrier; | 758 return kFullWriteBarrier; |
914 } | 759 } |
915 return kNoWriteBarrier; | 760 return kNoWriteBarrier; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 | 802 |
958 void SimplifiedLowering::DoStoreElement(Node* node) { | 803 void SimplifiedLowering::DoStoreElement(Node* node) { |
959 const ElementAccess& access = ElementAccessOf(node->op()); | 804 const ElementAccess& access = ElementAccessOf(node->op()); |
960 WriteBarrierKind kind = ComputeWriteBarrierKind( | 805 WriteBarrierKind kind = ComputeWriteBarrierKind( |
961 access.base_is_tagged, access.machine_type, access.type); | 806 access.base_is_tagged, access.machine_type, access.type); |
962 node->set_op(machine_.Store(access.machine_type, kind)); | 807 node->set_op(machine_.Store(access.machine_type, kind)); |
963 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 808 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); |
964 } | 809 } |
965 | 810 |
966 | 811 |
967 Reduction SimplifiedLowering::Reduce(Node* node) { return NoChange(); } | |
968 | |
969 | |
970 void SimplifiedLowering::LowerChange(Node* node, Node* effect, Node* control) { | |
971 switch (node->opcode()) { | |
972 case IrOpcode::kChangeTaggedToInt32: | |
973 DoChangeTaggedToUI32(node, effect, control, true); | |
974 break; | |
975 case IrOpcode::kChangeTaggedToUint32: | |
976 DoChangeTaggedToUI32(node, effect, control, false); | |
977 break; | |
978 case IrOpcode::kChangeTaggedToFloat64: | |
979 DoChangeTaggedToFloat64(node, effect, control); | |
980 break; | |
981 case IrOpcode::kChangeInt32ToTagged: | |
982 DoChangeUI32ToTagged(node, effect, control, true); | |
983 break; | |
984 case IrOpcode::kChangeUint32ToTagged: | |
985 DoChangeUI32ToTagged(node, effect, control, false); | |
986 break; | |
987 case IrOpcode::kChangeFloat64ToTagged: | |
988 DoChangeFloat64ToTagged(node, effect, control); | |
989 break; | |
990 case IrOpcode::kChangeBoolToBit: | |
991 DoChangeBoolToBit(node, effect, control); | |
992 break; | |
993 case IrOpcode::kChangeBitToBool: | |
994 DoChangeBitToBool(node, effect, control); | |
995 break; | |
996 default: | |
997 UNREACHABLE(); | |
998 break; | |
999 } | |
1000 } | |
1001 | |
1002 } // namespace compiler | 812 } // namespace compiler |
1003 } // namespace internal | 813 } // namespace internal |
1004 } // namespace v8 | 814 } // namespace v8 |
OLD | NEW |