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(binop); | 103 CHECK_NE(NULL, 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(binop); | 115 CHECK_NE(NULL, 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(binop); | 127 CHECK_NE(NULL, 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(binop); | 142 CHECK_NE(NULL, 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(binop); | 157 CHECK_NE(NULL, 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 |
726 // TODO(titzer): test MachineOperatorReducer for Word64And | 853 // TODO(titzer): test MachineOperatorReducer for Word64And |
727 // TODO(titzer): test MachineOperatorReducer for Word64Or | 854 // TODO(titzer): test MachineOperatorReducer for Word64Or |
728 // TODO(titzer): test MachineOperatorReducer for Word64Xor | 855 // TODO(titzer): test MachineOperatorReducer for Word64Xor |
729 // TODO(titzer): test MachineOperatorReducer for Word64Shl | 856 // TODO(titzer): test MachineOperatorReducer for Word64Shl |
730 // TODO(titzer): test MachineOperatorReducer for Word64Shr | 857 // TODO(titzer): test MachineOperatorReducer for Word64Shr |
731 // TODO(titzer): test MachineOperatorReducer for Word64Sar | 858 // TODO(titzer): test MachineOperatorReducer for Word64Sar |
732 // TODO(titzer): test MachineOperatorReducer for Word64Equal | 859 // TODO(titzer): test MachineOperatorReducer for Word64Equal |
733 // TODO(titzer): test MachineOperatorReducer for Word64Not | 860 // TODO(titzer): test MachineOperatorReducer for Word64Not |
734 // TODO(titzer): test MachineOperatorReducer for Int64Add | 861 // TODO(titzer): test MachineOperatorReducer for Int64Add |
735 // TODO(titzer): test MachineOperatorReducer for Int64Sub | 862 // TODO(titzer): test MachineOperatorReducer for Int64Sub |
736 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 863 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
737 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 864 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
738 // TODO(titzer): test MachineOperatorReducer for Int64Div | 865 // TODO(titzer): test MachineOperatorReducer for Int64Div |
739 // TODO(titzer): test MachineOperatorReducer for Uint64Div | 866 // TODO(titzer): test MachineOperatorReducer for Uint64Div |
740 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 867 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
741 // TODO(titzer): test MachineOperatorReducer for Uint64Mod | 868 // TODO(titzer): test MachineOperatorReducer for Uint64Mod |
742 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 869 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
743 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 870 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
744 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 871 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
745 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 872 // 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 |