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 |