| 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 |