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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 type_cache_(TypeCache::Get()) { | 426 type_cache_(TypeCache::Get()) { |
427 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | 427 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
428 double min = kMinInt / (1 << k); | 428 double min = kMinInt / (1 << k); |
429 double max = kMaxInt / (1 << k); | 429 double max = kMaxInt / (1 << k); |
430 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 430 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 | 434 |
435 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 435 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
436 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
437 | |
438 JSBinopReduction r(this, node); | 436 JSBinopReduction r(this, node); |
439 | |
440 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 437 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
441 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 438 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
442 r.BothInputsAre(Type::PlainPrimitive()) && | 439 r.BothInputsAre(Type::PlainPrimitive()) && |
443 r.NeitherInputCanBe(Type::StringOrReceiver())) { | 440 r.NeitherInputCanBe(Type::StringOrReceiver())) { |
444 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 441 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
445 r.ConvertInputsToNumber(); | 442 r.ConvertInputsToNumber(); |
446 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 443 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
447 } | 444 } |
448 if (feedback != BinaryOperationHints::kAny) { | 445 if (feedback != BinaryOperationHints::kAny) { |
449 // Lower to the optimistic number binop. | 446 // Lower to the optimistic number binop. |
(...skipping 30 matching lines...) Expand all Loading... |
480 node->InsertInput(graph()->zone(), 0, | 477 node->InsertInput(graph()->zone(), 0, |
481 jsgraph()->HeapConstant(callable.code())); | 478 jsgraph()->HeapConstant(callable.code())); |
482 NodeProperties::ChangeOp(node, common()->Call(desc)); | 479 NodeProperties::ChangeOp(node, common()->Call(desc)); |
483 return Changed(node); | 480 return Changed(node); |
484 } | 481 } |
485 return NoChange(); | 482 return NoChange(); |
486 } | 483 } |
487 | 484 |
488 | 485 |
489 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { | 486 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { |
490 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
491 JSBinopReduction r(this, node); | 487 JSBinopReduction r(this, node); |
492 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 488 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
493 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 489 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
494 r.BothInputsAre(Type::PlainPrimitive())) { | 490 r.BothInputsAre(Type::PlainPrimitive())) { |
495 // JSSubtract(x:plain-primitive, y:plain-primitive) | 491 // JSSubtract(x:plain-primitive, y:plain-primitive) |
496 // => NumberSubtract(ToNumber(x), ToNumber(y)) | 492 // => NumberSubtract(ToNumber(x), ToNumber(y)) |
497 r.ConvertInputsToNumber(); | 493 r.ConvertInputsToNumber(); |
498 return r.ChangeToPureOperator(simplified()->NumberSubtract(), | 494 return r.ChangeToPureOperator(simplified()->NumberSubtract(), |
499 Type::Number()); | 495 Type::Number()); |
500 } | 496 } |
501 if (feedback != BinaryOperationHints::kAny) { | 497 if (feedback != BinaryOperationHints::kAny) { |
502 // Lower to the optimistic number binop. | 498 // Lower to the optimistic number binop. |
503 return r.ChangeToSpeculativeOperator( | 499 return r.ChangeToSpeculativeOperator( |
504 simplified()->SpeculativeNumberSubtract(feedback), Type::Number()); | 500 simplified()->SpeculativeNumberSubtract(feedback), Type::Number()); |
505 } | 501 } |
506 | 502 |
507 // If deoptimization is enabled we rely on type feedback. | 503 // If deoptimization is enabled we rely on type feedback. |
508 if (r.BothInputsAre(Type::PlainPrimitive()) || | 504 if (r.BothInputsAre(Type::PlainPrimitive()) || |
509 !(flags() & kDeoptimizationEnabled)) { | 505 !(flags() & kDeoptimizationEnabled)) { |
510 r.ConvertInputsToNumber(); | 506 r.ConvertInputsToNumber(); |
511 return r.ChangeToPureOperator(simplified()->NumberSubtract(), | 507 return r.ChangeToPureOperator(simplified()->NumberSubtract(), |
512 Type::Number()); | 508 Type::Number()); |
513 } | 509 } |
514 | 510 |
515 return NoChange(); | 511 return NoChange(); |
516 } | 512 } |
517 | 513 |
518 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { | 514 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) { |
519 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
520 JSBinopReduction r(this, node); | 515 JSBinopReduction r(this, node); |
521 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 516 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
522 if (feedback != BinaryOperationHints::kAny) { | 517 if (feedback != BinaryOperationHints::kAny) { |
523 return r.ChangeToSpeculativeOperator( | 518 return r.ChangeToSpeculativeOperator( |
524 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); | 519 simplified()->SpeculativeNumberMultiply(feedback), Type::Number()); |
525 } | 520 } |
526 | 521 |
527 // If deoptimization is enabled we rely on type feedback. | 522 // If deoptimization is enabled we rely on type feedback. |
528 if (r.BothInputsAre(Type::PlainPrimitive()) || | 523 if (r.BothInputsAre(Type::PlainPrimitive()) || |
529 !(flags() & kDeoptimizationEnabled)) { | 524 !(flags() & kDeoptimizationEnabled)) { |
530 r.ConvertInputsToNumber(); | 525 r.ConvertInputsToNumber(); |
531 return r.ChangeToPureOperator(simplified()->NumberMultiply(), | 526 return r.ChangeToPureOperator(simplified()->NumberMultiply(), |
532 Type::Number()); | 527 Type::Number()); |
533 } | 528 } |
534 | 529 |
535 return NoChange(); | 530 return NoChange(); |
536 } | 531 } |
537 | 532 |
538 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { | 533 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { |
539 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
540 JSBinopReduction r(this, node); | 534 JSBinopReduction r(this, node); |
541 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 535 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
542 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 536 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
543 r.BothInputsAre(Type::PlainPrimitive())) { | 537 r.BothInputsAre(Type::PlainPrimitive())) { |
544 // JSDivide(x:plain-primitive, | 538 // JSDivide(x:plain-primitive, |
545 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) | 539 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) |
546 r.ConvertInputsToNumber(); | 540 r.ConvertInputsToNumber(); |
547 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); | 541 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); |
548 } | 542 } |
549 if (feedback != BinaryOperationHints::kAny) { | 543 if (feedback != BinaryOperationHints::kAny) { |
550 return r.ChangeToSpeculativeOperator( | 544 return r.ChangeToSpeculativeOperator( |
551 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); | 545 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); |
552 } | 546 } |
553 if (r.BothInputsAre(Type::PlainPrimitive())) { | 547 if (r.BothInputsAre(Type::PlainPrimitive())) { |
554 // JSDivide(x:plain-primitive, | 548 // JSDivide(x:plain-primitive, |
555 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) | 549 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) |
556 r.ConvertInputsToNumber(); | 550 r.ConvertInputsToNumber(); |
557 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); | 551 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); |
558 } | 552 } |
559 return NoChange(); | 553 return NoChange(); |
560 } | 554 } |
561 | 555 |
562 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { | 556 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { |
563 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
564 JSBinopReduction r(this, node); | 557 JSBinopReduction r(this, node); |
565 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 558 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
566 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 559 if (feedback == BinaryOperationHints::kNumberOrUndefined && |
567 r.BothInputsAre(Type::PlainPrimitive())) { | 560 r.BothInputsAre(Type::PlainPrimitive())) { |
568 // JSModulus(x:plain-primitive, | 561 // JSModulus(x:plain-primitive, |
569 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) | 562 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) |
570 r.ConvertInputsToNumber(); | 563 r.ConvertInputsToNumber(); |
571 return r.ChangeToPureOperator(simplified()->NumberModulus(), | 564 return r.ChangeToPureOperator(simplified()->NumberModulus(), |
572 Type::Number()); | 565 Type::Number()); |
573 } | 566 } |
574 if (feedback != BinaryOperationHints::kAny) { | 567 if (feedback != BinaryOperationHints::kAny) { |
575 return r.ChangeToSpeculativeOperator( | 568 return r.ChangeToSpeculativeOperator( |
576 simplified()->SpeculativeNumberModulus(feedback), Type::Number()); | 569 simplified()->SpeculativeNumberModulus(feedback), Type::Number()); |
577 } | 570 } |
578 if (r.BothInputsAre(Type::PlainPrimitive())) { | 571 if (r.BothInputsAre(Type::PlainPrimitive())) { |
579 // JSModulus(x:plain-primitive, | 572 // JSModulus(x:plain-primitive, |
580 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) | 573 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) |
581 r.ConvertInputsToNumber(); | 574 r.ConvertInputsToNumber(); |
582 return r.ChangeToPureOperator(simplified()->NumberModulus(), | 575 return r.ChangeToPureOperator(simplified()->NumberModulus(), |
583 Type::Number()); | 576 Type::Number()); |
584 } | 577 } |
585 return NoChange(); | 578 return NoChange(); |
586 } | 579 } |
587 | 580 |
588 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { | 581 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) { |
589 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 582 if (flags() & kDisableIntegerBinaryOpReduction) return NoChange(); |
590 | 583 |
591 JSBinopReduction r(this, node); | 584 JSBinopReduction r(this, node); |
592 r.ConvertInputsToNumber(); | 585 r.ConvertInputsToNumber(); |
593 r.ConvertInputsToUI32(kSigned, kSigned); | 586 r.ConvertInputsToUI32(kSigned, kSigned); |
594 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 587 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
595 } | 588 } |
596 | 589 |
597 | 590 |
598 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, | 591 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, |
599 Signedness left_signedness, | 592 Signedness left_signedness, |
600 const Operator* shift_op) { | 593 const Operator* shift_op) { |
601 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 594 if (flags() & kDisableIntegerBinaryOpReduction) return NoChange(); |
602 | 595 |
603 JSBinopReduction r(this, node); | 596 JSBinopReduction r(this, node); |
604 r.ConvertInputsToNumber(); | 597 r.ConvertInputsToNumber(); |
605 r.ConvertInputsToUI32(left_signedness, kUnsigned); | 598 r.ConvertInputsToUI32(left_signedness, kUnsigned); |
606 return r.ChangeToPureOperator(shift_op); | 599 return r.ChangeToPureOperator(shift_op); |
607 } | 600 } |
608 | 601 |
609 | 602 |
610 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 603 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { |
611 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
612 | |
613 JSBinopReduction r(this, node); | 604 JSBinopReduction r(this, node); |
614 if (r.BothInputsAre(Type::String())) { | 605 if (r.BothInputsAre(Type::String())) { |
615 // If both inputs are definitely strings, perform a string comparison. | 606 // If both inputs are definitely strings, perform a string comparison. |
616 const Operator* stringOp; | 607 const Operator* stringOp; |
617 switch (node->opcode()) { | 608 switch (node->opcode()) { |
618 case IrOpcode::kJSLessThan: | 609 case IrOpcode::kJSLessThan: |
619 stringOp = simplified()->StringLessThan(); | 610 stringOp = simplified()->StringLessThan(); |
620 break; | 611 break; |
621 case IrOpcode::kJSGreaterThan: | 612 case IrOpcode::kJSGreaterThan: |
622 stringOp = simplified()->StringLessThan(); | 613 stringOp = simplified()->StringLessThan(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 } | 705 } |
715 if (invert) { | 706 if (invert) { |
716 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); | 707 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); |
717 } | 708 } |
718 return Replace(replacement); | 709 return Replace(replacement); |
719 } | 710 } |
720 return NoChange(); | 711 return NoChange(); |
721 } | 712 } |
722 | 713 |
723 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { | 714 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { |
724 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
725 | |
726 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); | 715 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); |
727 if (reduction.Changed()) { | 716 if (reduction.Changed()) { |
728 ReplaceWithValue(node, reduction.replacement()); | 717 ReplaceWithValue(node, reduction.replacement()); |
729 return reduction; | 718 return reduction; |
730 } | 719 } |
731 | 720 |
732 JSBinopReduction r(this, node); | 721 JSBinopReduction r(this, node); |
733 | 722 |
734 if (r.BothInputsAre(Type::Number())) { | 723 if (r.BothInputsAre(Type::Number())) { |
735 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 724 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
(...skipping 22 matching lines...) Expand all Loading... |
758 value->ReplaceInput(0, node); | 747 value->ReplaceInput(0, node); |
759 return Replace(value); | 748 return Replace(value); |
760 } | 749 } |
761 return Changed(node); | 750 return Changed(node); |
762 } | 751 } |
763 return NoChange(); | 752 return NoChange(); |
764 } | 753 } |
765 | 754 |
766 | 755 |
767 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 756 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { |
768 if (flags() & kDisableBinaryOpReduction) return NoChange(); | |
769 | |
770 JSBinopReduction r(this, node); | 757 JSBinopReduction r(this, node); |
771 if (r.left() == r.right()) { | 758 if (r.left() == r.right()) { |
772 // x === x is always true if x != NaN | 759 // x === x is always true if x != NaN |
773 if (!r.left_type()->Maybe(Type::NaN())) { | 760 if (!r.left_type()->Maybe(Type::NaN())) { |
774 Node* replacement = jsgraph()->BooleanConstant(!invert); | 761 Node* replacement = jsgraph()->BooleanConstant(!invert); |
775 ReplaceWithValue(node, replacement); | 762 ReplaceWithValue(node, replacement); |
776 return Replace(replacement); | 763 return Replace(replacement); |
777 } | 764 } |
778 } | 765 } |
779 if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) { | 766 if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) { |
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 } | 2059 } |
2073 | 2060 |
2074 | 2061 |
2075 CompilationDependencies* JSTypedLowering::dependencies() const { | 2062 CompilationDependencies* JSTypedLowering::dependencies() const { |
2076 return dependencies_; | 2063 return dependencies_; |
2077 } | 2064 } |
2078 | 2065 |
2079 } // namespace compiler | 2066 } // namespace compiler |
2080 } // namespace internal | 2067 } // namespace internal |
2081 } // namespace v8 | 2068 } // namespace v8 |
OLD | NEW |