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 |