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 "test/cctest/cctest.h" | 5 #include "test/cctest/cctest.h" |
6 | 6 |
7 #include "src/base/utils/random-number-generator.h" | 7 #include "src/base/utils/random-number-generator.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/compiler/graph-inl.h" | 9 #include "src/compiler/graph-inl.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // yields the {expect} value. | 93 // yields the {expect} value. |
94 template <typename T> | 94 template <typename T> |
95 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { | 95 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { |
96 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); | 96 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); |
97 } | 97 } |
98 | 98 |
99 // Check that the reduction of this binop applied to {a} and {b} yields | 99 // Check that the reduction of this binop applied to {a} and {b} yields |
100 // the {expect} value. | 100 // the {expect} value. |
101 template <typename T> | 101 template <typename T> |
102 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { | 102 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { |
103 CHECK_NE(NULL, binop); | 103 CHECK(binop); |
104 Node* n = CreateBinopNode(a, b); | 104 Node* n = CreateBinopNode(a, b); |
105 MachineOperatorReducer reducer(&jsgraph); | 105 MachineOperatorReducer reducer(&jsgraph); |
106 Reduction reduction = reducer.Reduce(n); | 106 Reduction reduction = reducer.Reduce(n); |
107 CHECK(reduction.Changed()); | 107 CHECK(reduction.Changed()); |
108 CHECK_NE(n, reduction.replacement()); | 108 CHECK_NE(n, reduction.replacement()); |
109 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); | 109 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); |
110 } | 110 } |
111 | 111 |
112 // Check that the reduction of this binop applied to {a} and {b} yields | 112 // Check that the reduction of this binop applied to {a} and {b} yields |
113 // the {expect} node. | 113 // the {expect} node. |
114 void CheckBinop(Node* expect, Node* a, Node* b) { | 114 void CheckBinop(Node* expect, Node* a, Node* b) { |
115 CHECK_NE(NULL, binop); | 115 CHECK(binop); |
116 Node* n = CreateBinopNode(a, b); | 116 Node* n = CreateBinopNode(a, b); |
117 MachineOperatorReducer reducer(&jsgraph); | 117 MachineOperatorReducer reducer(&jsgraph); |
118 Reduction reduction = reducer.Reduce(n); | 118 Reduction reduction = reducer.Reduce(n); |
119 CHECK(reduction.Changed()); | 119 CHECK(reduction.Changed()); |
120 CHECK_EQ(expect, reduction.replacement()); | 120 CHECK_EQ(expect, reduction.replacement()); |
121 } | 121 } |
122 | 122 |
123 // Check that the reduction of this binop applied to {left} and {right} yields | 123 // Check that the reduction of this binop applied to {left} and {right} yields |
124 // this binop applied to {left_expect} and {right_expect}. | 124 // this binop applied to {left_expect} and {right_expect}. |
125 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, | 125 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, |
126 Node* right) { | 126 Node* right) { |
127 CHECK_NE(NULL, binop); | 127 CHECK(binop); |
128 Node* n = CreateBinopNode(left, right); | 128 Node* n = CreateBinopNode(left, right); |
129 MachineOperatorReducer reducer(&jsgraph); | 129 MachineOperatorReducer reducer(&jsgraph); |
130 Reduction reduction = reducer.Reduce(n); | 130 Reduction reduction = reducer.Reduce(n); |
131 CHECK(reduction.Changed()); | 131 CHECK(reduction.Changed()); |
132 CHECK_EQ(binop, reduction.replacement()->op()); | 132 CHECK_EQ(binop, reduction.replacement()->op()); |
133 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); | 133 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); |
134 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); | 134 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); |
135 } | 135 } |
136 | 136 |
137 // Check that the reduction of this binop applied to {left} and {right} yields | 137 // Check that the reduction of this binop applied to {left} and {right} yields |
138 // the {op_expect} applied to {left_expect} and {right_expect}. | 138 // the {op_expect} applied to {left_expect} and {right_expect}. |
139 template <typename T> | 139 template <typename T> |
140 void CheckFoldBinop(volatile T left_expect, const Operator* op_expect, | 140 void CheckFoldBinop(volatile T left_expect, const Operator* op_expect, |
141 Node* right_expect, Node* left, Node* right) { | 141 Node* right_expect, Node* left, Node* right) { |
142 CHECK_NE(NULL, binop); | 142 CHECK(binop); |
143 Node* n = CreateBinopNode(left, right); | 143 Node* n = CreateBinopNode(left, right); |
144 MachineOperatorReducer reducer(&jsgraph); | 144 MachineOperatorReducer reducer(&jsgraph); |
145 Reduction r = reducer.Reduce(n); | 145 Reduction r = reducer.Reduce(n); |
146 CHECK(r.Changed()); | 146 CHECK(r.Changed()); |
147 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 147 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
148 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); | 148 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); |
149 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); | 149 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); |
150 } | 150 } |
151 | 151 |
152 // Check that the reduction of this binop applied to {left} and {right} yields | 152 // Check that the reduction of this binop applied to {left} and {right} yields |
153 // the {op_expect} applied to {left_expect} and {right_expect}. | 153 // the {op_expect} applied to {left_expect} and {right_expect}. |
154 template <typename T> | 154 template <typename T> |
155 void CheckFoldBinop(Node* left_expect, const Operator* op_expect, | 155 void CheckFoldBinop(Node* left_expect, const Operator* op_expect, |
156 volatile T right_expect, Node* left, Node* right) { | 156 volatile T right_expect, Node* left, Node* right) { |
157 CHECK_NE(NULL, binop); | 157 CHECK(binop); |
158 Node* n = CreateBinopNode(left, right); | 158 Node* n = CreateBinopNode(left, right); |
159 MachineOperatorReducer reducer(&jsgraph); | 159 MachineOperatorReducer reducer(&jsgraph); |
160 Reduction r = reducer.Reduce(n); | 160 Reduction r = reducer.Reduce(n); |
161 CHECK(r.Changed()); | 161 CHECK(r.Changed()); |
162 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 162 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
163 CHECK_EQ(OperatorProperties::GetTotalInputCount(op_expect), | 163 CHECK_EQ(OperatorProperties::GetTotalInputCount(op_expect), |
164 r.replacement()->InputCount()); | 164 r.replacement()->InputCount()); |
165 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); | 165 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); |
166 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); | 166 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); |
167 } | 167 } |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 Node* store = R.graph.NewNode( | 716 Node* store = R.graph.NewNode( |
717 R.machine.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier)), base, | 717 R.machine.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier)), base, |
718 index, load); | 718 index, load); |
719 MachineOperatorReducer reducer(&R.jsgraph); | 719 MachineOperatorReducer reducer(&R.jsgraph); |
720 Reduction reduction = reducer.Reduce(store); | 720 Reduction reduction = reducer.Reduce(store); |
721 CHECK(!reduction.Changed()); // stores should not be reduced. | 721 CHECK(!reduction.Changed()); // stores should not be reduced. |
722 } | 722 } |
723 } | 723 } |
724 | 724 |
725 | 725 |
726 static void CheckNans(ReducerTester* R) { | |
727 Node* x = R->Parameter(); | |
728 std::vector<double> nans = ValueHelper::nan_vector(); | |
729 for (std::vector<double>::const_iterator pl = nans.begin(); pl != nans.end(); | |
730 ++pl) { | |
731 for (std::vector<double>::const_iterator pr = nans.begin(); | |
732 pr != nans.end(); ++pr) { | |
733 Node* nan1 = R->Constant<double>(*pl); | |
734 Node* nan2 = R->Constant<double>(*pr); | |
735 R->CheckBinop(nan1, x, nan1); // x op NaN => NaN | |
736 R->CheckBinop(nan1, nan1, x); // NaN op x => NaN | |
737 R->CheckBinop(nan1, nan2, nan1); // NaN op NaN => NaN | |
738 } | |
739 } | |
740 } | |
741 | |
742 | |
743 TEST(ReduceFloat64Add) { | |
744 ReducerTester R; | |
745 R.binop = R.machine.Float64Add(); | |
746 | |
747 FOR_FLOAT64_INPUTS(pl) { | |
748 FOR_FLOAT64_INPUTS(pr) { | |
749 double x = *pl, y = *pr; | |
750 R.CheckFoldBinop<double>(x + y, x, y); | |
751 } | |
752 } | |
753 | |
754 FOR_FLOAT64_INPUTS(i) { | |
755 Double tmp(*i); | |
756 if (!tmp.IsSpecial() || tmp.IsInfinite()) { | |
757 // Don't check NaNs as they are reduced more. | |
758 R.CheckPutConstantOnRight(*i); | |
759 } | |
760 } | |
761 | |
762 CheckNans(&R); | |
763 } | |
764 | |
765 | |
766 TEST(ReduceFloat64Sub) { | |
767 ReducerTester R; | |
768 R.binop = R.machine.Float64Sub(); | |
769 | |
770 FOR_FLOAT64_INPUTS(pl) { | |
771 FOR_FLOAT64_INPUTS(pr) { | |
772 double x = *pl, y = *pr; | |
773 R.CheckFoldBinop<double>(x - y, x, y); | |
774 } | |
775 } | |
776 | |
777 Node* zero = R.Constant<double>(0.0); | |
778 Node* x = R.Parameter(); | |
779 | |
780 R.CheckBinop(x, x, zero); // x - 0.0 => x | |
781 | |
782 CheckNans(&R); | |
783 } | |
784 | |
785 | |
786 TEST(ReduceFloat64Mul) { | |
787 ReducerTester R; | |
788 R.binop = R.machine.Float64Mul(); | |
789 | |
790 FOR_FLOAT64_INPUTS(pl) { | |
791 FOR_FLOAT64_INPUTS(pr) { | |
792 double x = *pl, y = *pr; | |
793 R.CheckFoldBinop<double>(x * y, x, y); | |
794 } | |
795 } | |
796 | |
797 double inf = V8_INFINITY; | |
798 R.CheckPutConstantOnRight(-inf); | |
799 R.CheckPutConstantOnRight(-0.1); | |
800 R.CheckPutConstantOnRight(0.1); | |
801 R.CheckPutConstantOnRight(inf); | |
802 | |
803 Node* x = R.Parameter(); | |
804 Node* one = R.Constant<double>(1.0); | |
805 | |
806 R.CheckBinop(x, x, one); // x * 1.0 => x | |
807 R.CheckBinop(x, one, x); // 1.0 * x => x | |
808 | |
809 CheckNans(&R); | |
810 } | |
811 | |
812 | |
813 TEST(ReduceFloat64Div) { | |
814 ReducerTester R; | |
815 R.binop = R.machine.Float64Div(); | |
816 | |
817 FOR_FLOAT64_INPUTS(pl) { | |
818 FOR_FLOAT64_INPUTS(pr) { | |
819 double x = *pl, y = *pr; | |
820 R.CheckFoldBinop<double>(x / y, x, y); | |
821 } | |
822 } | |
823 | |
824 Node* x = R.Parameter(); | |
825 Node* one = R.Constant<double>(1.0); | |
826 | |
827 R.CheckBinop(x, x, one); // x / 1.0 => x | |
828 | |
829 CheckNans(&R); | |
830 } | |
831 | |
832 | |
833 TEST(ReduceFloat64Mod) { | |
834 ReducerTester R; | |
835 R.binop = R.machine.Float64Mod(); | |
836 | |
837 FOR_FLOAT64_INPUTS(pl) { | |
838 FOR_FLOAT64_INPUTS(pr) { | |
839 double x = *pl, y = *pr; | |
840 R.CheckFoldBinop<double>(modulo(x, y), x, y); | |
841 } | |
842 } | |
843 | |
844 Node* x = R.Parameter(); | |
845 Node* zero = R.Constant<double>(0.0); | |
846 | |
847 R.CheckFoldBinop<double>(std::numeric_limits<double>::quiet_NaN(), x, zero); | |
848 | |
849 CheckNans(&R); | |
850 } | |
851 | |
852 | |
853 // TODO(titzer): test MachineOperatorReducer for Word64And | 726 // TODO(titzer): test MachineOperatorReducer for Word64And |
854 // TODO(titzer): test MachineOperatorReducer for Word64Or | 727 // TODO(titzer): test MachineOperatorReducer for Word64Or |
855 // TODO(titzer): test MachineOperatorReducer for Word64Xor | 728 // TODO(titzer): test MachineOperatorReducer for Word64Xor |
856 // TODO(titzer): test MachineOperatorReducer for Word64Shl | 729 // TODO(titzer): test MachineOperatorReducer for Word64Shl |
857 // TODO(titzer): test MachineOperatorReducer for Word64Shr | 730 // TODO(titzer): test MachineOperatorReducer for Word64Shr |
858 // TODO(titzer): test MachineOperatorReducer for Word64Sar | 731 // TODO(titzer): test MachineOperatorReducer for Word64Sar |
859 // TODO(titzer): test MachineOperatorReducer for Word64Equal | 732 // TODO(titzer): test MachineOperatorReducer for Word64Equal |
860 // TODO(titzer): test MachineOperatorReducer for Word64Not | 733 // TODO(titzer): test MachineOperatorReducer for Word64Not |
861 // TODO(titzer): test MachineOperatorReducer for Int64Add | 734 // TODO(titzer): test MachineOperatorReducer for Int64Add |
862 // TODO(titzer): test MachineOperatorReducer for Int64Sub | 735 // TODO(titzer): test MachineOperatorReducer for Int64Sub |
863 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 736 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
864 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 737 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
865 // TODO(titzer): test MachineOperatorReducer for Int64Div | 738 // TODO(titzer): test MachineOperatorReducer for Int64Div |
866 // TODO(titzer): test MachineOperatorReducer for Uint64Div | 739 // TODO(titzer): test MachineOperatorReducer for Uint64Div |
867 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 740 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
868 // TODO(titzer): test MachineOperatorReducer for Uint64Mod | 741 // TODO(titzer): test MachineOperatorReducer for Uint64Mod |
869 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 742 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
870 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 743 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
871 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 744 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
872 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 745 // TODO(titzer): test MachineOperatorReducer for Float64Compare |
| 746 // TODO(titzer): test MachineOperatorReducer for Float64Add |
| 747 // TODO(titzer): test MachineOperatorReducer for Float64Sub |
| 748 // TODO(titzer): test MachineOperatorReducer for Float64Mul |
| 749 // TODO(titzer): test MachineOperatorReducer for Float64Div |
| 750 // TODO(titzer): test MachineOperatorReducer for Float64Mod |
OLD | NEW |