| 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 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ | 5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ |
| 6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_ | 6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_ |
| 7 | 7 |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 namespace compiler { | 13 namespace compiler { |
| 14 | 14 |
| 15 enum IdentifyZeros { kIdentifyZeros, kDistinguishZeros }; |
| 16 |
| 15 class Truncation final { | 17 class Truncation final { |
| 16 public: | 18 public: |
| 17 // Constructors. | 19 // Constructors. |
| 18 static Truncation None() { return Truncation(TruncationKind::kNone); } | 20 static Truncation None() { |
| 19 static Truncation Bool() { return Truncation(TruncationKind::kBool); } | 21 return Truncation(TruncationKind::kNone, kIdentifyZeros); |
| 20 static Truncation Word32() { return Truncation(TruncationKind::kWord32); } | 22 } |
| 21 static Truncation Word64() { return Truncation(TruncationKind::kWord64); } | 23 static Truncation Bool() { |
| 22 static Truncation Float64() { return Truncation(TruncationKind::kFloat64); } | 24 return Truncation(TruncationKind::kBool, kIdentifyZeros); |
| 23 static Truncation Any() { return Truncation(TruncationKind::kAny); } | 25 } |
| 26 static Truncation Word32() { |
| 27 return Truncation(TruncationKind::kWord32, kIdentifyZeros); |
| 28 } |
| 29 static Truncation Word64() { |
| 30 return Truncation(TruncationKind::kWord64, kIdentifyZeros); |
| 31 } |
| 32 static Truncation Float64(IdentifyZeros identify_zeros = kDistinguishZeros) { |
| 33 return Truncation(TruncationKind::kFloat64, identify_zeros); |
| 34 } |
| 35 static Truncation Any(IdentifyZeros identify_zeros = kDistinguishZeros) { |
| 36 return Truncation(TruncationKind::kAny, identify_zeros); |
| 37 } |
| 24 | 38 |
| 25 static Truncation Generalize(Truncation t1, Truncation t2) { | 39 static Truncation Generalize(Truncation t1, Truncation t2) { |
| 26 return Truncation(Generalize(t1.kind(), t2.kind())); | 40 return Truncation( |
| 41 Generalize(t1.kind(), t2.kind()), |
| 42 GeneralizeIdentifyZeros(t1.identify_zeros(), t2.identify_zeros())); |
| 27 } | 43 } |
| 28 | 44 |
| 29 // Queries. | 45 // Queries. |
| 30 bool IsUnused() const { return kind_ == TruncationKind::kNone; } | 46 bool IsUnused() const { return kind_ == TruncationKind::kNone; } |
| 31 bool IsUsedAsBool() const { | 47 bool IsUsedAsBool() const { |
| 32 return LessGeneral(kind_, TruncationKind::kBool); | 48 return LessGeneral(kind_, TruncationKind::kBool); |
| 33 } | 49 } |
| 34 bool IsUsedAsWord32() const { | 50 bool IsUsedAsWord32() const { |
| 35 return LessGeneral(kind_, TruncationKind::kWord32); | 51 return LessGeneral(kind_, TruncationKind::kWord32); |
| 36 } | 52 } |
| 37 bool IsUsedAsFloat64() const { | 53 bool IsUsedAsFloat64() const { |
| 38 return LessGeneral(kind_, TruncationKind::kFloat64); | 54 return LessGeneral(kind_, TruncationKind::kFloat64); |
| 39 } | 55 } |
| 40 bool IdentifiesNaNAndZero() { | 56 bool IdentifiesNaNAndZero() { |
| 41 return LessGeneral(kind_, TruncationKind::kWord32) || | 57 return LessGeneral(kind_, TruncationKind::kWord32) || |
| 42 LessGeneral(kind_, TruncationKind::kBool); | 58 LessGeneral(kind_, TruncationKind::kBool); |
| 43 } | 59 } |
| 44 bool IdentifiesUndefinedAndNaNAndZero() { | 60 bool IdentifiesUndefinedAndNaNAndZero() { |
| 45 return LessGeneral(kind_, TruncationKind::kFloat64) || | 61 return LessGeneral(kind_, TruncationKind::kFloat64) || |
| 46 LessGeneral(kind_, TruncationKind::kWord64); | 62 LessGeneral(kind_, TruncationKind::kWord64); |
| 47 } | 63 } |
| 64 bool IdentifiesZeroAndMinusZero() const { |
| 65 return identify_zeros() == kIdentifyZeros; |
| 66 } |
| 48 | 67 |
| 49 // Operators. | 68 // Operators. |
| 50 bool operator==(Truncation other) const { return kind() == other.kind(); } | 69 bool operator==(Truncation other) const { |
| 70 return kind() == other.kind() && identify_zeros() == other.identify_zeros(); |
| 71 } |
| 51 bool operator!=(Truncation other) const { return !(*this == other); } | 72 bool operator!=(Truncation other) const { return !(*this == other); } |
| 52 | 73 |
| 53 // Debug utilities. | 74 // Debug utilities. |
| 54 const char* description() const; | 75 const char* description() const; |
| 55 bool IsLessGeneralThan(Truncation other) { | 76 bool IsLessGeneralThan(Truncation other) { |
| 56 return LessGeneral(kind(), other.kind()); | 77 return LessGeneral(kind(), other.kind()) && |
| 78 LessGeneralIdentifyZeros(identify_zeros(), other.identify_zeros()); |
| 57 } | 79 } |
| 58 | 80 |
| 81 IdentifyZeros identify_zeros() const { return identify_zeros_; } |
| 82 |
| 59 private: | 83 private: |
| 60 enum class TruncationKind : uint8_t { | 84 enum class TruncationKind : uint8_t { |
| 61 kNone, | 85 kNone, |
| 62 kBool, | 86 kBool, |
| 63 kWord32, | 87 kWord32, |
| 64 kWord64, | 88 kWord64, |
| 65 kFloat64, | 89 kFloat64, |
| 66 kAny | 90 kAny |
| 67 }; | 91 }; |
| 68 | 92 |
| 69 explicit Truncation(TruncationKind kind) : kind_(kind) {} | 93 explicit Truncation(TruncationKind kind, IdentifyZeros identify_zeros) |
| 94 : kind_(kind), identify_zeros_(identify_zeros) { |
| 95 DCHECK(kind == TruncationKind::kAny || kind == TruncationKind::kFloat64 || |
| 96 identify_zeros == kIdentifyZeros); |
| 97 } |
| 70 TruncationKind kind() const { return kind_; } | 98 TruncationKind kind() const { return kind_; } |
| 71 | 99 |
| 72 TruncationKind kind_; | 100 TruncationKind kind_; |
| 101 IdentifyZeros identify_zeros_; |
| 73 | 102 |
| 74 static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2); | 103 static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2); |
| 104 static IdentifyZeros GeneralizeIdentifyZeros(IdentifyZeros i1, |
| 105 IdentifyZeros i2); |
| 75 static bool LessGeneral(TruncationKind rep1, TruncationKind rep2); | 106 static bool LessGeneral(TruncationKind rep1, TruncationKind rep2); |
| 107 static bool LessGeneralIdentifyZeros(IdentifyZeros u1, IdentifyZeros u2); |
| 76 }; | 108 }; |
| 77 | 109 |
| 78 enum class TypeCheckKind : uint8_t { | 110 enum class TypeCheckKind : uint8_t { |
| 79 kNone, | 111 kNone, |
| 80 kSignedSmall, | 112 kSignedSmall, |
| 81 kSigned32, | 113 kSigned32, |
| 82 kNumber, | 114 kNumber, |
| 83 kNumberOrOddball, | 115 kNumberOrOddball, |
| 84 kHeapObject | 116 kHeapObject |
| 85 }; | 117 }; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 112 // is the preferred representation. For conversions that will require | 144 // is the preferred representation. For conversions that will require |
| 113 // checks, we also keep track of whether a minus zero check is needed. | 145 // checks, we also keep track of whether a minus zero check is needed. |
| 114 // | 146 // |
| 115 // 2. During lowering, the use info is used to properly convert the input | 147 // 2. During lowering, the use info is used to properly convert the input |
| 116 // to the preferred representation. The preferred representation might be | 148 // to the preferred representation. The preferred representation might be |
| 117 // insufficient to do the conversion (e.g. word32->float64 conv), so we also | 149 // insufficient to do the conversion (e.g. word32->float64 conv), so we also |
| 118 // need the signedness information to produce the correct value. | 150 // need the signedness information to produce the correct value. |
| 119 class UseInfo { | 151 class UseInfo { |
| 120 public: | 152 public: |
| 121 UseInfo(MachineRepresentation representation, Truncation truncation, | 153 UseInfo(MachineRepresentation representation, Truncation truncation, |
| 122 TypeCheckKind type_check = TypeCheckKind::kNone, | 154 TypeCheckKind type_check = TypeCheckKind::kNone) |
| 123 CheckForMinusZeroMode minus_zero_check = | |
| 124 CheckForMinusZeroMode::kCheckForMinusZero) | |
| 125 : representation_(representation), | 155 : representation_(representation), |
| 126 truncation_(truncation), | 156 truncation_(truncation), |
| 127 type_check_(type_check), | 157 type_check_(type_check) {} |
| 128 minus_zero_check_(minus_zero_check) {} | |
| 129 static UseInfo TruncatingWord32() { | 158 static UseInfo TruncatingWord32() { |
| 130 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32()); | 159 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32()); |
| 131 } | 160 } |
| 132 static UseInfo TruncatingWord64() { | 161 static UseInfo TruncatingWord64() { |
| 133 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64()); | 162 return UseInfo(MachineRepresentation::kWord64, Truncation::Word64()); |
| 134 } | 163 } |
| 135 static UseInfo Bool() { | 164 static UseInfo Bool() { |
| 136 return UseInfo(MachineRepresentation::kBit, Truncation::Bool()); | 165 return UseInfo(MachineRepresentation::kBit, Truncation::Bool()); |
| 137 } | 166 } |
| 138 static UseInfo Float32() { | 167 static UseInfo Float32() { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 156 | 185 |
| 157 // Possibly deoptimizing conversions. | 186 // Possibly deoptimizing conversions. |
| 158 static UseInfo CheckedHeapObjectAsTaggedPointer() { | 187 static UseInfo CheckedHeapObjectAsTaggedPointer() { |
| 159 return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(), | 188 return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(), |
| 160 TypeCheckKind::kHeapObject); | 189 TypeCheckKind::kHeapObject); |
| 161 } | 190 } |
| 162 static UseInfo CheckedSignedSmallAsTaggedSigned() { | 191 static UseInfo CheckedSignedSmallAsTaggedSigned() { |
| 163 return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any(), | 192 return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any(), |
| 164 TypeCheckKind::kSignedSmall); | 193 TypeCheckKind::kSignedSmall); |
| 165 } | 194 } |
| 166 static UseInfo CheckedSignedSmallAsWord32( | 195 static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros) { |
| 167 CheckForMinusZeroMode minus_zero_mode = | 196 return UseInfo(MachineRepresentation::kWord32, |
| 168 CheckForMinusZeroMode::kCheckForMinusZero) { | 197 Truncation::Any(identify_zeros), |
| 198 TypeCheckKind::kSignedSmall); |
| 199 } |
| 200 static UseInfo CheckedSigned32AsWord32(IdentifyZeros identify_zeros) { |
| 169 return UseInfo(MachineRepresentation::kWord32, Truncation::Any(), | 201 return UseInfo(MachineRepresentation::kWord32, Truncation::Any(), |
| 170 TypeCheckKind::kSignedSmall, minus_zero_mode); | 202 TypeCheckKind::kSigned32); |
| 171 } | |
| 172 static UseInfo CheckedSigned32AsWord32( | |
| 173 CheckForMinusZeroMode minus_zero_mode = | |
| 174 CheckForMinusZeroMode::kCheckForMinusZero) { | |
| 175 return UseInfo(MachineRepresentation::kWord32, Truncation::Any(), | |
| 176 TypeCheckKind::kSigned32, minus_zero_mode); | |
| 177 } | 203 } |
| 178 static UseInfo CheckedNumberAsFloat64() { | 204 static UseInfo CheckedNumberAsFloat64() { |
| 179 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64(), | 205 return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64(), |
| 180 TypeCheckKind::kNumber); | 206 TypeCheckKind::kNumber); |
| 181 } | 207 } |
| 182 static UseInfo CheckedNumberAsWord32() { | 208 static UseInfo CheckedNumberAsWord32() { |
| 183 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(), | 209 return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(), |
| 184 TypeCheckKind::kNumber); | 210 TypeCheckKind::kNumber); |
| 185 } | 211 } |
| 186 static UseInfo CheckedNumberOrOddballAsFloat64() { | 212 static UseInfo CheckedNumberOrOddballAsFloat64() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 201 } | 227 } |
| 202 | 228 |
| 203 // Value not used. | 229 // Value not used. |
| 204 static UseInfo None() { | 230 static UseInfo None() { |
| 205 return UseInfo(MachineRepresentation::kNone, Truncation::None()); | 231 return UseInfo(MachineRepresentation::kNone, Truncation::None()); |
| 206 } | 232 } |
| 207 | 233 |
| 208 MachineRepresentation representation() const { return representation_; } | 234 MachineRepresentation representation() const { return representation_; } |
| 209 Truncation truncation() const { return truncation_; } | 235 Truncation truncation() const { return truncation_; } |
| 210 TypeCheckKind type_check() const { return type_check_; } | 236 TypeCheckKind type_check() const { return type_check_; } |
| 211 CheckForMinusZeroMode minus_zero_check() const { return minus_zero_check_; } | 237 CheckForMinusZeroMode minus_zero_check() const { |
| 238 return truncation().IdentifiesZeroAndMinusZero() |
| 239 ? CheckForMinusZeroMode::kDontCheckForMinusZero |
| 240 : CheckForMinusZeroMode::kCheckForMinusZero; |
| 241 } |
| 212 | 242 |
| 213 private: | 243 private: |
| 214 MachineRepresentation representation_; | 244 MachineRepresentation representation_; |
| 215 Truncation truncation_; | 245 Truncation truncation_; |
| 216 TypeCheckKind type_check_; | 246 TypeCheckKind type_check_; |
| 217 // TODO(jarin) Integrate with truncations. | |
| 218 CheckForMinusZeroMode minus_zero_check_; | |
| 219 }; | 247 }; |
| 220 | 248 |
| 221 // Contains logic related to changing the representation of values for constants | 249 // Contains logic related to changing the representation of values for constants |
| 222 // and other nodes, as well as lowering Simplified->Machine operators. | 250 // and other nodes, as well as lowering Simplified->Machine operators. |
| 223 // Eagerly folds any representation changes for constants. | 251 // Eagerly folds any representation changes for constants. |
| 224 class RepresentationChanger final { | 252 class RepresentationChanger final { |
| 225 public: | 253 public: |
| 226 RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) | 254 RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) |
| 227 : jsgraph_(jsgraph), | 255 : jsgraph_(jsgraph), |
| 228 isolate_(isolate), | 256 isolate_(isolate), |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 Factory* factory() const { return isolate()->factory(); } | 333 Factory* factory() const { return isolate()->factory(); } |
| 306 SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); } | 334 SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); } |
| 307 MachineOperatorBuilder* machine() { return jsgraph()->machine(); } | 335 MachineOperatorBuilder* machine() { return jsgraph()->machine(); } |
| 308 }; | 336 }; |
| 309 | 337 |
| 310 } // namespace compiler | 338 } // namespace compiler |
| 311 } // namespace internal | 339 } // namespace internal |
| 312 } // namespace v8 | 340 } // namespace v8 |
| 313 | 341 |
| 314 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_ | 342 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_ |
| OLD | NEW |