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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 return GetFloat32RepresentationFor(node, output_rep, output_type, | 135 return GetFloat32RepresentationFor(node, output_rep, output_type, |
136 truncation); | 136 truncation); |
137 case MachineRepresentation::kFloat64: | 137 case MachineRepresentation::kFloat64: |
138 return GetFloat64RepresentationFor(node, output_rep, output_type, | 138 return GetFloat64RepresentationFor(node, output_rep, output_type, |
139 truncation); | 139 truncation); |
140 case MachineRepresentation::kBit: | 140 case MachineRepresentation::kBit: |
141 return GetBitRepresentationFor(node, output_rep, output_type); | 141 return GetBitRepresentationFor(node, output_rep, output_type); |
142 case MachineRepresentation::kWord8: | 142 case MachineRepresentation::kWord8: |
143 case MachineRepresentation::kWord16: | 143 case MachineRepresentation::kWord16: |
144 case MachineRepresentation::kWord32: | 144 case MachineRepresentation::kWord32: |
145 return GetWord32RepresentationFor(node, output_rep, output_type); | 145 return GetWord32RepresentationFor(node, output_rep, output_type, |
| 146 truncation); |
146 case MachineRepresentation::kWord64: | 147 case MachineRepresentation::kWord64: |
147 return GetWord64RepresentationFor(node, output_rep, output_type); | 148 return GetWord64RepresentationFor(node, output_rep, output_type); |
148 case MachineRepresentation::kSimd128: // Fall through. | 149 case MachineRepresentation::kSimd128: // Fall through. |
149 // TODO(bbudge) Handle conversions between tagged and untagged. | 150 // TODO(bbudge) Handle conversions between tagged and untagged. |
150 break; | 151 break; |
151 case MachineRepresentation::kNone: | 152 case MachineRepresentation::kNone: |
152 return node; | 153 return node; |
153 } | 154 } |
154 UNREACHABLE(); | 155 UNREACHABLE(); |
155 return nullptr; | 156 return nullptr; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 } else { | 228 } else { |
228 int32_t value = OpParameter<int32_t>(node); | 229 int32_t value = OpParameter<int32_t>(node); |
229 return jsgraph()->Float32Constant(static_cast<float>(value)); | 230 return jsgraph()->Float32Constant(static_cast<float>(value)); |
230 } | 231 } |
231 case IrOpcode::kFloat32Constant: | 232 case IrOpcode::kFloat32Constant: |
232 return node; // No change necessary. | 233 return node; // No change necessary. |
233 default: | 234 default: |
234 break; | 235 break; |
235 } | 236 } |
236 // Select the correct X -> Float32 operator. | 237 // Select the correct X -> Float32 operator. |
237 const Operator* op; | 238 const Operator* op = nullptr; |
238 if (output_rep == MachineRepresentation::kBit) { | 239 if (IsWord(output_rep)) { |
239 return TypeError(node, output_rep, output_type, | |
240 MachineRepresentation::kFloat32); | |
241 } else if (IsWord(output_rep)) { | |
242 if (output_type->Is(Type::Signed32())) { | 240 if (output_type->Is(Type::Signed32())) { |
| 241 // int32 -> float64 -> float32 |
243 op = machine()->ChangeInt32ToFloat64(); | 242 op = machine()->ChangeInt32ToFloat64(); |
244 } else { | 243 node = jsgraph()->graph()->NewNode(op, node); |
245 // Either the output is int32 or the uses only care about the | 244 op = machine()->TruncateFloat64ToFloat32(); |
246 // low 32 bits (so we can pick int32 safely). | 245 } else if (output_type->Is(Type::Unsigned32()) || |
247 DCHECK(output_type->Is(Type::Unsigned32()) || | 246 truncation.TruncatesToWord32()) { |
248 truncation.TruncatesToWord32()); | 247 // Either the output is uint32 or the uses only care about the |
| 248 // low 32 bits (so we can pick uint32 safely). |
| 249 |
| 250 // uint32 -> float64 -> float32 |
249 op = machine()->ChangeUint32ToFloat64(); | 251 op = machine()->ChangeUint32ToFloat64(); |
| 252 node = jsgraph()->graph()->NewNode(op, node); |
| 253 op = machine()->TruncateFloat64ToFloat32(); |
250 } | 254 } |
251 // int32 -> float64 -> float32 | |
252 node = jsgraph()->graph()->NewNode(op, node); | |
253 op = machine()->TruncateFloat64ToFloat32(); | |
254 } else if (output_rep == MachineRepresentation::kTagged) { | 255 } else if (output_rep == MachineRepresentation::kTagged) { |
255 op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 | 256 if (output_type->Is(Type::Number())) { |
256 node = jsgraph()->graph()->NewNode(op, node); | 257 op = simplified() |
257 op = machine()->TruncateFloat64ToFloat32(); | 258 ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32 |
| 259 node = jsgraph()->graph()->NewNode(op, node); |
| 260 op = machine()->TruncateFloat64ToFloat32(); |
| 261 } |
258 } else if (output_rep == MachineRepresentation::kFloat64) { | 262 } else if (output_rep == MachineRepresentation::kFloat64) { |
259 op = machine()->TruncateFloat64ToFloat32(); | 263 op = machine()->TruncateFloat64ToFloat32(); |
260 } else { | 264 } |
| 265 if (op == nullptr) { |
261 return TypeError(node, output_rep, output_type, | 266 return TypeError(node, output_rep, output_type, |
262 MachineRepresentation::kFloat32); | 267 MachineRepresentation::kFloat32); |
263 } | 268 } |
264 return jsgraph()->graph()->NewNode(op, node); | 269 return jsgraph()->graph()->NewNode(op, node); |
265 } | 270 } |
266 | 271 |
267 | 272 |
268 Node* RepresentationChanger::GetFloat64RepresentationFor( | 273 Node* RepresentationChanger::GetFloat64RepresentationFor( |
269 Node* node, MachineRepresentation output_rep, Type* output_type, | 274 Node* node, MachineRepresentation output_rep, Type* output_type, |
270 Truncation truncation) { | 275 Truncation truncation) { |
(...skipping 11 matching lines...) Expand all Loading... |
282 return jsgraph()->Float64Constant(static_cast<double>(value)); | 287 return jsgraph()->Float64Constant(static_cast<double>(value)); |
283 } | 288 } |
284 case IrOpcode::kFloat64Constant: | 289 case IrOpcode::kFloat64Constant: |
285 return node; // No change necessary. | 290 return node; // No change necessary. |
286 case IrOpcode::kFloat32Constant: | 291 case IrOpcode::kFloat32Constant: |
287 return jsgraph()->Float64Constant(OpParameter<float>(node)); | 292 return jsgraph()->Float64Constant(OpParameter<float>(node)); |
288 default: | 293 default: |
289 break; | 294 break; |
290 } | 295 } |
291 // Select the correct X -> Float64 operator. | 296 // Select the correct X -> Float64 operator. |
292 const Operator* op; | 297 const Operator* op = nullptr; |
293 if (output_rep == MachineRepresentation::kBit) { | 298 if (IsWord(output_rep)) { |
294 return TypeError(node, output_rep, output_type, | |
295 MachineRepresentation::kFloat64); | |
296 } else if (IsWord(output_rep)) { | |
297 if (output_type->Is(Type::Signed32())) { | 299 if (output_type->Is(Type::Signed32())) { |
298 op = machine()->ChangeInt32ToFloat64(); | 300 op = machine()->ChangeInt32ToFloat64(); |
299 } else { | 301 } else if (output_type->Is(Type::Unsigned32()) || |
300 // Either the output is int32 or the uses only care about the | 302 truncation.TruncatesToWord32()) { |
301 // low 32 bits (so we can pick int32 safely). | 303 // Either the output is uint32 or the uses only care about the |
302 DCHECK(output_type->Is(Type::Unsigned32()) || | 304 // low 32 bits (so we can pick uint32 safely). |
303 truncation.TruncatesToWord32()); | |
304 op = machine()->ChangeUint32ToFloat64(); | 305 op = machine()->ChangeUint32ToFloat64(); |
305 } | 306 } |
306 } else if (output_rep == MachineRepresentation::kTagged) { | 307 } else if (output_rep == MachineRepresentation::kTagged) { |
307 op = simplified()->ChangeTaggedToFloat64(); | 308 if (output_type->Is(Type::Number())) { |
| 309 op = simplified()->ChangeTaggedToFloat64(); |
| 310 } |
308 } else if (output_rep == MachineRepresentation::kFloat32) { | 311 } else if (output_rep == MachineRepresentation::kFloat32) { |
309 op = machine()->ChangeFloat32ToFloat64(); | 312 op = machine()->ChangeFloat32ToFloat64(); |
310 } else { | 313 } |
| 314 if (op == nullptr) { |
311 return TypeError(node, output_rep, output_type, | 315 return TypeError(node, output_rep, output_type, |
312 MachineRepresentation::kFloat64); | 316 MachineRepresentation::kFloat64); |
313 } | 317 } |
314 return jsgraph()->graph()->NewNode(op, node); | 318 return jsgraph()->graph()->NewNode(op, node); |
315 } | 319 } |
316 | 320 |
317 | 321 |
318 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { | 322 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { |
319 return jsgraph()->Int32Constant(DoubleToInt32(value)); | 323 return jsgraph()->Int32Constant(DoubleToInt32(value)); |
320 } | 324 } |
321 | 325 |
322 | |
323 Node* RepresentationChanger::GetWord32RepresentationFor( | 326 Node* RepresentationChanger::GetWord32RepresentationFor( |
324 Node* node, MachineRepresentation output_rep, Type* output_type) { | 327 Node* node, MachineRepresentation output_rep, Type* output_type, |
| 328 Truncation truncation) { |
325 // Eagerly fold representation changes for constants. | 329 // Eagerly fold representation changes for constants. |
326 switch (node->opcode()) { | 330 switch (node->opcode()) { |
327 case IrOpcode::kInt32Constant: | 331 case IrOpcode::kInt32Constant: |
328 return node; // No change necessary. | 332 return node; // No change necessary. |
329 case IrOpcode::kFloat32Constant: | 333 case IrOpcode::kFloat32Constant: |
330 return MakeTruncatedInt32Constant(OpParameter<float>(node)); | 334 return MakeTruncatedInt32Constant(OpParameter<float>(node)); |
331 case IrOpcode::kNumberConstant: | 335 case IrOpcode::kNumberConstant: |
332 case IrOpcode::kFloat64Constant: | 336 case IrOpcode::kFloat64Constant: |
333 return MakeTruncatedInt32Constant(OpParameter<double>(node)); | 337 return MakeTruncatedInt32Constant(OpParameter<double>(node)); |
334 default: | 338 default: |
335 break; | 339 break; |
336 } | 340 } |
337 // Select the correct X -> Word32 operator. | 341 // Select the correct X -> Word32 operator. |
338 const Operator* op; | 342 const Operator* op = nullptr; |
339 Type* type = NodeProperties::GetType(node); | |
340 | |
341 if (output_rep == MachineRepresentation::kBit) { | 343 if (output_rep == MachineRepresentation::kBit) { |
342 return node; // Sloppy comparison -> word32 | 344 return node; // Sloppy comparison -> word32 |
343 } else if (output_rep == MachineRepresentation::kFloat64) { | 345 } else if (output_rep == MachineRepresentation::kFloat64) { |
344 // TODO(jarin) Use only output_type here, once we intersect it with the | 346 if (output_type->Is(Type::Unsigned32())) { |
345 // type inferred by the typer. | |
346 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) { | |
347 op = machine()->ChangeFloat64ToUint32(); | 347 op = machine()->ChangeFloat64ToUint32(); |
348 } else if (output_type->Is(Type::Signed32()) || | 348 } else if (output_type->Is(Type::Signed32())) { |
349 type->Is(Type::Signed32())) { | |
350 op = machine()->ChangeFloat64ToInt32(); | 349 op = machine()->ChangeFloat64ToInt32(); |
351 } else { | 350 } else if (truncation.TruncatesToWord32()) { |
352 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 351 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
353 } | 352 } |
354 } else if (output_rep == MachineRepresentation::kFloat32) { | 353 } else if (output_rep == MachineRepresentation::kFloat32) { |
355 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 | 354 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 |
356 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) { | 355 if (output_type->Is(Type::Unsigned32())) { |
357 op = machine()->ChangeFloat64ToUint32(); | 356 op = machine()->ChangeFloat64ToUint32(); |
358 } else if (output_type->Is(Type::Signed32()) || | 357 } else if (output_type->Is(Type::Signed32())) { |
359 type->Is(Type::Signed32())) { | |
360 op = machine()->ChangeFloat64ToInt32(); | 358 op = machine()->ChangeFloat64ToInt32(); |
361 } else { | 359 } else if (truncation.TruncatesToWord32()) { |
362 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 360 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
363 } | 361 } |
364 } else if (output_rep == MachineRepresentation::kTagged) { | 362 } else if (output_rep == MachineRepresentation::kTagged) { |
365 if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) { | 363 if (output_type->Is(Type::Unsigned32())) { |
366 op = simplified()->ChangeTaggedToUint32(); | 364 op = simplified()->ChangeTaggedToUint32(); |
367 } else if (output_type->Is(Type::Signed32()) || | 365 } else if (output_type->Is(Type::Signed32())) { |
368 type->Is(Type::Signed32())) { | |
369 op = simplified()->ChangeTaggedToInt32(); | 366 op = simplified()->ChangeTaggedToInt32(); |
370 } else { | 367 } else if (truncation.TruncatesToWord32()) { |
371 node = InsertChangeTaggedToFloat64(node); | 368 node = InsertChangeTaggedToFloat64(node); |
372 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); | 369 op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript); |
373 } | 370 } |
374 } else { | 371 } |
| 372 if (op == nullptr) { |
375 return TypeError(node, output_rep, output_type, | 373 return TypeError(node, output_rep, output_type, |
376 MachineRepresentation::kWord32); | 374 MachineRepresentation::kWord32); |
377 } | 375 } |
378 return jsgraph()->graph()->NewNode(op, node); | 376 return jsgraph()->graph()->NewNode(op, node); |
379 } | 377 } |
380 | 378 |
381 | 379 |
382 Node* RepresentationChanger::GetBitRepresentationFor( | 380 Node* RepresentationChanger::GetBitRepresentationFor( |
383 Node* node, MachineRepresentation output_rep, Type* output_type) { | 381 Node* node, MachineRepresentation output_rep, Type* output_type) { |
384 // Eagerly fold representation changes for constants. | 382 // Eagerly fold representation changes for constants. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 | 528 |
531 | 529 |
532 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { | 530 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { |
533 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), | 531 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), |
534 node); | 532 node); |
535 } | 533 } |
536 | 534 |
537 } // namespace compiler | 535 } // namespace compiler |
538 } // namespace internal | 536 } // namespace internal |
539 } // namespace v8 | 537 } // namespace v8 |
OLD | NEW |