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/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
6 #include "src/codegen.h" | 6 #include "src/codegen.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/machine-operator-reducer.h" | 8 #include "src/compiler/machine-operator-reducer.h" |
9 #include "src/compiler/operator-properties.h" | 9 #include "src/compiler/operator-properties.h" |
10 #include "src/compiler/typer.h" | 10 #include "src/compiler/typer.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 volatile int64_t value) { | 30 volatile int64_t value) { |
31 return common->Int64Constant(value); | 31 return common->Int64Constant(value); |
32 } | 32 } |
33 | 33 |
34 template <> | 34 template <> |
35 const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common, | 35 const Operator* NewConstantOperator<double>(CommonOperatorBuilder* common, |
36 volatile double value) { | 36 volatile double value) { |
37 return common->Float64Constant(value); | 37 return common->Float64Constant(value); |
38 } | 38 } |
39 | 39 |
| 40 template <> |
| 41 const Operator* NewConstantOperator<float>(CommonOperatorBuilder* common, |
| 42 volatile float value) { |
| 43 return common->Float32Constant(value); |
| 44 } |
40 | 45 |
41 template <typename T> | 46 template <typename T> |
42 T ValueOfOperator(const Operator* op); | 47 T ValueOfOperator(const Operator* op); |
43 | 48 |
44 template <> | 49 template <> |
45 int32_t ValueOfOperator<int32_t>(const Operator* op) { | 50 int32_t ValueOfOperator<int32_t>(const Operator* op) { |
46 CHECK_EQ(IrOpcode::kInt32Constant, op->opcode()); | 51 CHECK_EQ(IrOpcode::kInt32Constant, op->opcode()); |
47 return OpParameter<int32_t>(op); | 52 return OpParameter<int32_t>(op); |
48 } | 53 } |
49 | 54 |
50 template <> | 55 template <> |
51 int64_t ValueOfOperator<int64_t>(const Operator* op) { | 56 int64_t ValueOfOperator<int64_t>(const Operator* op) { |
52 CHECK_EQ(IrOpcode::kInt64Constant, op->opcode()); | 57 CHECK_EQ(IrOpcode::kInt64Constant, op->opcode()); |
53 return OpParameter<int64_t>(op); | 58 return OpParameter<int64_t>(op); |
54 } | 59 } |
55 | 60 |
56 template <> | 61 template <> |
| 62 float ValueOfOperator<float>(const Operator* op) { |
| 63 CHECK_EQ(IrOpcode::kFloat32Constant, op->opcode()); |
| 64 return OpParameter<float>(op); |
| 65 } |
| 66 |
| 67 template <> |
57 double ValueOfOperator<double>(const Operator* op) { | 68 double ValueOfOperator<double>(const Operator* op) { |
58 CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode()); | 69 CHECK_EQ(IrOpcode::kFloat64Constant, op->opcode()); |
59 return OpParameter<double>(op); | 70 return OpParameter<double>(op); |
60 } | 71 } |
61 | 72 |
62 | 73 |
63 class ReducerTester : public HandleAndZoneScope { | 74 class ReducerTester : public HandleAndZoneScope { |
64 public: | 75 public: |
65 explicit ReducerTester( | 76 explicit ReducerTester(int num_parameters = 0, |
66 int num_parameters = 0, | 77 MachineOperatorBuilder::Flags flags = |
67 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) | 78 MachineOperatorBuilder::kAllOptionalOps) |
68 : isolate(main_isolate()), | 79 : isolate(main_isolate()), |
69 binop(NULL), | 80 binop(NULL), |
70 unop(NULL), | 81 unop(NULL), |
71 machine(main_zone(), MachineType::PointerRepresentation(), flags), | 82 machine(main_zone(), MachineType::PointerRepresentation(), flags), |
72 common(main_zone()), | 83 common(main_zone()), |
73 graph(main_zone()), | 84 graph(main_zone()), |
74 javascript(main_zone()), | 85 javascript(main_zone()), |
75 typer(isolate, &graph), | 86 typer(isolate, &graph), |
76 jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine), | 87 jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine), |
77 maxuint32(Constant<int32_t>(kMaxUInt32)) { | 88 maxuint32(Constant<int32_t>(kMaxUInt32)) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // Check that the reduction of this binop applied to {a} and {b} yields | 121 // Check that the reduction of this binop applied to {a} and {b} yields |
111 // the {expect} value. | 122 // the {expect} value. |
112 template <typename T> | 123 template <typename T> |
113 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { | 124 void CheckFoldBinop(volatile T expect, Node* a, Node* b) { |
114 CHECK(binop); | 125 CHECK(binop); |
115 Node* n = CreateBinopNode(a, b); | 126 Node* n = CreateBinopNode(a, b); |
116 MachineOperatorReducer reducer(&jsgraph); | 127 MachineOperatorReducer reducer(&jsgraph); |
117 Reduction reduction = reducer.Reduce(n); | 128 Reduction reduction = reducer.Reduce(n); |
118 CHECK(reduction.Changed()); | 129 CHECK(reduction.Changed()); |
119 CHECK_NE(n, reduction.replacement()); | 130 CHECK_NE(n, reduction.replacement()); |
120 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); | 131 // Deal with NaNs. |
| 132 if (expect == expect) { |
| 133 // We do not expect a NaN, check for equality. |
| 134 CHECK_EQ(expect, ValueOf<T>(reduction.replacement()->op())); |
| 135 } else { |
| 136 // Check for NaN. |
| 137 T result = ValueOf<T>(reduction.replacement()->op()); |
| 138 CHECK_NE(result, result); |
| 139 } |
121 } | 140 } |
122 | 141 |
123 // Check that the reduction of this binop applied to {a} and {b} yields | 142 // Check that the reduction of this binop applied to {a} and {b} yields |
124 // the {expect} node. | 143 // the {expect} node. |
125 void CheckBinop(Node* expect, Node* a, Node* b) { | 144 void CheckBinop(Node* expect, Node* a, Node* b) { |
126 CHECK(binop); | 145 CHECK(binop); |
127 Node* n = CreateBinopNode(a, b); | 146 Node* n = CreateBinopNode(a, b); |
128 MachineOperatorReducer reducer(&jsgraph); | 147 MachineOperatorReducer reducer(&jsgraph); |
129 Reduction reduction = reducer.Reduce(n); | 148 Reduction reduction = reducer.Reduce(n); |
130 CHECK(reduction.Changed()); | 149 CHECK(reduction.Changed()); |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 Node* store = | 833 Node* store = |
815 R.graph.NewNode(R.machine.Store(StoreRepresentation( | 834 R.graph.NewNode(R.machine.Store(StoreRepresentation( |
816 MachineRepresentation::kWord32, kNoWriteBarrier)), | 835 MachineRepresentation::kWord32, kNoWriteBarrier)), |
817 base, index, load, load, R.graph.start()); | 836 base, index, load, load, R.graph.start()); |
818 MachineOperatorReducer reducer(&R.jsgraph); | 837 MachineOperatorReducer reducer(&R.jsgraph); |
819 Reduction reduction = reducer.Reduce(store); | 838 Reduction reduction = reducer.Reduce(store); |
820 CHECK(!reduction.Changed()); // stores should not be reduced. | 839 CHECK(!reduction.Changed()); // stores should not be reduced. |
821 } | 840 } |
822 } | 841 } |
823 | 842 |
| 843 TEST(ReduceFloat32Sub) { |
| 844 ReducerTester R; |
| 845 R.binop = R.machine.Float32Sub(); |
| 846 |
| 847 FOR_FLOAT32_INPUTS(pl) { |
| 848 FOR_FLOAT32_INPUTS(pr) { |
| 849 float x = *pl, y = *pr; |
| 850 R.CheckFoldBinop<float>(x - y, x, y); |
| 851 } |
| 852 } |
| 853 |
| 854 Node* x = R.Parameter(); |
| 855 Node* zero = R.Constant<float>(0.0); |
| 856 Node* nan = R.Constant<float>(std::numeric_limits<float>::quiet_NaN()); |
| 857 |
| 858 R.CheckBinop(x, x, zero); // x - 0 => x |
| 859 R.CheckBinop(nan, nan, x); // nan - x => nan |
| 860 R.CheckBinop(nan, x, nan); // x - nan => nan |
| 861 } |
| 862 |
| 863 TEST(ReduceFloat64Sub) { |
| 864 ReducerTester R; |
| 865 R.binop = R.machine.Float64Sub(); |
| 866 |
| 867 FOR_FLOAT64_INPUTS(pl) { |
| 868 FOR_FLOAT64_INPUTS(pr) { |
| 869 double x = *pl, y = *pr; |
| 870 R.CheckFoldBinop<double>(x - y, x, y); |
| 871 } |
| 872 } |
| 873 |
| 874 Node* x = R.Parameter(); |
| 875 Node* zero = R.Constant<double>(0.0); |
| 876 Node* nan = R.Constant<double>(std::numeric_limits<double>::quiet_NaN()); |
| 877 |
| 878 R.CheckBinop(x, x, zero); // x - 0 => x |
| 879 R.CheckBinop(nan, nan, x); // nan - x => nan |
| 880 R.CheckBinop(nan, x, nan); // x - nan => nan |
| 881 } |
824 | 882 |
825 // TODO(titzer): test MachineOperatorReducer for Word64And | 883 // TODO(titzer): test MachineOperatorReducer for Word64And |
826 // TODO(titzer): test MachineOperatorReducer for Word64Or | 884 // TODO(titzer): test MachineOperatorReducer for Word64Or |
827 // TODO(titzer): test MachineOperatorReducer for Word64Xor | 885 // TODO(titzer): test MachineOperatorReducer for Word64Xor |
828 // TODO(titzer): test MachineOperatorReducer for Word64Equal | 886 // TODO(titzer): test MachineOperatorReducer for Word64Equal |
829 // TODO(titzer): test MachineOperatorReducer for Word64Not | 887 // TODO(titzer): test MachineOperatorReducer for Word64Not |
830 // TODO(titzer): test MachineOperatorReducer for Int64Mul | 888 // TODO(titzer): test MachineOperatorReducer for Int64Mul |
831 // TODO(titzer): test MachineOperatorReducer for Int64UMul | 889 // TODO(titzer): test MachineOperatorReducer for Int64UMul |
832 // TODO(titzer): test MachineOperatorReducer for Int64Div | 890 // TODO(titzer): test MachineOperatorReducer for Int64Div |
833 // TODO(titzer): test MachineOperatorReducer for Uint64Div | 891 // TODO(titzer): test MachineOperatorReducer for Uint64Div |
834 // TODO(titzer): test MachineOperatorReducer for Int64Mod | 892 // TODO(titzer): test MachineOperatorReducer for Int64Mod |
835 // TODO(titzer): test MachineOperatorReducer for Uint64Mod | 893 // TODO(titzer): test MachineOperatorReducer for Uint64Mod |
836 // TODO(titzer): test MachineOperatorReducer for Int64Neg | 894 // TODO(titzer): test MachineOperatorReducer for Int64Neg |
837 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 | 895 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64 |
838 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 | 896 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32 |
839 // TODO(titzer): test MachineOperatorReducer for Float64Compare | 897 // TODO(titzer): test MachineOperatorReducer for Float64Compare |
840 // TODO(titzer): test MachineOperatorReducer for Float64Add | 898 // TODO(titzer): test MachineOperatorReducer for Float64Add |
841 // TODO(titzer): test MachineOperatorReducer for Float64Sub | 899 // TODO(titzer): test MachineOperatorReducer for Float64Sub |
842 // TODO(titzer): test MachineOperatorReducer for Float64Mul | 900 // TODO(titzer): test MachineOperatorReducer for Float64Mul |
843 // TODO(titzer): test MachineOperatorReducer for Float64Div | 901 // TODO(titzer): test MachineOperatorReducer for Float64Div |
844 // TODO(titzer): test MachineOperatorReducer for Float64Mod | 902 // TODO(titzer): test MachineOperatorReducer for Float64Mod |
845 | 903 |
846 } // namespace compiler | 904 } // namespace compiler |
847 } // namespace internal | 905 } // namespace internal |
848 } // namespace v8 | 906 } // namespace v8 |
OLD | NEW |