| 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 #include "src/compiler/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
| 6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
| 7 #include "src/compiler/js-typed-lowering.h" | 7 #include "src/compiler/js-typed-lowering.h" |
| 8 #include "src/compiler/node-aux-data-inl.h" | 8 #include "src/compiler/node-aux-data-inl.h" |
| 9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
| 10 #include "src/types.h" | 10 #include "src/types.h" |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 // Recursively try to reduce the input first. | 409 // Recursively try to reduce the input first. |
| 410 Reduction result = ReduceJSToNumberInput(input->InputAt(0)); | 410 Reduction result = ReduceJSToNumberInput(input->InputAt(0)); |
| 411 if (result.Changed()) { | 411 if (result.Changed()) { |
| 412 RelaxEffects(input); | 412 RelaxEffects(input); |
| 413 return result; | 413 return result; |
| 414 } | 414 } |
| 415 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x) | 415 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x) |
| 416 } | 416 } |
| 417 Type* input_type = NodeProperties::GetBounds(input).upper; | 417 Type* input_type = NodeProperties::GetBounds(input).upper; |
| 418 if (input_type->Is(Type::Number())) { | 418 if (input_type->Is(Type::Number())) { |
| 419 // JSToNumber(number) => x | 419 // JSToNumber(x:number) => x |
| 420 return Changed(input); | 420 return Changed(input); |
| 421 } | 421 } |
| 422 if (input_type->Is(Type::Undefined())) { | 422 if (input_type->Is(Type::Undefined())) { |
| 423 // JSToNumber(undefined) => #NaN | 423 // JSToNumber(undefined) => #NaN |
| 424 return ReplaceWith(jsgraph()->NaNConstant()); | 424 return ReplaceWith(jsgraph()->NaNConstant()); |
| 425 } | 425 } |
| 426 if (input_type->Is(Type::Null())) { | 426 if (input_type->Is(Type::Null())) { |
| 427 // JSToNumber(null) => #0 | 427 // JSToNumber(null) => #0 |
| 428 return ReplaceWith(jsgraph()->ZeroConstant()); | 428 return ReplaceWith(jsgraph()->ZeroConstant()); |
| 429 } | 429 } |
| 430 // TODO(turbofan): js-typed-lowering of ToNumber(boolean) | 430 // TODO(turbofan): js-typed-lowering of ToNumber(x:boolean) |
| 431 // TODO(turbofan): js-typed-lowering of ToNumber(string) | 431 // TODO(turbofan): js-typed-lowering of ToNumber(x:string) |
| 432 return NoChange(); | 432 return NoChange(); |
| 433 } | 433 } |
| 434 | 434 |
| 435 | 435 |
| 436 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { | 436 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { |
| 437 if (input->opcode() == IrOpcode::kJSToString) { | 437 if (input->opcode() == IrOpcode::kJSToString) { |
| 438 // Recursively try to reduce the input first. | 438 // Recursively try to reduce the input first. |
| 439 Reduction result = ReduceJSToStringInput(input->InputAt(0)); | 439 Reduction result = ReduceJSToStringInput(input->InputAt(0)); |
| 440 if (result.Changed()) { | 440 if (result.Changed()) { |
| 441 RelaxEffects(input); | 441 RelaxEffects(input); |
| 442 return result; | 442 return result; |
| 443 } | 443 } |
| 444 return Changed(input); // JSToString(JSToString(x)) => JSToString(x) | 444 return Changed(input); // JSToString(JSToString(x)) => JSToString(x) |
| 445 } | 445 } |
| 446 Type* input_type = NodeProperties::GetBounds(input).upper; | 446 Type* input_type = NodeProperties::GetBounds(input).upper; |
| 447 if (input_type->Is(Type::String())) { | 447 if (input_type->Is(Type::String())) { |
| 448 return Changed(input); // JSToString(string) => x | 448 return Changed(input); // JSToString(x:string) => x |
| 449 } | 449 } |
| 450 if (input_type->Is(Type::Undefined())) { | 450 if (input_type->Is(Type::Undefined())) { |
| 451 return ReplaceWith(jsgraph()->HeapConstant( | 451 return ReplaceWith(jsgraph()->HeapConstant( |
| 452 graph()->zone()->isolate()->factory()->undefined_string())); | 452 graph()->zone()->isolate()->factory()->undefined_string())); |
| 453 } | 453 } |
| 454 if (input_type->Is(Type::Null())) { | 454 if (input_type->Is(Type::Null())) { |
| 455 return ReplaceWith(jsgraph()->HeapConstant( | 455 return ReplaceWith(jsgraph()->HeapConstant( |
| 456 graph()->zone()->isolate()->factory()->null_string())); | 456 graph()->zone()->isolate()->factory()->null_string())); |
| 457 } | 457 } |
| 458 // TODO(turbofan): js-typed-lowering of ToString(boolean) | 458 // TODO(turbofan): js-typed-lowering of ToString(x:boolean) |
| 459 // TODO(turbofan): js-typed-lowering of ToString(number) | 459 // TODO(turbofan): js-typed-lowering of ToString(x:number) |
| 460 return NoChange(); | 460 return NoChange(); |
| 461 } | 461 } |
| 462 | 462 |
| 463 | 463 |
| 464 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { | 464 Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) { |
| 465 if (input->opcode() == IrOpcode::kJSToBoolean) { | 465 if (input->opcode() == IrOpcode::kJSToBoolean) { |
| 466 // Recursively try to reduce the input first. | 466 // Recursively try to reduce the input first. |
| 467 Reduction result = ReduceJSToBooleanInput(input->InputAt(0)); | 467 Reduction result = ReduceJSToBooleanInput(input->InputAt(0)); |
| 468 if (result.Changed()) { | 468 if (result.Changed()) { |
| 469 RelaxEffects(input); | 469 RelaxEffects(input); |
| 470 return result; | 470 return result; |
| 471 } | 471 } |
| 472 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) | 472 return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x) |
| 473 } | 473 } |
| 474 Type* input_type = NodeProperties::GetBounds(input).upper; | 474 Type* input_type = NodeProperties::GetBounds(input).upper; |
| 475 if (input_type->Is(Type::Boolean())) { | 475 if (input_type->Is(Type::Boolean())) { |
| 476 return Changed(input); // JSToBoolean(boolean) => x | 476 return Changed(input); // JSToBoolean(x:boolean) => x |
| 477 } | 477 } |
| 478 if (input_type->Is(Type::Undefined())) { | 478 if (input_type->Is(Type::Undefined())) { |
| 479 // JSToBoolean(undefined) => #false | 479 // JSToBoolean(undefined) => #false |
| 480 return ReplaceWith(jsgraph()->FalseConstant()); | 480 return ReplaceWith(jsgraph()->FalseConstant()); |
| 481 } | 481 } |
| 482 if (input_type->Is(Type::Null())) { | 482 if (input_type->Is(Type::Null())) { |
| 483 // JSToBoolean(null) => #false | 483 // JSToBoolean(null) => #false |
| 484 return ReplaceWith(jsgraph()->FalseConstant()); | 484 return ReplaceWith(jsgraph()->FalseConstant()); |
| 485 } | 485 } |
| 486 if (input_type->Is(Type::DetectableReceiver())) { | 486 if (input_type->Is(Type::DetectableReceiver())) { |
| 487 // JSToBoolean(detectable) => #true | 487 // JSToBoolean(x:detectable) => #true |
| 488 return ReplaceWith(jsgraph()->TrueConstant()); | 488 return ReplaceWith(jsgraph()->TrueConstant()); |
| 489 } | 489 } |
| 490 if (input_type->Is(Type::Undetectable())) { | 490 if (input_type->Is(Type::Undetectable())) { |
| 491 // JSToBoolean(undetectable) => #false | 491 // JSToBoolean(x:undetectable) => #false |
| 492 return ReplaceWith(jsgraph()->FalseConstant()); | 492 return ReplaceWith(jsgraph()->FalseConstant()); |
| 493 } | 493 } |
| 494 if (input_type->Is(Type::Number())) { | 494 if (input_type->Is(Type::OrderedNumber())) { |
| 495 // JSToBoolean(number) => BooleanNot(NumberEqual(x, #0)) | 495 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0)) |
| 496 Node* cmp = graph()->NewNode(simplified()->NumberEqual(), input, | 496 Node* cmp = graph()->NewNode(simplified()->NumberEqual(), input, |
| 497 jsgraph()->ZeroConstant()); | 497 jsgraph()->ZeroConstant()); |
| 498 Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp); | 498 Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp); |
| 499 return ReplaceWith(inv); | 499 return ReplaceWith(inv); |
| 500 } | 500 } |
| 501 // TODO(turbofan): js-typed-lowering of ToBoolean(string) | 501 // TODO(turbofan): js-typed-lowering of ToBoolean(string) |
| 502 return NoChange(); | 502 return NoChange(); |
| 503 } | 503 } |
| 504 | 504 |
| 505 | 505 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 case IrOpcode::kJSMultiply: | 622 case IrOpcode::kJSMultiply: |
| 623 return ReduceNumberBinop(node, simplified()->NumberMultiply()); | 623 return ReduceNumberBinop(node, simplified()->NumberMultiply()); |
| 624 case IrOpcode::kJSDivide: | 624 case IrOpcode::kJSDivide: |
| 625 return ReduceNumberBinop(node, simplified()->NumberDivide()); | 625 return ReduceNumberBinop(node, simplified()->NumberDivide()); |
| 626 case IrOpcode::kJSModulus: | 626 case IrOpcode::kJSModulus: |
| 627 return ReduceNumberBinop(node, simplified()->NumberModulus()); | 627 return ReduceNumberBinop(node, simplified()->NumberModulus()); |
| 628 case IrOpcode::kJSUnaryNot: { | 628 case IrOpcode::kJSUnaryNot: { |
| 629 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); | 629 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); |
| 630 Node* value; | 630 Node* value; |
| 631 if (result.Changed()) { | 631 if (result.Changed()) { |
| 632 // JSUnaryNot(x) => BooleanNot(x) | 632 // JSUnaryNot(x:boolean) => BooleanNot(x) |
| 633 value = | 633 value = |
| 634 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); | 634 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); |
| 635 NodeProperties::ReplaceWithValue(node, value); | 635 NodeProperties::ReplaceWithValue(node, value); |
| 636 return Changed(value); | 636 return Changed(value); |
| 637 } else { | 637 } else { |
| 638 // JSUnaryNot(x) => BooleanNot(JSToBoolean(x)) | 638 // JSUnaryNot(x) => BooleanNot(JSToBoolean(x)) |
| 639 value = graph()->NewNode(simplified()->BooleanNot(), node); | 639 value = graph()->NewNode(simplified()->BooleanNot(), node); |
| 640 node->set_op(javascript()->ToBoolean()); | 640 node->set_op(javascript()->ToBoolean()); |
| 641 NodeProperties::ReplaceWithValue(node, value, node); | 641 NodeProperties::ReplaceWithValue(node, value, node); |
| 642 // Note: ReplaceUses() smashes all uses, so smash it back here. | 642 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 659 return ReduceJSStoreProperty(node); | 659 return ReduceJSStoreProperty(node); |
| 660 default: | 660 default: |
| 661 break; | 661 break; |
| 662 } | 662 } |
| 663 return NoChange(); | 663 return NoChange(); |
| 664 } | 664 } |
| 665 | 665 |
| 666 } // namespace compiler | 666 } // namespace compiler |
| 667 } // namespace internal | 667 } // namespace internal |
| 668 } // namespace v8 | 668 } // namespace v8 |
| OLD | NEW |