OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/representation-change.h" | 5 #include "src/compiler/representation-change.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 return rep2 == TruncationKind::kAny; | 91 return rep2 == TruncationKind::kAny; |
92 } | 92 } |
93 UNREACHABLE(); | 93 UNREACHABLE(); |
94 return false; | 94 return false; |
95 } | 95 } |
96 | 96 |
97 | 97 |
98 namespace { | 98 namespace { |
99 | 99 |
100 // TODO(titzer): should Word64 also be implicitly convertable to others? | 100 // TODO(titzer): should Word64 also be implicitly convertable to others? |
101 bool IsWord(MachineTypeUnion type) { | 101 bool IsWord(MachineRepresentation rep) { |
102 return (type & (kRepWord8 | kRepWord16 | kRepWord32)) != 0; | 102 return rep == MachineRepresentation::kWord8 || |
| 103 rep == MachineRepresentation::kWord16 || |
| 104 rep == MachineRepresentation::kWord32; |
103 } | 105 } |
104 | 106 |
105 } // namespace | 107 } // namespace |
106 | 108 |
107 | 109 |
108 // Changes representation from {output_type} to {use_rep}. The {truncation} | 110 // Changes representation from {output_type} to {use_rep}. The {truncation} |
109 // parameter is only used for sanity checking - if the changer cannot figure | 111 // parameter is only used for sanity checking - if the changer cannot figure |
110 // out signedness for the word32->float64 conversion, then we check that the | 112 // out signedness for the word32->float64 conversion, then we check that the |
111 // uses truncate to word32 (so they do not care about signedness). | 113 // uses truncate to word32 (so they do not care about signedness). |
112 Node* RepresentationChanger::GetRepresentationFor(Node* node, | 114 Node* RepresentationChanger::GetRepresentationFor(Node* node, |
113 MachineTypeUnion output_type, | 115 MachineType output_type, |
114 MachineTypeUnion use_rep, | 116 MachineRepresentation use_rep, |
115 Truncation truncation) { | 117 Truncation truncation) { |
116 DCHECK((use_rep & kRepMask) == use_rep); | 118 if (output_type.representation() == MachineRepresentation::kNone) { |
117 if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) { | 119 // The output representation should be set. |
118 // There should be only one output representation. | |
119 return TypeError(node, output_type, use_rep); | 120 return TypeError(node, output_type, use_rep); |
120 } | 121 } |
121 if (use_rep == (output_type & kRepMask)) { | 122 if (use_rep == output_type.representation()) { |
122 // Representations are the same. That's a no-op. | 123 // Representations are the same. That's a no-op. |
123 return node; | 124 return node; |
124 } | 125 } |
125 if (IsWord(use_rep) && IsWord(output_type)) { | 126 if (IsWord(use_rep) && IsWord(output_type.representation())) { |
126 // Both are words less than or equal to 32-bits. | 127 // Both are words less than or equal to 32-bits. |
127 // Since loads of integers from memory implicitly sign or zero extend the | 128 // Since loads of integers from memory implicitly sign or zero extend the |
128 // value to the full machine word size and stores implicitly truncate, | 129 // value to the full machine word size and stores implicitly truncate, |
129 // no representation change is necessary. | 130 // no representation change is necessary. |
130 return node; | 131 return node; |
131 } | 132 } |
132 if (use_rep & kRepTagged) { | 133 switch (use_rep) { |
133 return GetTaggedRepresentationFor(node, output_type); | 134 case MachineRepresentation::kTagged: |
134 } else if (use_rep & kRepFloat32) { | 135 return GetTaggedRepresentationFor(node, output_type); |
135 return GetFloat32RepresentationFor(node, output_type, truncation); | 136 case MachineRepresentation::kFloat32: |
136 } else if (use_rep & kRepFloat64) { | 137 return GetFloat32RepresentationFor(node, output_type, truncation); |
137 return GetFloat64RepresentationFor(node, output_type, truncation); | 138 case MachineRepresentation::kFloat64: |
138 } else if (use_rep & kRepBit) { | 139 return GetFloat64RepresentationFor(node, output_type, truncation); |
139 return GetBitRepresentationFor(node, output_type); | 140 case MachineRepresentation::kBit: |
140 } else if (IsWord(use_rep)) { | 141 return GetBitRepresentationFor(node, output_type); |
141 return GetWord32RepresentationFor(node, output_type); | 142 case MachineRepresentation::kWord8: |
142 } else if (use_rep & kRepWord64) { | 143 case MachineRepresentation::kWord16: |
143 return GetWord64RepresentationFor(node, output_type); | 144 case MachineRepresentation::kWord32: |
144 } else { | 145 return GetWord32RepresentationFor(node, output_type); |
145 return node; | 146 case MachineRepresentation::kWord64: |
| 147 return GetWord64RepresentationFor(node, output_type); |
| 148 default: |
| 149 return node; |
146 } | 150 } |
| 151 UNREACHABLE(); |
| 152 return nullptr; |
147 } | 153 } |
148 | 154 |
149 | 155 |
150 Node* RepresentationChanger::GetTaggedRepresentationFor( | 156 Node* RepresentationChanger::GetTaggedRepresentationFor( |
151 Node* node, MachineTypeUnion output_type) { | 157 Node* node, MachineType output_type) { |
152 // Eagerly fold representation changes for constants. | 158 // Eagerly fold representation changes for constants. |
153 switch (node->opcode()) { | 159 switch (node->opcode()) { |
154 case IrOpcode::kNumberConstant: | 160 case IrOpcode::kNumberConstant: |
155 case IrOpcode::kHeapConstant: | 161 case IrOpcode::kHeapConstant: |
156 return node; // No change necessary. | 162 return node; // No change necessary. |
157 case IrOpcode::kInt32Constant: | 163 case IrOpcode::kInt32Constant: |
158 if (output_type & kTypeUint32) { | 164 if (output_type.semantic() == MachineSemantic::kUint32) { |
159 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | 165 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); |
160 return jsgraph()->Constant(static_cast<double>(value)); | 166 return jsgraph()->Constant(static_cast<double>(value)); |
161 } else if (output_type & kTypeInt32) { | 167 } else if (output_type.semantic() == MachineSemantic::kInt32) { |
162 int32_t value = OpParameter<int32_t>(node); | 168 int32_t value = OpParameter<int32_t>(node); |
163 return jsgraph()->Constant(value); | 169 return jsgraph()->Constant(value); |
164 } else if (output_type & kRepBit) { | 170 } else if (output_type.representation() == MachineRepresentation::kBit) { |
165 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() | 171 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() |
166 : jsgraph()->TrueConstant(); | 172 : jsgraph()->TrueConstant(); |
167 } else { | 173 } else { |
168 return TypeError(node, output_type, kRepTagged); | 174 return TypeError(node, output_type, MachineRepresentation::kTagged); |
169 } | 175 } |
170 case IrOpcode::kFloat64Constant: | 176 case IrOpcode::kFloat64Constant: |
171 return jsgraph()->Constant(OpParameter<double>(node)); | 177 return jsgraph()->Constant(OpParameter<double>(node)); |
172 case IrOpcode::kFloat32Constant: | 178 case IrOpcode::kFloat32Constant: |
173 return jsgraph()->Constant(OpParameter<float>(node)); | 179 return jsgraph()->Constant(OpParameter<float>(node)); |
174 default: | 180 default: |
175 break; | 181 break; |
176 } | 182 } |
177 // Select the correct X -> Tagged operator. | 183 // Select the correct X -> Tagged operator. |
178 const Operator* op; | 184 const Operator* op; |
179 if (output_type & kRepBit) { | 185 if (output_type.representation() == MachineRepresentation::kBit) { |
180 op = simplified()->ChangeBitToBool(); | 186 op = simplified()->ChangeBitToBool(); |
181 } else if (IsWord(output_type)) { | 187 } else if (IsWord(output_type.representation())) { |
182 if (output_type & kTypeUint32) { | 188 if (output_type.semantic() == MachineSemantic::kUint32) { |
183 op = simplified()->ChangeUint32ToTagged(); | 189 op = simplified()->ChangeUint32ToTagged(); |
184 } else if (output_type & kTypeInt32) { | 190 } else if (output_type.semantic() == MachineSemantic::kInt32) { |
185 op = simplified()->ChangeInt32ToTagged(); | 191 op = simplified()->ChangeInt32ToTagged(); |
186 } else { | 192 } else { |
187 return TypeError(node, output_type, kRepTagged); | 193 return TypeError(node, output_type, MachineRepresentation::kTagged); |
188 } | 194 } |
189 } else if (output_type & kRepFloat32) { // float32 -> float64 -> tagged | 195 } else if (output_type.representation() == |
| 196 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged |
190 node = InsertChangeFloat32ToFloat64(node); | 197 node = InsertChangeFloat32ToFloat64(node); |
191 op = simplified()->ChangeFloat64ToTagged(); | 198 op = simplified()->ChangeFloat64ToTagged(); |
192 } else if (output_type & kRepFloat64) { | 199 } else if (output_type.representation() == MachineRepresentation::kFloat64) { |
193 op = simplified()->ChangeFloat64ToTagged(); | 200 op = simplified()->ChangeFloat64ToTagged(); |
194 } else { | 201 } else { |
195 return TypeError(node, output_type, kRepTagged); | 202 return TypeError(node, output_type, MachineRepresentation::kTagged); |
196 } | 203 } |
197 return jsgraph()->graph()->NewNode(op, node); | 204 return jsgraph()->graph()->NewNode(op, node); |
198 } | 205 } |
199 | 206 |
200 | 207 |
201 Node* RepresentationChanger::GetFloat32RepresentationFor( | 208 Node* RepresentationChanger::GetFloat32RepresentationFor( |
202 Node* node, MachineTypeUnion output_type, Truncation truncation) { | 209 Node* node, MachineType output_type, Truncation truncation) { |
203 // Eagerly fold representation changes for constants. | 210 // Eagerly fold representation changes for constants. |
204 switch (node->opcode()) { | 211 switch (node->opcode()) { |
205 case IrOpcode::kFloat64Constant: | 212 case IrOpcode::kFloat64Constant: |
206 case IrOpcode::kNumberConstant: | 213 case IrOpcode::kNumberConstant: |
207 return jsgraph()->Float32Constant( | 214 return jsgraph()->Float32Constant( |
208 DoubleToFloat32(OpParameter<double>(node))); | 215 DoubleToFloat32(OpParameter<double>(node))); |
209 case IrOpcode::kInt32Constant: | 216 case IrOpcode::kInt32Constant: |
210 if (output_type & kTypeUint32) { | 217 if (output_type.semantic() == MachineSemantic::kUint32) { |
211 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | 218 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); |
212 return jsgraph()->Float32Constant(static_cast<float>(value)); | 219 return jsgraph()->Float32Constant(static_cast<float>(value)); |
213 } else { | 220 } else { |
214 int32_t value = OpParameter<int32_t>(node); | 221 int32_t value = OpParameter<int32_t>(node); |
215 return jsgraph()->Float32Constant(static_cast<float>(value)); | 222 return jsgraph()->Float32Constant(static_cast<float>(value)); |
216 } | 223 } |
217 case IrOpcode::kFloat32Constant: | 224 case IrOpcode::kFloat32Constant: |
218 return node; // No change necessary. | 225 return node; // No change necessary. |
219 default: | 226 default: |
220 break; | 227 break; |
221 } | 228 } |
222 // Select the correct X -> Float32 operator. | 229 // Select the correct X -> Float32 operator. |
223 const Operator* op; | 230 const Operator* op; |
224 if (output_type & kRepBit) { | 231 if (output_type.representation() == MachineRepresentation::kBit) { |
225 return TypeError(node, output_type, kRepFloat32); | 232 return TypeError(node, output_type, MachineRepresentation::kFloat32); |
226 } else if (IsWord(output_type)) { | 233 } else if (IsWord(output_type.representation())) { |
227 if (output_type & kTypeUint32) { | 234 if (output_type.semantic() == MachineSemantic::kUint32) { |
228 op = machine()->ChangeUint32ToFloat64(); | 235 op = machine()->ChangeUint32ToFloat64(); |
229 } else { | 236 } else { |
230 // Either the output is int32 or the uses only care about the | 237 // Either the output is int32 or the uses only care about the |
231 // low 32 bits (so we can pick int32 safely). | 238 // low 32 bits (so we can pick int32 safely). |
232 DCHECK(output_type & kTypeInt32 || truncation.TruncatesToWord32()); | 239 DCHECK(output_type.semantic() == MachineSemantic::kInt32 || |
| 240 truncation.TruncatesToWord32()); |
233 op = machine()->ChangeInt32ToFloat64(); | 241 op = machine()->ChangeInt32ToFloat64(); |
234 } | 242 } |
235 // int32 -> float64 -> float32 | 243 // int32 -> float64 -> float32 |
236 node = jsgraph()->graph()->NewNode(op, node); | 244 node = jsgraph()->graph()->NewNode(op, node); |
237 op = machine()->TruncateFloat64ToFloat32(); | 245 op = machine()->TruncateFloat64ToFloat32(); |
238 } else if (output_type & kRepTagged) { | 246 } else if (output_type.representation() == MachineRepresentation::kTagged) { |
239 op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 | 247 op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 |
240 node = jsgraph()->graph()->NewNode(op, node); | 248 node = jsgraph()->graph()->NewNode(op, node); |
241 op = machine()->TruncateFloat64ToFloat32(); | 249 op = machine()->TruncateFloat64ToFloat32(); |
242 } else if (output_type & kRepFloat64) { | 250 } else if (output_type.representation() == MachineRepresentation::kFloat64) { |
243 op = machine()->TruncateFloat64ToFloat32(); | 251 op = machine()->TruncateFloat64ToFloat32(); |
244 } else { | 252 } else { |
245 return TypeError(node, output_type, kRepFloat32); | 253 return TypeError(node, output_type, MachineRepresentation::kFloat32); |
246 } | 254 } |
247 return jsgraph()->graph()->NewNode(op, node); | 255 return jsgraph()->graph()->NewNode(op, node); |
248 } | 256 } |
249 | 257 |
250 | 258 |
251 Node* RepresentationChanger::GetFloat64RepresentationFor( | 259 Node* RepresentationChanger::GetFloat64RepresentationFor( |
252 Node* node, MachineTypeUnion output_type, Truncation truncation) { | 260 Node* node, MachineType output_type, Truncation truncation) { |
253 // Eagerly fold representation changes for constants. | 261 // Eagerly fold representation changes for constants. |
254 switch (node->opcode()) { | 262 switch (node->opcode()) { |
255 case IrOpcode::kNumberConstant: | 263 case IrOpcode::kNumberConstant: |
256 return jsgraph()->Float64Constant(OpParameter<double>(node)); | 264 return jsgraph()->Float64Constant(OpParameter<double>(node)); |
257 case IrOpcode::kInt32Constant: | 265 case IrOpcode::kInt32Constant: |
258 if (output_type & kTypeUint32) { | 266 if (output_type.semantic() == MachineSemantic::kUint32) { |
259 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | 267 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); |
260 return jsgraph()->Float64Constant(static_cast<double>(value)); | 268 return jsgraph()->Float64Constant(static_cast<double>(value)); |
261 } else { | 269 } else { |
262 int32_t value = OpParameter<int32_t>(node); | 270 int32_t value = OpParameter<int32_t>(node); |
263 return jsgraph()->Float64Constant(value); | 271 return jsgraph()->Float64Constant(value); |
264 } | 272 } |
265 case IrOpcode::kFloat64Constant: | 273 case IrOpcode::kFloat64Constant: |
266 return node; // No change necessary. | 274 return node; // No change necessary. |
267 case IrOpcode::kFloat32Constant: | 275 case IrOpcode::kFloat32Constant: |
268 return jsgraph()->Float64Constant(OpParameter<float>(node)); | 276 return jsgraph()->Float64Constant(OpParameter<float>(node)); |
269 default: | 277 default: |
270 break; | 278 break; |
271 } | 279 } |
272 // Select the correct X -> Float64 operator. | 280 // Select the correct X -> Float64 operator. |
273 const Operator* op; | 281 const Operator* op; |
274 if (output_type & kRepBit) { | 282 if (output_type.representation() == MachineRepresentation::kBit) { |
275 return TypeError(node, output_type, kRepFloat64); | 283 return TypeError(node, output_type, MachineRepresentation::kFloat64); |
276 } else if (IsWord(output_type)) { | 284 } else if (IsWord(output_type.representation())) { |
277 if (output_type & kTypeUint32) { | 285 if (output_type.semantic() == MachineSemantic::kUint32) { |
278 op = machine()->ChangeUint32ToFloat64(); | 286 op = machine()->ChangeUint32ToFloat64(); |
279 } else { | 287 } else { |
280 // Either the output is int32 or the uses only care about the | 288 // Either the output is int32 or the uses only care about the |
281 // low 32 bits (so we can pick int32 safely). | 289 // low 32 bits (so we can pick int32 safely). |
282 DCHECK(output_type & kTypeInt32 || truncation.TruncatesToWord32()); | 290 DCHECK(output_type.semantic() == MachineSemantic::kInt32 || |
| 291 truncation.TruncatesToWord32()); |
283 op = machine()->ChangeInt32ToFloat64(); | 292 op = machine()->ChangeInt32ToFloat64(); |
284 } | 293 } |
285 } else if (output_type & kRepTagged) { | 294 } else if (output_type.representation() == MachineRepresentation::kTagged) { |
286 op = simplified()->ChangeTaggedToFloat64(); | 295 op = simplified()->ChangeTaggedToFloat64(); |
287 } else if (output_type & kRepFloat32) { | 296 } else if (output_type.representation() == MachineRepresentation::kFloat32) { |
288 op = machine()->ChangeFloat32ToFloat64(); | 297 op = machine()->ChangeFloat32ToFloat64(); |
289 } else { | 298 } else { |
290 return TypeError(node, output_type, kRepFloat64); | 299 return TypeError(node, output_type, MachineRepresentation::kFloat64); |
291 } | 300 } |
292 return jsgraph()->graph()->NewNode(op, node); | 301 return jsgraph()->graph()->NewNode(op, node); |
293 } | 302 } |
294 | 303 |
295 | 304 |
296 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { | 305 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { |
297 return jsgraph()->Int32Constant(DoubleToInt32(value)); | 306 return jsgraph()->Int32Constant(DoubleToInt32(value)); |
298 } | 307 } |
299 | 308 |
300 | 309 |
301 Node* RepresentationChanger::GetWord32RepresentationFor( | 310 Node* RepresentationChanger::GetWord32RepresentationFor( |
302 Node* node, MachineTypeUnion output_type) { | 311 Node* node, MachineType output_type) { |
303 // Eagerly fold representation changes for constants. | 312 // Eagerly fold representation changes for constants. |
304 switch (node->opcode()) { | 313 switch (node->opcode()) { |
305 case IrOpcode::kInt32Constant: | 314 case IrOpcode::kInt32Constant: |
306 return node; // No change necessary. | 315 return node; // No change necessary. |
307 case IrOpcode::kFloat32Constant: | 316 case IrOpcode::kFloat32Constant: |
308 return MakeTruncatedInt32Constant(OpParameter<float>(node)); | 317 return MakeTruncatedInt32Constant(OpParameter<float>(node)); |
309 case IrOpcode::kNumberConstant: | 318 case IrOpcode::kNumberConstant: |
310 case IrOpcode::kFloat64Constant: | 319 case IrOpcode::kFloat64Constant: |
311 return MakeTruncatedInt32Constant(OpParameter<double>(node)); | 320 return MakeTruncatedInt32Constant(OpParameter<double>(node)); |
312 default: | 321 default: |
313 break; | 322 break; |
314 } | 323 } |
315 // Select the correct X -> Word32 operator. | 324 // Select the correct X -> Word32 operator. |
316 const Operator* op; | 325 const Operator* op; |
317 Type* type = NodeProperties::GetType(node); | 326 Type* type = NodeProperties::GetType(node); |
318 | 327 |
319 if (output_type & kRepBit) { | 328 if (output_type.representation() == MachineRepresentation::kBit) { |
320 return node; // Sloppy comparison -> word32 | 329 return node; // Sloppy comparison -> word32 |
321 } else if (output_type & kRepFloat64) { | 330 } else if (output_type.representation() == MachineRepresentation::kFloat64) { |
322 if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) { | 331 if (output_type.semantic() == MachineSemantic::kUint32 || |
| 332 type->Is(Type::Unsigned32())) { |
323 op = machine()->ChangeFloat64ToUint32(); | 333 op = machine()->ChangeFloat64ToUint32(); |
324 } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) { | 334 } else if (output_type.semantic() == MachineSemantic::kInt32 || |
| 335 type->Is(Type::Signed32())) { |
325 op = machine()->ChangeFloat64ToInt32(); | 336 op = machine()->ChangeFloat64ToInt32(); |
326 } else { | 337 } else { |
327 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 338 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
328 } | 339 } |
329 } else if (output_type & kRepFloat32) { | 340 } else if (output_type.representation() == MachineRepresentation::kFloat32) { |
330 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 | 341 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 |
331 if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) { | 342 if (output_type.semantic() == MachineSemantic::kUint32 || |
| 343 type->Is(Type::Unsigned32())) { |
332 op = machine()->ChangeFloat64ToUint32(); | 344 op = machine()->ChangeFloat64ToUint32(); |
333 } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) { | 345 } else if (output_type.semantic() == MachineSemantic::kInt32 || |
| 346 type->Is(Type::Signed32())) { |
334 op = machine()->ChangeFloat64ToInt32(); | 347 op = machine()->ChangeFloat64ToInt32(); |
335 } else { | 348 } else { |
336 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 349 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
337 } | 350 } |
338 } else if (output_type & kRepTagged) { | 351 } else if (output_type.representation() == MachineRepresentation::kTagged) { |
339 if (output_type & kTypeUint32 || type->Is(Type::Unsigned32())) { | 352 if (output_type.semantic() == MachineSemantic::kUint32 || |
| 353 type->Is(Type::Unsigned32())) { |
340 op = simplified()->ChangeTaggedToUint32(); | 354 op = simplified()->ChangeTaggedToUint32(); |
341 } else if (output_type & kTypeInt32 || type->Is(Type::Signed32())) { | 355 } else if (output_type.semantic() == MachineSemantic::kInt32 || |
| 356 type->Is(Type::Signed32())) { |
342 op = simplified()->ChangeTaggedToInt32(); | 357 op = simplified()->ChangeTaggedToInt32(); |
343 } else { | 358 } else { |
344 node = InsertChangeTaggedToFloat64(node); | 359 node = InsertChangeTaggedToFloat64(node); |
345 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 360 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
346 } | 361 } |
347 } else { | 362 } else { |
348 return TypeError(node, output_type, kRepWord32); | 363 return TypeError(node, output_type, MachineRepresentation::kWord32); |
349 } | 364 } |
350 return jsgraph()->graph()->NewNode(op, node); | 365 return jsgraph()->graph()->NewNode(op, node); |
351 } | 366 } |
352 | 367 |
353 | 368 |
354 Node* RepresentationChanger::GetBitRepresentationFor( | 369 Node* RepresentationChanger::GetBitRepresentationFor(Node* node, |
355 Node* node, MachineTypeUnion output_type) { | 370 MachineType output_type) { |
356 // Eagerly fold representation changes for constants. | 371 // Eagerly fold representation changes for constants. |
357 switch (node->opcode()) { | 372 switch (node->opcode()) { |
358 case IrOpcode::kHeapConstant: { | 373 case IrOpcode::kHeapConstant: { |
359 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node); | 374 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node); |
360 DCHECK(value.is_identical_to(factory()->true_value()) || | 375 DCHECK(value.is_identical_to(factory()->true_value()) || |
361 value.is_identical_to(factory()->false_value())); | 376 value.is_identical_to(factory()->false_value())); |
362 return jsgraph()->Int32Constant( | 377 return jsgraph()->Int32Constant( |
363 value.is_identical_to(factory()->true_value()) ? 1 : 0); | 378 value.is_identical_to(factory()->true_value()) ? 1 : 0); |
364 } | 379 } |
365 default: | 380 default: |
366 break; | 381 break; |
367 } | 382 } |
368 // Select the correct X -> Bit operator. | 383 // Select the correct X -> Bit operator. |
369 const Operator* op; | 384 const Operator* op; |
370 if (output_type & kRepTagged) { | 385 if (output_type.representation() == MachineRepresentation::kTagged) { |
371 op = simplified()->ChangeBoolToBit(); | 386 op = simplified()->ChangeBoolToBit(); |
372 } else { | 387 } else { |
373 return TypeError(node, output_type, kRepBit); | 388 return TypeError(node, output_type, MachineRepresentation::kBit); |
374 } | 389 } |
375 return jsgraph()->graph()->NewNode(op, node); | 390 return jsgraph()->graph()->NewNode(op, node); |
376 } | 391 } |
377 | 392 |
378 | 393 |
379 Node* RepresentationChanger::GetWord64RepresentationFor( | 394 Node* RepresentationChanger::GetWord64RepresentationFor( |
380 Node* node, MachineTypeUnion output_type) { | 395 Node* node, MachineType output_type) { |
381 if (output_type & kRepBit) { | 396 if (output_type.representation() == MachineRepresentation::kBit) { |
382 return node; // Sloppy comparison -> word64 | 397 return node; // Sloppy comparison -> word64 |
383 } | 398 } |
384 // Can't really convert Word64 to anything else. Purported to be internal. | 399 // Can't really convert Word64 to anything else. Purported to be internal. |
385 return TypeError(node, output_type, kRepWord64); | 400 return TypeError(node, output_type, MachineRepresentation::kWord64); |
386 } | 401 } |
387 | 402 |
388 | 403 |
389 const Operator* RepresentationChanger::Int32OperatorFor( | 404 const Operator* RepresentationChanger::Int32OperatorFor( |
390 IrOpcode::Value opcode) { | 405 IrOpcode::Value opcode) { |
391 switch (opcode) { | 406 switch (opcode) { |
392 case IrOpcode::kNumberAdd: | 407 case IrOpcode::kNumberAdd: |
393 return machine()->Int32Add(); | 408 return machine()->Int32Add(); |
394 case IrOpcode::kNumberSubtract: | 409 case IrOpcode::kNumberSubtract: |
395 return machine()->Int32Sub(); | 410 return machine()->Int32Sub(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 return machine()->Float64LessThan(); | 478 return machine()->Float64LessThan(); |
464 case IrOpcode::kNumberLessThanOrEqual: | 479 case IrOpcode::kNumberLessThanOrEqual: |
465 return machine()->Float64LessThanOrEqual(); | 480 return machine()->Float64LessThanOrEqual(); |
466 default: | 481 default: |
467 UNREACHABLE(); | 482 UNREACHABLE(); |
468 return NULL; | 483 return NULL; |
469 } | 484 } |
470 } | 485 } |
471 | 486 |
472 | 487 |
473 MachineType RepresentationChanger::TypeFromUpperBound(Type* type) { | 488 MachineSemantic RepresentationChanger::TypeFromUpperBound(Type* type) { |
474 CHECK(!type->Is(Type::None())); | 489 CHECK(!type->Is(Type::None())); |
475 if (type->Is(Type::Signed32())) return kTypeInt32; | 490 if (type->Is(Type::Signed32())) return MachineSemantic::kInt32; |
476 if (type->Is(Type::Unsigned32())) return kTypeUint32; | 491 if (type->Is(Type::Unsigned32())) return MachineSemantic::kUint32; |
477 if (type->Is(Type::Number())) return kTypeNumber; | 492 if (type->Is(Type::Number())) return MachineSemantic::kNumber; |
478 if (type->Is(Type::Boolean())) return kTypeBool; | 493 if (type->Is(Type::Boolean())) return MachineSemantic::kBool; |
479 return kTypeAny; | 494 return MachineSemantic::kAny; |
480 } | 495 } |
481 | 496 |
482 | 497 |
483 Node* RepresentationChanger::TypeError(Node* node, MachineTypeUnion output_type, | 498 Node* RepresentationChanger::TypeError(Node* node, MachineType output_type, |
484 MachineTypeUnion use) { | 499 MachineRepresentation use) { |
485 type_error_ = true; | 500 type_error_ = true; |
486 if (!testing_type_errors_) { | 501 if (!testing_type_errors_) { |
487 std::ostringstream out_str; | 502 std::ostringstream out_str; |
488 out_str << static_cast<MachineType>(output_type); | 503 out_str << output_type; |
489 | 504 |
490 std::ostringstream use_str; | 505 std::ostringstream use_str; |
491 use_str << static_cast<MachineType>(use); | 506 use_str << use; |
492 | 507 |
493 V8_Fatal(__FILE__, __LINE__, | 508 V8_Fatal(__FILE__, __LINE__, |
494 "RepresentationChangerError: node #%d:%s of " | 509 "RepresentationChangerError: node #%d:%s of " |
495 "%s cannot be changed to %s", | 510 "%s cannot be changed to %s", |
496 node->id(), node->op()->mnemonic(), out_str.str().c_str(), | 511 node->id(), node->op()->mnemonic(), out_str.str().c_str(), |
497 use_str.str().c_str()); | 512 use_str.str().c_str()); |
498 } | 513 } |
499 return node; | 514 return node; |
500 } | 515 } |
501 | 516 |
502 | 517 |
503 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { | 518 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { |
504 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); | 519 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); |
505 } | 520 } |
506 | 521 |
507 | 522 |
508 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { | 523 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { |
509 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), | 524 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), |
510 node); | 525 node); |
511 } | 526 } |
512 | 527 |
513 } // namespace compiler | 528 } // namespace compiler |
514 } // namespace internal | 529 } // namespace internal |
515 } // namespace v8 | 530 } // namespace v8 |
OLD | NEW |