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/compiler/machine-operator-reducer.h" | 5 #include "src/compiler/machine-operator-reducer.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/compiler/diamond.h" | 10 #include "src/compiler/diamond.h" |
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 Uint32Matcher mrhs(node->InputAt(1)); | 1001 Uint32Matcher mrhs(node->InputAt(1)); |
1002 if (mlhs.HasValue() && mrhs.HasValue()) { | 1002 if (mlhs.HasValue() && mrhs.HasValue()) { |
1003 return ReplaceFloat64(bit_cast<double>( | 1003 return ReplaceFloat64(bit_cast<double>( |
1004 (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF)) | | 1004 (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF)) | |
1005 (static_cast<uint64_t>(mrhs.Value()) << 32))); | 1005 (static_cast<uint64_t>(mrhs.Value()) << 32))); |
1006 } | 1006 } |
1007 return NoChange(); | 1007 return NoChange(); |
1008 } | 1008 } |
1009 | 1009 |
1010 | 1010 |
| 1011 namespace { |
| 1012 |
| 1013 bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) { |
| 1014 if (m.HasValue()) { |
| 1015 double v = m.Value(); |
| 1016 float fv = static_cast<float>(v); |
| 1017 return static_cast<double>(fv) == v; |
| 1018 } |
| 1019 return false; |
| 1020 } |
| 1021 |
| 1022 } // namespace |
| 1023 |
| 1024 |
1011 Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) { | 1025 Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) { |
1012 DCHECK((IrOpcode::kFloat64Equal == node->opcode()) || | 1026 DCHECK((IrOpcode::kFloat64Equal == node->opcode()) || |
1013 (IrOpcode::kFloat64LessThan == node->opcode()) || | 1027 (IrOpcode::kFloat64LessThan == node->opcode()) || |
1014 (IrOpcode::kFloat64LessThanOrEqual == node->opcode())); | 1028 (IrOpcode::kFloat64LessThanOrEqual == node->opcode())); |
1015 // As all Float32 values have an exact representation in Float64, comparing | 1029 // As all Float32 values have an exact representation in Float64, comparing |
1016 // two Float64 values both converted from Float32 is equivalent to comparing | 1030 // two Float64 values both converted from Float32 is equivalent to comparing |
1017 // the original Float32s, so we can ignore the conversions. | 1031 // the original Float32s, so we can ignore the conversions. We can also reduce |
| 1032 // comparisons of converted Float64 values against constants that can be |
| 1033 // represented exactly as Float32. |
1018 Float64BinopMatcher m(node); | 1034 Float64BinopMatcher m(node); |
1019 if (m.left().IsChangeFloat32ToFloat64() && | 1035 if ((m.left().IsChangeFloat32ToFloat64() && |
1020 m.right().IsChangeFloat32ToFloat64()) { | 1036 m.right().IsChangeFloat32ToFloat64()) || |
| 1037 (m.left().IsChangeFloat32ToFloat64() && |
| 1038 IsFloat64RepresentableAsFloat32(m.right())) || |
| 1039 (IsFloat64RepresentableAsFloat32(m.left()) && |
| 1040 m.right().IsChangeFloat32ToFloat64())) { |
1021 switch (node->opcode()) { | 1041 switch (node->opcode()) { |
1022 case IrOpcode::kFloat64Equal: | 1042 case IrOpcode::kFloat64Equal: |
1023 node->set_op(machine()->Float32Equal()); | 1043 node->set_op(machine()->Float32Equal()); |
1024 break; | 1044 break; |
1025 case IrOpcode::kFloat64LessThan: | 1045 case IrOpcode::kFloat64LessThan: |
1026 node->set_op(machine()->Float32LessThan()); | 1046 node->set_op(machine()->Float32LessThan()); |
1027 break; | 1047 break; |
1028 case IrOpcode::kFloat64LessThanOrEqual: | 1048 case IrOpcode::kFloat64LessThanOrEqual: |
1029 node->set_op(machine()->Float32LessThanOrEqual()); | 1049 node->set_op(machine()->Float32LessThanOrEqual()); |
1030 break; | 1050 break; |
1031 default: | 1051 default: |
1032 return NoChange(); | 1052 return NoChange(); |
1033 } | 1053 } |
1034 node->ReplaceInput(0, m.left().InputAt(0)); | 1054 node->ReplaceInput( |
1035 node->ReplaceInput(1, m.right().InputAt(0)); | 1055 0, m.left().HasValue() |
| 1056 ? Float32Constant(static_cast<float>(m.left().Value())) |
| 1057 : m.left().InputAt(0)); |
| 1058 node->ReplaceInput( |
| 1059 1, m.right().HasValue() |
| 1060 ? Float32Constant(static_cast<float>(m.right().Value())) |
| 1061 : m.right().InputAt(0)); |
1036 return Changed(node); | 1062 return Changed(node); |
1037 } | 1063 } |
1038 return NoChange(); | 1064 return NoChange(); |
1039 } | 1065 } |
1040 | 1066 |
1041 | 1067 |
1042 CommonOperatorBuilder* MachineOperatorReducer::common() const { | 1068 CommonOperatorBuilder* MachineOperatorReducer::common() const { |
1043 return jsgraph()->common(); | 1069 return jsgraph()->common(); |
1044 } | 1070 } |
1045 | 1071 |
1046 | 1072 |
1047 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 1073 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
1048 return jsgraph()->machine(); | 1074 return jsgraph()->machine(); |
1049 } | 1075 } |
1050 | 1076 |
1051 | 1077 |
1052 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 1078 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
1053 | 1079 |
1054 } // namespace compiler | 1080 } // namespace compiler |
1055 } // namespace internal | 1081 } // namespace internal |
1056 } // namespace v8 | 1082 } // namespace v8 |
OLD | NEW |