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