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