Chromium Code Reviews| 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 info->restriction_type(), graph_zone()); \ | 461 info->restriction_type(), graph_zone()); \ |
| 462 break; \ | 462 break; \ |
| 463 } | 463 } |
| 464 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE) | 464 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE) |
| 465 #undef DECLARE_CASE | 465 #undef DECLARE_CASE |
| 466 | 466 |
| 467 case IrOpcode::kPlainPrimitiveToNumber: | 467 case IrOpcode::kPlainPrimitiveToNumber: |
| 468 new_type = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 468 new_type = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
| 469 break; | 469 break; |
| 470 | 470 |
| 471 case IrOpcode::kCheckFloat64Hole: | |
| 472 new_type = Type::Intersect( | |
| 473 op_typer_.CheckFloat64Hole(FeedbackTypeOf(node->InputAt(0))), | |
| 474 info->restriction_type(), graph_zone()); | |
| 475 break; | |
| 476 | |
| 477 case IrOpcode::kCheckNumber: | |
| 478 new_type = Type::Intersect( | |
| 479 op_typer_.CheckNumber(FeedbackTypeOf(node->InputAt(0))), | |
| 480 info->restriction_type(), graph_zone()); | |
| 481 break; | |
| 482 | |
| 471 case IrOpcode::kPhi: { | 483 case IrOpcode::kPhi: { |
| 472 new_type = TypePhi(node); | 484 new_type = TypePhi(node); |
| 473 if (type != nullptr) { | 485 if (type != nullptr) { |
| 474 new_type = Weaken(node, type, new_type); | 486 new_type = Weaken(node, type, new_type); |
| 475 } | 487 } |
| 476 break; | 488 break; |
| 477 } | 489 } |
| 478 | 490 |
| 479 case IrOpcode::kTypeGuard: { | 491 case IrOpcode::kTypeGuard: { |
| 480 new_type = op_typer_.TypeTypeGuard(node->op(), | 492 new_type = op_typer_.TypeTypeGuard(node->op(), |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 int value_count = node->op()->ValueInputCount() + | 824 int value_count = node->op()->ValueInputCount() + |
| 813 OperatorProperties::GetContextInputCount(node->op()) + | 825 OperatorProperties::GetContextInputCount(node->op()) + |
| 814 OperatorProperties::GetFrameStateInputCount(node->op()); | 826 OperatorProperties::GetFrameStateInputCount(node->op()); |
| 815 for (int i = 0; i < value_count; i++) { | 827 for (int i = 0; i < value_count; i++) { |
| 816 ProcessInput(node, i, UseInfo::None()); | 828 ProcessInput(node, i, UseInfo::None()); |
| 817 } | 829 } |
| 818 ProcessRemainingInputs(node, value_count); | 830 ProcessRemainingInputs(node, value_count); |
| 819 if (lower()) Kill(node); | 831 if (lower()) Kill(node); |
| 820 } | 832 } |
| 821 | 833 |
| 834 // Helper for no-op node. | |
| 835 void VisitNoop(Node* node, Truncation truncation) { | |
| 836 if (truncation.IsUnused()) return VisitUnused(node); | |
| 837 MachineRepresentation representation = | |
| 838 GetOutputInfoForPhi(node, TypeOf(node), truncation); | |
| 839 VisitUnop(node, UseInfo(representation, truncation), representation); | |
| 840 if (lower()) DeferReplacement(node, node->InputAt(0)); | |
| 841 } | |
| 842 | |
| 822 // Helper for binops of the R x L -> O variety. | 843 // Helper for binops of the R x L -> O variety. |
| 823 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 844 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
| 824 MachineRepresentation output, | 845 MachineRepresentation output, |
| 825 Type* restriction_type = Type::Any()) { | 846 Type* restriction_type = Type::Any()) { |
| 826 DCHECK_EQ(2, node->op()->ValueInputCount()); | 847 DCHECK_EQ(2, node->op()->ValueInputCount()); |
| 827 ProcessInput(node, 0, left_use); | 848 ProcessInput(node, 0, left_use); |
| 828 ProcessInput(node, 1, right_use); | 849 ProcessInput(node, 1, right_use); |
| 829 for (int i = 2; i < node->InputCount(); i++) { | 850 for (int i = 2; i < node->InputCount(); i++) { |
| 830 EnqueueInput(node, i); | 851 EnqueueInput(node, i); |
| 831 } | 852 } |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2349 VisitUnop(node, UseInfo::AnyTagged(), | 2370 VisitUnop(node, UseInfo::AnyTagged(), |
| 2350 MachineRepresentation::kTaggedPointer); | 2371 MachineRepresentation::kTaggedPointer); |
| 2351 if (lower()) DeferReplacement(node, node->InputAt(0)); | 2372 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 2352 } else { | 2373 } else { |
| 2353 VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(), | 2374 VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(), |
| 2354 MachineRepresentation::kTaggedPointer); | 2375 MachineRepresentation::kTaggedPointer); |
| 2355 } | 2376 } |
| 2356 return; | 2377 return; |
| 2357 } | 2378 } |
| 2358 case IrOpcode::kCheckNumber: { | 2379 case IrOpcode::kCheckNumber: { |
| 2359 if (InputIs(node, Type::Number())) { | 2380 Type* const input_type = TypeOf(node->InputAt(0)); |
| 2360 if (truncation.IsUsedAsWord32()) { | 2381 if (input_type->Is(Type::Number())) { |
| 2361 VisitUnop(node, UseInfo::TruncatingWord32(), | 2382 VisitNoop(node, truncation); |
| 2362 MachineRepresentation::kWord32); | |
| 2363 } else { | |
| 2364 // TODO(jarin,bmeurer): We need to go to Tagged here, because | |
| 2365 // otherwise we cannot distinguish the hole NaN (which might need to | |
| 2366 // be treated as undefined). We should have a dedicated Type for | |
| 2367 // that at some point, and maybe even a dedicated truncation. | |
| 2368 VisitUnop(node, UseInfo::AnyTagged(), | |
| 2369 MachineRepresentation::kTagged); | |
| 2370 } | |
| 2371 if (lower()) DeferReplacement(node, node->InputAt(0)); | |
| 2372 } else { | 2383 } else { |
| 2373 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); | 2384 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
| 2374 } | 2385 } |
| 2375 return; | 2386 return; |
| 2376 } | 2387 } |
| 2377 case IrOpcode::kCheckReceiver: { | 2388 case IrOpcode::kCheckReceiver: { |
| 2378 if (InputIs(node, Type::Receiver())) { | 2389 if (InputIs(node, Type::Receiver())) { |
| 2379 VisitUnop(node, UseInfo::AnyTagged(), | 2390 VisitUnop(node, UseInfo::AnyTagged(), |
| 2380 MachineRepresentation::kTaggedPointer); | 2391 MachineRepresentation::kTaggedPointer); |
| 2381 if (lower()) DeferReplacement(node, node->InputAt(0)); | 2392 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2674 case IrOpcode::kNewUnmappedArgumentsElements: { | 2685 case IrOpcode::kNewUnmappedArgumentsElements: { |
| 2675 VisitBinop(node, UseInfo::PointerInt(), UseInfo::TaggedSigned(), | 2686 VisitBinop(node, UseInfo::PointerInt(), UseInfo::TaggedSigned(), |
| 2676 MachineRepresentation::kTaggedPointer); | 2687 MachineRepresentation::kTaggedPointer); |
| 2677 return; | 2688 return; |
| 2678 } | 2689 } |
| 2679 case IrOpcode::kArrayBufferWasNeutered: { | 2690 case IrOpcode::kArrayBufferWasNeutered: { |
| 2680 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); | 2691 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); |
| 2681 return; | 2692 return; |
| 2682 } | 2693 } |
| 2683 case IrOpcode::kCheckFloat64Hole: { | 2694 case IrOpcode::kCheckFloat64Hole: { |
| 2684 CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op()); | 2695 Type* const input_type = TypeOf(node->InputAt(0)); |
| 2685 ProcessInput(node, 0, UseInfo::TruncatingFloat64()); | 2696 if (input_type->Is(Type::Number())) { |
| 2686 ProcessRemainingInputs(node, 1); | 2697 VisitNoop(node, truncation); |
| 2687 SetOutput(node, MachineRepresentation::kFloat64); | 2698 } else { |
| 2688 if (truncation.IsUsedAsFloat64() && | 2699 CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op()); |
| 2689 mode == CheckFloat64HoleMode::kAllowReturnHole) { | 2700 switch (mode) { |
| 2690 if (lower()) DeferReplacement(node, node->InputAt(0)); | 2701 case CheckFloat64HoleMode::kAllowReturnHole: |
| 2702 if (truncation.IsUnused()) return VisitUnused(node); | |
| 2703 if (truncation.IsUsedAsWord32()) { | |
|
Michael Achenbach
2017/04/12 10:23:01
FYI: According to (64 bit) coverage bot, this cond
Benedikt Meurer
2017/04/12 10:24:18
Not necessarily.
| |
| 2704 VisitUnop(node, UseInfo::TruncatingWord32(), | |
| 2705 MachineRepresentation::kWord32); | |
| 2706 if (lower()) DeferReplacement(node, node->InputAt(0)); | |
| 2707 } else if (truncation.IsUsedAsFloat64()) { | |
| 2708 VisitUnop(node, UseInfo::TruncatingFloat64(), | |
| 2709 MachineRepresentation::kFloat64); | |
| 2710 if (lower()) DeferReplacement(node, node->InputAt(0)); | |
| 2711 } else { | |
| 2712 VisitUnop( | |
| 2713 node, | |
| 2714 UseInfo(MachineRepresentation::kFloat64, Truncation::Any()), | |
| 2715 MachineRepresentation::kFloat64, Type::Number()); | |
| 2716 } | |
| 2717 break; | |
| 2718 case CheckFloat64HoleMode::kNeverReturnHole: | |
| 2719 VisitUnop( | |
| 2720 node, | |
| 2721 UseInfo(MachineRepresentation::kFloat64, Truncation::Any()), | |
| 2722 MachineRepresentation::kFloat64, Type::Number()); | |
| 2723 break; | |
| 2724 } | |
| 2691 } | 2725 } |
| 2692 return; | 2726 return; |
| 2693 } | 2727 } |
| 2694 case IrOpcode::kCheckTaggedHole: { | 2728 case IrOpcode::kCheckTaggedHole: { |
| 2695 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); | 2729 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
| 2696 return; | 2730 return; |
| 2697 } | 2731 } |
| 2698 case IrOpcode::kConvertTaggedHoleToUndefined: { | 2732 case IrOpcode::kConvertTaggedHoleToUndefined: { |
| 2699 if (InputIs(node, Type::NumberOrOddball()) && | 2733 if (InputIs(node, Type::NumberOrOddball()) && |
| 2700 truncation.IsUsedAsWord32()) { | 2734 truncation.IsUsedAsWord32()) { |
| (...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3645 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3679 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3646 Operator::kNoProperties); | 3680 Operator::kNoProperties); |
| 3647 to_number_operator_.set(common()->Call(desc)); | 3681 to_number_operator_.set(common()->Call(desc)); |
| 3648 } | 3682 } |
| 3649 return to_number_operator_.get(); | 3683 return to_number_operator_.get(); |
| 3650 } | 3684 } |
| 3651 | 3685 |
| 3652 } // namespace compiler | 3686 } // namespace compiler |
| 3653 } // namespace internal | 3687 } // namespace internal |
| 3654 } // namespace v8 | 3688 } // namespace v8 |
| OLD | NEW |