| 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" |
| 11 #include "src/compiler/machine-operator-reducer.h" | 11 #include "src/compiler/machine-operator-reducer.h" |
| 12 #include "src/compiler/operator-properties.h" |
| 13 #include "src/compiler/operator-properties-inl.h" |
| 12 #include "src/compiler/typer.h" | 14 #include "src/compiler/typer.h" |
| 13 #include "test/cctest/compiler/value-helper.h" | 15 #include "test/cctest/compiler/value-helper.h" |
| 14 | 16 |
| 15 using namespace v8::internal; | 17 using namespace v8::internal; |
| 16 using namespace v8::internal::compiler; | 18 using namespace v8::internal::compiler; |
| 17 | 19 |
| 18 template <typename T> | 20 template <typename T> |
| 19 const Operator* NewConstantOperator(CommonOperatorBuilder* common, | 21 const Operator* NewConstantOperator(CommonOperatorBuilder* common, |
| 20 volatile T value); | 22 volatile T value); |
| 21 | 23 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 template <typename T> | 92 template <typename T> |
| 91 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { | 93 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { |
| 92 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); | 94 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); |
| 93 } | 95 } |
| 94 | 96 |
| 95 // Check that the reduction of this binop applied to {a} and {b} yields | 97 // Check that the reduction of this binop applied to {a} and {b} yields |
| 96 // the {expect} value. | 98 // the {expect} value. |
| 97 template <typename T> | 99 template <typename T> |
| 98 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { | 100 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { |
| 99 CHECK_NE(NULL, binop); | 101 CHECK_NE(NULL, binop); |
| 100 Node* n = graph.NewNode(binop, a, b); | 102 Node* n = CreateBinopNode(a, b); |
| 101 MachineOperatorReducer reducer(&jsgraph); | 103 MachineOperatorReducer reducer(&jsgraph); |
| 102 Reduction reduction = reducer.Reduce(n); | 104 Reduction reduction = reducer.Reduce(n); |
| 103 CHECK(reduction.Changed()); | 105 CHECK(reduction.Changed()); |
| 104 CHECK_NE(n, reduction.replacement()); | 106 CHECK_NE(n, reduction.replacement()); |
| 105 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); | 107 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); |
| 106 } | 108 } |
| 107 | 109 |
| 108 // Check that the reduction of this binop applied to {a} and {b} yields | 110 // Check that the reduction of this binop applied to {a} and {b} yields |
| 109 // the {expect} node. | 111 // the {expect} node. |
| 110 void CheckBinop(Node* expect, Node* a, Node* b) { | 112 void CheckBinop(Node* expect, Node* a, Node* b) { |
| 111 CHECK_NE(NULL, binop); | 113 CHECK_NE(NULL, binop); |
| 112 Node* n = graph.NewNode(binop, a, b); | 114 Node* n = CreateBinopNode(a, b); |
| 113 MachineOperatorReducer reducer(&jsgraph); | 115 MachineOperatorReducer reducer(&jsgraph); |
| 114 Reduction reduction = reducer.Reduce(n); | 116 Reduction reduction = reducer.Reduce(n); |
| 115 CHECK(reduction.Changed()); | 117 CHECK(reduction.Changed()); |
| 116 CHECK_EQ(expect, reduction.replacement()); | 118 CHECK_EQ(expect, reduction.replacement()); |
| 117 } | 119 } |
| 118 | 120 |
| 119 // Check that the reduction of this binop applied to {left} and {right} yields | 121 // Check that the reduction of this binop applied to {left} and {right} yields |
| 120 // this binop applied to {left_expect} and {right_expect}. | 122 // this binop applied to {left_expect} and {right_expect}. |
| 121 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, | 123 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, |
| 122 Node* right) { | 124 Node* right) { |
| 123 CHECK_NE(NULL, binop); | 125 CHECK_NE(NULL, binop); |
| 124 Node* n = graph.NewNode(binop, left, right); | 126 Node* n = CreateBinopNode(left, right); |
| 125 MachineOperatorReducer reducer(&jsgraph); | 127 MachineOperatorReducer reducer(&jsgraph); |
| 126 Reduction reduction = reducer.Reduce(n); | 128 Reduction reduction = reducer.Reduce(n); |
| 127 CHECK(reduction.Changed()); | 129 CHECK(reduction.Changed()); |
| 128 CHECK_EQ(binop, reduction.replacement()->op()); | 130 CHECK_EQ(binop, reduction.replacement()->op()); |
| 129 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); | 131 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); |
| 130 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); | 132 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); |
| 131 } | 133 } |
| 132 | 134 |
| 133 // Check that the reduction of this binop applied to {left} and {right} yields | 135 // Check that the reduction of this binop applied to {left} and {right} yields |
| 134 // the {op_expect} applied to {left_expect} and {right_expect}. | 136 // the {op_expect} applied to {left_expect} and {right_expect}. |
| 135 template <typename T> | 137 template <typename T> |
| 136 void CheckFoldBinop(volatile T left_expect, const Operator* op_expect, | 138 void CheckFoldBinop(volatile T left_expect, const Operator* op_expect, |
| 137 Node* right_expect, Node* left, Node* right) { | 139 Node* right_expect, Node* left, Node* right) { |
| 138 CHECK_NE(NULL, binop); | 140 CHECK_NE(NULL, binop); |
| 139 Node* n = graph.NewNode(binop, left, right); | 141 Node* n = CreateBinopNode(left, right); |
| 140 MachineOperatorReducer reducer(&jsgraph); | 142 MachineOperatorReducer reducer(&jsgraph); |
| 141 Reduction r = reducer.Reduce(n); | 143 Reduction r = reducer.Reduce(n); |
| 142 CHECK(r.Changed()); | 144 CHECK(r.Changed()); |
| 143 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 145 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
| 144 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); | 146 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); |
| 145 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); | 147 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); |
| 146 } | 148 } |
| 147 | 149 |
| 148 // Check that the reduction of this binop applied to {left} and {right} yields | 150 // Check that the reduction of this binop applied to {left} and {right} yields |
| 149 // the {op_expect} applied to {left_expect} and {right_expect}. | 151 // the {op_expect} applied to {left_expect} and {right_expect}. |
| 150 template <typename T> | 152 template <typename T> |
| 151 void CheckFoldBinop(Node* left_expect, const Operator* op_expect, | 153 void CheckFoldBinop(Node* left_expect, const Operator* op_expect, |
| 152 volatile T right_expect, Node* left, Node* right) { | 154 volatile T right_expect, Node* left, Node* right) { |
| 153 CHECK_NE(NULL, binop); | 155 CHECK_NE(NULL, binop); |
| 154 Node* n = graph.NewNode(binop, left, right); | 156 Node* n = CreateBinopNode(left, right); |
| 155 MachineOperatorReducer reducer(&jsgraph); | 157 MachineOperatorReducer reducer(&jsgraph); |
| 156 Reduction r = reducer.Reduce(n); | 158 Reduction r = reducer.Reduce(n); |
| 157 CHECK(r.Changed()); | 159 CHECK(r.Changed()); |
| 158 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 160 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
| 161 CHECK_EQ(OperatorProperties::GetTotalInputCount(op_expect), |
| 162 r.replacement()->InputCount()); |
| 159 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); | 163 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); |
| 160 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); | 164 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); |
| 161 } | 165 } |
| 162 | 166 |
| 163 // Check that if the given constant appears on the left, the reducer will | 167 // Check that if the given constant appears on the left, the reducer will |
| 164 // swap it to be on the right. | 168 // swap it to be on the right. |
| 165 template <typename T> | 169 template <typename T> |
| 166 void CheckPutConstantOnRight(volatile T constant) { | 170 void CheckPutConstantOnRight(volatile T constant) { |
| 167 // TODO(titzer): CHECK(binop->HasProperty(Operator::kCommutative)); | 171 // TODO(titzer): CHECK(binop->HasProperty(Operator::kCommutative)); |
| 168 Node* p = Parameter(); | 172 Node* p = Parameter(); |
| 169 Node* k = Constant<T>(constant); | 173 Node* k = Constant<T>(constant); |
| 170 { | 174 { |
| 171 Node* n = graph.NewNode(binop, k, p); | 175 Node* n = CreateBinopNode(k, p); |
| 172 MachineOperatorReducer reducer(&jsgraph); | 176 MachineOperatorReducer reducer(&jsgraph); |
| 173 Reduction reduction = reducer.Reduce(n); | 177 Reduction reduction = reducer.Reduce(n); |
| 174 CHECK(!reduction.Changed() || reduction.replacement() == n); | 178 CHECK(!reduction.Changed() || reduction.replacement() == n); |
| 175 CHECK_EQ(p, n->InputAt(0)); | 179 CHECK_EQ(p, n->InputAt(0)); |
| 176 CHECK_EQ(k, n->InputAt(1)); | 180 CHECK_EQ(k, n->InputAt(1)); |
| 177 } | 181 } |
| 178 { | 182 { |
| 179 Node* n = graph.NewNode(binop, p, k); | 183 Node* n = CreateBinopNode(p, k); |
| 180 MachineOperatorReducer reducer(&jsgraph); | 184 MachineOperatorReducer reducer(&jsgraph); |
| 181 Reduction reduction = reducer.Reduce(n); | 185 Reduction reduction = reducer.Reduce(n); |
| 182 CHECK(!reduction.Changed()); | 186 CHECK(!reduction.Changed()); |
| 183 CHECK_EQ(p, n->InputAt(0)); | 187 CHECK_EQ(p, n->InputAt(0)); |
| 184 CHECK_EQ(k, n->InputAt(1)); | 188 CHECK_EQ(k, n->InputAt(1)); |
| 185 } | 189 } |
| 186 } | 190 } |
| 187 | 191 |
| 188 // Check that if the given constant appears on the left, the reducer will | 192 // Check that if the given constant appears on the left, the reducer will |
| 189 // *NOT* swap it to be on the right. | 193 // *NOT* swap it to be on the right. |
| 190 template <typename T> | 194 template <typename T> |
| 191 void CheckDontPutConstantOnRight(volatile T constant) { | 195 void CheckDontPutConstantOnRight(volatile T constant) { |
| 192 CHECK(!binop->HasProperty(Operator::kCommutative)); | 196 CHECK(!binop->HasProperty(Operator::kCommutative)); |
| 193 Node* p = Parameter(); | 197 Node* p = Parameter(); |
| 194 Node* k = Constant<T>(constant); | 198 Node* k = Constant<T>(constant); |
| 195 Node* n = graph.NewNode(binop, k, p); | 199 Node* n = CreateBinopNode(k, p); |
| 196 MachineOperatorReducer reducer(&jsgraph); | 200 MachineOperatorReducer reducer(&jsgraph); |
| 197 Reduction reduction = reducer.Reduce(n); | 201 Reduction reduction = reducer.Reduce(n); |
| 198 CHECK(!reduction.Changed()); | 202 CHECK(!reduction.Changed()); |
| 199 CHECK_EQ(k, n->InputAt(0)); | 203 CHECK_EQ(k, n->InputAt(0)); |
| 200 CHECK_EQ(p, n->InputAt(1)); | 204 CHECK_EQ(p, n->InputAt(1)); |
| 201 } | 205 } |
| 202 | 206 |
| 203 Node* Parameter(int32_t index = 0) { | 207 Node* Parameter(int32_t index = 0) { |
| 204 return graph.NewNode(common.Parameter(index), graph.start()); | 208 return graph.NewNode(common.Parameter(index), graph.start()); |
| 205 } | 209 } |
| 210 |
| 211 private: |
| 212 Node* CreateBinopNode(Node* left, Node* right) { |
| 213 if (OperatorProperties::HasControlInput(binop)) { |
| 214 return graph.NewNode(binop, left, right, graph.start()); |
| 215 } else { |
| 216 return graph.NewNode(binop, left, right); |
| 217 } |
| 218 } |
| 206 }; | 219 }; |
| 207 | 220 |
| 208 | 221 |
| 209 TEST(ReduceWord32And) { | 222 TEST(ReduceWord32And) { |
| 210 ReducerTester R; | 223 ReducerTester R; |
| 211 R.binop = R.machine.Word32And(); | 224 R.binop = R.machine.Word32And(); |
| 212 | 225 |
| 213 FOR_INT32_INPUTS(pl) { | 226 FOR_INT32_INPUTS(pl) { |
| 214 FOR_INT32_INPUTS(pr) { | 227 FOR_INT32_INPUTS(pr) { |
| 215 int32_t x = *pl, y = *pr; | 228 int32_t x = *pl, y = *pr; |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 832 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
| 820 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 833 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
| 821 // TODO(titzer): test MachineOperatorReducer for Int64Div | 834 // TODO(titzer): test MachineOperatorReducer for Int64Div |
| 822 // TODO(titzer): test MachineOperatorReducer for Uint64Div | 835 // TODO(titzer): test MachineOperatorReducer for Uint64Div |
| 823 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 836 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
| 824 // TODO(titzer): test MachineOperatorReducer for Uint64Mod | 837 // TODO(titzer): test MachineOperatorReducer for Uint64Mod |
| 825 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 838 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
| 826 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 839 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
| 827 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 840 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
| 828 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 841 // TODO(titzer): test MachineOperatorReducer for Float64Compare |
| OLD | NEW |