| 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/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
| 9 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/machine-operator-reducer.h" | 10 #include "src/compiler/machine-operator-reducer.h" |
| 11 #include "src/compiler/typer.h" |
| 10 #include "test/cctest/compiler/value-helper.h" | 12 #include "test/cctest/compiler/value-helper.h" |
| 11 | 13 |
| 12 using namespace v8::internal; | 14 using namespace v8::internal; |
| 13 using namespace v8::internal::compiler; | 15 using namespace v8::internal::compiler; |
| 14 | 16 |
| 15 template <typename T> | 17 template <typename T> |
| 16 Operator* NewConstantOperator(CommonOperatorBuilder* common, volatile T value); | 18 Operator* NewConstantOperator(CommonOperatorBuilder* common, volatile T value); |
| 17 | 19 |
| 18 template <> | 20 template <> |
| 19 Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common, | 21 Operator* NewConstantOperator<int32_t>(CommonOperatorBuilder* common, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 30 | 32 |
| 31 class ReducerTester : public HandleAndZoneScope { | 33 class ReducerTester : public HandleAndZoneScope { |
| 32 public: | 34 public: |
| 33 explicit ReducerTester(int num_parameters = 0) | 35 explicit ReducerTester(int num_parameters = 0) |
| 34 : isolate(main_isolate()), | 36 : isolate(main_isolate()), |
| 35 binop(NULL), | 37 binop(NULL), |
| 36 unop(NULL), | 38 unop(NULL), |
| 37 machine(main_zone()), | 39 machine(main_zone()), |
| 38 common(main_zone()), | 40 common(main_zone()), |
| 39 graph(main_zone()), | 41 graph(main_zone()), |
| 42 typer(main_zone()), |
| 43 jsgraph(&graph, &common, &typer), |
| 40 maxuint32(Constant<int32_t>(kMaxUInt32)) { | 44 maxuint32(Constant<int32_t>(kMaxUInt32)) { |
| 41 Node* s = graph.NewNode(common.Start(num_parameters)); | 45 Node* s = graph.NewNode(common.Start(num_parameters)); |
| 42 graph.SetStart(s); | 46 graph.SetStart(s); |
| 43 } | 47 } |
| 44 | 48 |
| 45 Isolate* isolate; | 49 Isolate* isolate; |
| 46 Operator* binop; | 50 Operator* binop; |
| 47 Operator* unop; | 51 Operator* unop; |
| 48 MachineOperatorBuilder machine; | 52 MachineOperatorBuilder machine; |
| 49 CommonOperatorBuilder common; | 53 CommonOperatorBuilder common; |
| 50 Graph graph; | 54 Graph graph; |
| 55 Typer typer; |
| 56 JSGraph jsgraph; |
| 51 Node* maxuint32; | 57 Node* maxuint32; |
| 52 | 58 |
| 53 template <typename T> | 59 template <typename T> |
| 54 Node* Constant(volatile T value) { | 60 Node* Constant(volatile T value) { |
| 55 return graph.NewNode(NewConstantOperator<T>(&common, value)); | 61 return graph.NewNode(NewConstantOperator<T>(&common, value)); |
| 56 } | 62 } |
| 57 | 63 |
| 58 // Check that the reduction of this binop applied to constants {a} and {b} | 64 // Check that the reduction of this binop applied to constants {a} and {b} |
| 59 // yields the {expect} value. | 65 // yields the {expect} value. |
| 60 template <typename T> | 66 template <typename T> |
| 61 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { | 67 void CheckFoldBinop(volatile T expect, volatile T a, volatile T b) { |
| 62 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); | 68 CheckFoldBinop<T>(expect, Constant<T>(a), Constant<T>(b)); |
| 63 } | 69 } |
| 64 | 70 |
| 65 // Check that the reduction of this binop applied to {a} and {b} yields | 71 // Check that the reduction of this binop applied to {a} and {b} yields |
| 66 // the {expect} value. | 72 // the {expect} value. |
| 67 template <typename T> | 73 template <typename T> |
| 68 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { | 74 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { |
| 69 CHECK_NE(NULL, binop); | 75 CHECK_NE(NULL, binop); |
| 70 Node* n = graph.NewNode(binop, a, b); | 76 Node* n = graph.NewNode(binop, a, b); |
| 71 MachineOperatorReducer reducer(&graph); | 77 MachineOperatorReducer reducer(&jsgraph); |
| 72 Reduction reduction = reducer.Reduce(n); | 78 Reduction reduction = reducer.Reduce(n); |
| 73 CHECK(reduction.Changed()); | 79 CHECK(reduction.Changed()); |
| 74 CHECK_NE(n, reduction.replacement()); | 80 CHECK_NE(n, reduction.replacement()); |
| 75 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); | 81 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); |
| 76 } | 82 } |
| 77 | 83 |
| 78 // Check that the reduction of this binop applied to {a} and {b} yields | 84 // Check that the reduction of this binop applied to {a} and {b} yields |
| 79 // the {expect} node. | 85 // the {expect} node. |
| 80 void CheckBinop(Node* expect, Node* a, Node* b) { | 86 void CheckBinop(Node* expect, Node* a, Node* b) { |
| 81 CHECK_NE(NULL, binop); | 87 CHECK_NE(NULL, binop); |
| 82 Node* n = graph.NewNode(binop, a, b); | 88 Node* n = graph.NewNode(binop, a, b); |
| 83 MachineOperatorReducer reducer(&graph); | 89 MachineOperatorReducer reducer(&jsgraph); |
| 84 Reduction reduction = reducer.Reduce(n); | 90 Reduction reduction = reducer.Reduce(n); |
| 85 CHECK(reduction.Changed()); | 91 CHECK(reduction.Changed()); |
| 86 CHECK_EQ(expect, reduction.replacement()); | 92 CHECK_EQ(expect, reduction.replacement()); |
| 87 } | 93 } |
| 88 | 94 |
| 89 // Check that the reduction of this binop applied to {left} and {right} yields | 95 // Check that the reduction of this binop applied to {left} and {right} yields |
| 90 // this binop applied to {left_expect} and {right_expect}. | 96 // this binop applied to {left_expect} and {right_expect}. |
| 91 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, | 97 void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left, |
| 92 Node* right) { | 98 Node* right) { |
| 93 CHECK_NE(NULL, binop); | 99 CHECK_NE(NULL, binop); |
| 94 Node* n = graph.NewNode(binop, left, right); | 100 Node* n = graph.NewNode(binop, left, right); |
| 95 MachineOperatorReducer reducer(&graph); | 101 MachineOperatorReducer reducer(&jsgraph); |
| 96 Reduction reduction = reducer.Reduce(n); | 102 Reduction reduction = reducer.Reduce(n); |
| 97 CHECK(reduction.Changed()); | 103 CHECK(reduction.Changed()); |
| 98 CHECK_EQ(binop, reduction.replacement()->op()); | 104 CHECK_EQ(binop, reduction.replacement()->op()); |
| 99 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); | 105 CHECK_EQ(left_expect, reduction.replacement()->InputAt(0)); |
| 100 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); | 106 CHECK_EQ(right_expect, reduction.replacement()->InputAt(1)); |
| 101 } | 107 } |
| 102 | 108 |
| 103 // Check that the reduction of this binop applied to {left} and {right} yields | 109 // Check that the reduction of this binop applied to {left} and {right} yields |
| 104 // the {op_expect} applied to {left_expect} and {right_expect}. | 110 // the {op_expect} applied to {left_expect} and {right_expect}. |
| 105 template <typename T> | 111 template <typename T> |
| 106 void CheckFoldBinop(volatile T left_expect, Operator* op_expect, | 112 void CheckFoldBinop(volatile T left_expect, Operator* op_expect, |
| 107 Node* right_expect, Node* left, Node* right) { | 113 Node* right_expect, Node* left, Node* right) { |
| 108 CHECK_NE(NULL, binop); | 114 CHECK_NE(NULL, binop); |
| 109 Node* n = graph.NewNode(binop, left, right); | 115 Node* n = graph.NewNode(binop, left, right); |
| 110 MachineOperatorReducer reducer(&graph); | 116 MachineOperatorReducer reducer(&jsgraph); |
| 111 Reduction r = reducer.Reduce(n); | 117 Reduction r = reducer.Reduce(n); |
| 112 CHECK(r.Changed()); | 118 CHECK(r.Changed()); |
| 113 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 119 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
| 114 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); | 120 CHECK_EQ(left_expect, ValueOf<T>(r.replacement()->InputAt(0)->op())); |
| 115 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); | 121 CHECK_EQ(right_expect, r.replacement()->InputAt(1)); |
| 116 } | 122 } |
| 117 | 123 |
| 118 // Check that the reduction of this binop applied to {left} and {right} yields | 124 // Check that the reduction of this binop applied to {left} and {right} yields |
| 119 // the {op_expect} applied to {left_expect} and {right_expect}. | 125 // the {op_expect} applied to {left_expect} and {right_expect}. |
| 120 template <typename T> | 126 template <typename T> |
| 121 void CheckFoldBinop(Node* left_expect, Operator* op_expect, | 127 void CheckFoldBinop(Node* left_expect, Operator* op_expect, |
| 122 volatile T right_expect, Node* left, Node* right) { | 128 volatile T right_expect, Node* left, Node* right) { |
| 123 CHECK_NE(NULL, binop); | 129 CHECK_NE(NULL, binop); |
| 124 Node* n = graph.NewNode(binop, left, right); | 130 Node* n = graph.NewNode(binop, left, right); |
| 125 MachineOperatorReducer reducer(&graph); | 131 MachineOperatorReducer reducer(&jsgraph); |
| 126 Reduction r = reducer.Reduce(n); | 132 Reduction r = reducer.Reduce(n); |
| 127 CHECK(r.Changed()); | 133 CHECK(r.Changed()); |
| 128 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); | 134 CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode()); |
| 129 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); | 135 CHECK_EQ(left_expect, r.replacement()->InputAt(0)); |
| 130 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); | 136 CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op())); |
| 131 } | 137 } |
| 132 | 138 |
| 133 // Check that if the given constant appears on the left, the reducer will | 139 // Check that if the given constant appears on the left, the reducer will |
| 134 // swap it to be on the right. | 140 // swap it to be on the right. |
| 135 template <typename T> | 141 template <typename T> |
| 136 void CheckPutConstantOnRight(volatile T constant) { | 142 void CheckPutConstantOnRight(volatile T constant) { |
| 137 // TODO(titzer): CHECK(binop->HasProperty(Operator::kCommutative)); | 143 // TODO(titzer): CHECK(binop->HasProperty(Operator::kCommutative)); |
| 138 Node* p = Parameter(); | 144 Node* p = Parameter(); |
| 139 Node* k = Constant<T>(constant); | 145 Node* k = Constant<T>(constant); |
| 140 { | 146 { |
| 141 Node* n = graph.NewNode(binop, k, p); | 147 Node* n = graph.NewNode(binop, k, p); |
| 142 MachineOperatorReducer reducer(&graph); | 148 MachineOperatorReducer reducer(&jsgraph); |
| 143 Reduction reduction = reducer.Reduce(n); | 149 Reduction reduction = reducer.Reduce(n); |
| 144 CHECK(!reduction.Changed() || reduction.replacement() == n); | 150 CHECK(!reduction.Changed() || reduction.replacement() == n); |
| 145 CHECK_EQ(p, n->InputAt(0)); | 151 CHECK_EQ(p, n->InputAt(0)); |
| 146 CHECK_EQ(k, n->InputAt(1)); | 152 CHECK_EQ(k, n->InputAt(1)); |
| 147 } | 153 } |
| 148 { | 154 { |
| 149 Node* n = graph.NewNode(binop, p, k); | 155 Node* n = graph.NewNode(binop, p, k); |
| 150 MachineOperatorReducer reducer(&graph); | 156 MachineOperatorReducer reducer(&jsgraph); |
| 151 Reduction reduction = reducer.Reduce(n); | 157 Reduction reduction = reducer.Reduce(n); |
| 152 CHECK(!reduction.Changed()); | 158 CHECK(!reduction.Changed()); |
| 153 CHECK_EQ(p, n->InputAt(0)); | 159 CHECK_EQ(p, n->InputAt(0)); |
| 154 CHECK_EQ(k, n->InputAt(1)); | 160 CHECK_EQ(k, n->InputAt(1)); |
| 155 } | 161 } |
| 156 } | 162 } |
| 157 | 163 |
| 158 // Check that if the given constant appears on the left, the reducer will | 164 // Check that if the given constant appears on the left, the reducer will |
| 159 // *NOT* swap it to be on the right. | 165 // *NOT* swap it to be on the right. |
| 160 template <typename T> | 166 template <typename T> |
| 161 void CheckDontPutConstantOnRight(volatile T constant) { | 167 void CheckDontPutConstantOnRight(volatile T constant) { |
| 162 CHECK(!binop->HasProperty(Operator::kCommutative)); | 168 CHECK(!binop->HasProperty(Operator::kCommutative)); |
| 163 Node* p = Parameter(); | 169 Node* p = Parameter(); |
| 164 Node* k = Constant<T>(constant); | 170 Node* k = Constant<T>(constant); |
| 165 Node* n = graph.NewNode(binop, k, p); | 171 Node* n = graph.NewNode(binop, k, p); |
| 166 MachineOperatorReducer reducer(&graph); | 172 MachineOperatorReducer reducer(&jsgraph); |
| 167 Reduction reduction = reducer.Reduce(n); | 173 Reduction reduction = reducer.Reduce(n); |
| 168 CHECK(!reduction.Changed()); | 174 CHECK(!reduction.Changed()); |
| 169 CHECK_EQ(k, n->InputAt(0)); | 175 CHECK_EQ(k, n->InputAt(0)); |
| 170 CHECK_EQ(p, n->InputAt(1)); | 176 CHECK_EQ(p, n->InputAt(1)); |
| 171 } | 177 } |
| 172 | 178 |
| 173 Node* Parameter(int32_t index = 0) { | 179 Node* Parameter(int32_t index = 0) { |
| 174 return graph.NewNode(common.Parameter(index), graph.start()); | 180 return graph.NewNode(common.Parameter(index), graph.start()); |
| 175 } | 181 } |
| 176 }; | 182 }; |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 | 632 |
| 627 | 633 |
| 628 TEST(ReduceLoadStore) { | 634 TEST(ReduceLoadStore) { |
| 629 ReducerTester R; | 635 ReducerTester R; |
| 630 | 636 |
| 631 Node* base = R.Constant<int32_t>(11); | 637 Node* base = R.Constant<int32_t>(11); |
| 632 Node* index = R.Constant<int32_t>(4); | 638 Node* index = R.Constant<int32_t>(4); |
| 633 Node* load = R.graph.NewNode(R.machine.Load(kMachInt32), base, index); | 639 Node* load = R.graph.NewNode(R.machine.Load(kMachInt32), base, index); |
| 634 | 640 |
| 635 { | 641 { |
| 636 MachineOperatorReducer reducer(&R.graph); | 642 MachineOperatorReducer reducer(&R.jsgraph); |
| 637 Reduction reduction = reducer.Reduce(load); | 643 Reduction reduction = reducer.Reduce(load); |
| 638 CHECK(!reduction.Changed()); // loads should not be reduced. | 644 CHECK(!reduction.Changed()); // loads should not be reduced. |
| 639 } | 645 } |
| 640 | 646 |
| 641 { | 647 { |
| 642 Node* store = R.graph.NewNode(R.machine.Store(kMachInt32, kNoWriteBarrier), | 648 Node* store = R.graph.NewNode(R.machine.Store(kMachInt32, kNoWriteBarrier), |
| 643 base, index, load); | 649 base, index, load); |
| 644 MachineOperatorReducer reducer(&R.graph); | 650 MachineOperatorReducer reducer(&R.jsgraph); |
| 645 Reduction reduction = reducer.Reduce(store); | 651 Reduction reduction = reducer.Reduce(store); |
| 646 CHECK(!reduction.Changed()); // stores should not be reduced. | 652 CHECK(!reduction.Changed()); // stores should not be reduced. |
| 647 } | 653 } |
| 648 } | 654 } |
| 649 | 655 |
| 650 | 656 |
| 651 static void CheckNans(ReducerTester* R) { | 657 static void CheckNans(ReducerTester* R) { |
| 652 Node* x = R->Parameter(); | 658 Node* x = R->Parameter(); |
| 653 std::vector<double> nans = ValueHelper::nan_vector(); | 659 std::vector<double> nans = ValueHelper::nan_vector(); |
| 654 for (std::vector<double>::const_iterator pl = nans.begin(); pl != nans.end(); | 660 for (std::vector<double>::const_iterator pl = nans.begin(); pl != nans.end(); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 776 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
| 771 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 777 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
| 772 // TODO(titzer): test MachineOperatorReducer for Int64Div | 778 // TODO(titzer): test MachineOperatorReducer for Int64Div |
| 773 // TODO(titzer): test MachineOperatorReducer for Int64UDiv | 779 // TODO(titzer): test MachineOperatorReducer for Int64UDiv |
| 774 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 780 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
| 775 // TODO(titzer): test MachineOperatorReducer for Int64UMod | 781 // TODO(titzer): test MachineOperatorReducer for Int64UMod |
| 776 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 782 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
| 777 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 783 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
| 778 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 784 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
| 779 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 785 // TODO(titzer): test MachineOperatorReducer for Float64Compare |
| OLD | NEW |