Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 19695007: Optimize double min/max by reducing the code size (reusing left register as result removes the need… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 3624 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 3635
3636 3636
3637 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3637 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const {
3638 if (result_cid() == kDoubleCid) { 3638 if (result_cid() == kDoubleCid) {
3639 const intptr_t kNumInputs = 2; 3639 const intptr_t kNumInputs = 2;
3640 const intptr_t kNumTemps = 1; 3640 const intptr_t kNumTemps = 1;
3641 LocationSummary* summary = 3641 LocationSummary* summary =
3642 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3642 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3643 summary->set_in(0, Location::RequiresFpuRegister()); 3643 summary->set_in(0, Location::RequiresFpuRegister());
3644 summary->set_in(1, Location::RequiresFpuRegister()); 3644 summary->set_in(1, Location::RequiresFpuRegister());
3645 summary->set_out(Location::RequiresFpuRegister()); 3645 // Reuse the left register so that code can be made shorter.
3646 summary->set_out(Location::SameAsFirstInput());
3646 summary->set_temp(0, Location::RequiresRegister()); 3647 summary->set_temp(0, Location::RequiresRegister());
3647 return summary; 3648 return summary;
3648 } 3649 }
3649 ASSERT(result_cid() == kSmiCid); 3650 ASSERT(result_cid() == kSmiCid);
3650 UNIMPLEMENTED(); 3651 const intptr_t kNumInputs = 2;
3651 return NULL; 3652 const intptr_t kNumTemps = 0;
3653 LocationSummary* summary =
3654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3655 summary->set_in(0, Location::RequiresRegister());
3656 summary->set_in(1, Location::RequiresRegister());
3657 // Reuse the left register so that code can be made shorter.
3658 summary->set_out(Location::SameAsFirstInput());
3659 return summary;
3652 } 3660 }
3653 3661
3654 3662
3655 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3663 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3656 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3664 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3657 (op_kind() == MethodRecognizer::kMathMax)); 3665 (op_kind() == MethodRecognizer::kMathMax));
3666 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3658 if (result_cid() == kDoubleCid) { 3667 if (result_cid() == kDoubleCid) {
3659 Label done, returns_left, returns_nan, are_equal; 3668 Label done, returns_nan, are_equal;
3660 XmmRegister left = locs()->in(0).fpu_reg(); 3669 XmmRegister left = locs()->in(0).fpu_reg();
3661 XmmRegister right = locs()->in(1).fpu_reg(); 3670 XmmRegister right = locs()->in(1).fpu_reg();
3662 XmmRegister result = locs()->out().fpu_reg(); 3671 XmmRegister result = locs()->out().fpu_reg();
3663 Register temp = locs()->temp(0).reg(); 3672 Register temp = locs()->temp(0).reg();
3664 __ comisd(left, right); 3673 __ comisd(left, right);
3665 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); 3674 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump);
3666 __ j(EQUAL, &are_equal, Assembler::kNearJump); 3675 __ j(EQUAL, &are_equal, Assembler::kNearJump);
3667 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3668 const Condition double_condition = 3676 const Condition double_condition =
3669 is_min ? TokenKindToDoubleCondition(Token::kLT) 3677 is_min ? TokenKindToDoubleCondition(Token::kLT)
3670 : TokenKindToDoubleCondition(Token::kGT); 3678 : TokenKindToDoubleCondition(Token::kGT);
3671 __ j(double_condition, &returns_left, Assembler::kNearJump); 3679 ASSERT(left == result);
3680 __ j(double_condition, &done, Assembler::kNearJump);
3672 __ movsd(result, right); 3681 __ movsd(result, right);
3673 __ jmp(&done, Assembler::kNearJump); 3682 __ jmp(&done, Assembler::kNearJump);
3674 3683
3675 __ Bind(&returns_left);
3676 __ movsd(result, left);
3677 __ jmp(&done, Assembler::kNearJump);
3678
3679 __ Bind(&returns_nan); 3684 __ Bind(&returns_nan);
3680 static double kNaN = NAN; 3685 static double kNaN = NAN;
3681 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN))); 3686 __ movsd(result, Address::Absolute(reinterpret_cast<uword>(&kNaN)));
3682 __ jmp(&done, Assembler::kNearJump); 3687 __ jmp(&done, Assembler::kNearJump);
3683 3688
3684 __ Bind(&are_equal); 3689 __ Bind(&are_equal);
3685 Label left_is_negative; 3690 Label left_is_negative;
3686 // Check for negative zero: -0.0 is equal 0.0 but min or max must return 3691 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3687 // -0.0 or 0.0 respectively. 3692 // -0.0 or 0.0 respectively.
3688 // Check for negative left value (get the sign bit): 3693 // Check for negative left value (get the sign bit):
3689 // - min -> left is negative ? left : right. 3694 // - min -> left is negative ? left : right.
3690 // - max -> left is negative ? right : left 3695 // - max -> left is negative ? right : left
3691 // Check the sign bit. 3696 // Check the sign bit.
3692 __ movmskpd(temp, left); 3697 __ movmskpd(temp, left);
3693 __ testl(temp, Immediate(1)); 3698 __ testl(temp, Immediate(1));
3694 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump); 3699 ASSERT(left == result);
3695 // Left is positive. 3700 if (is_min) {
3696 __ movsd(result, (is_min ? right : left)); 3701 __ j(NOT_ZERO, &done, Assembler::kNearJump); // Negative -> return left.
3697 __ jmp(&done, Assembler::kNearJump); 3702 } else {
3698 3703 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left.
3699 __ Bind(&left_is_negative); 3704 }
3700 __ movsd(result, (is_min ? left : right)); 3705 __ movsd(result, right);
3701 __ Bind(&done); 3706 __ Bind(&done);
3702 return; 3707 return;
3703 } 3708 }
3709
3710 Label done;
3704 ASSERT(result_cid() == kSmiCid); 3711 ASSERT(result_cid() == kSmiCid);
3705 UNIMPLEMENTED(); 3712 Register left = locs()->in(0).reg();
3713 Register right = locs()->in(1).reg();
3714 Register result = locs()->out().reg();
3715 __ cmpl(left, right);
3716 if (is_min) {
3717 ASSERT(result == left);
3718 __ j(LESS_EQUAL, &done, Assembler::kNearJump);
3719 } else {
3720 __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
3721 }
3722 __ movl(result, right);
3723 __ Bind(&done);
3706 } 3724 }
3707 3725
3708 3726
3709 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3727 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
3710 const intptr_t kNumInputs = 1; 3728 const intptr_t kNumInputs = 1;
3711 return LocationSummary::Make(kNumInputs, 3729 return LocationSummary::Make(kNumInputs,
3712 Location::SameAsFirstInput(), 3730 Location::SameAsFirstInput(),
3713 LocationSummary::kNoCall); 3731 LocationSummary::kNoCall);
3714 } 3732 }
3715 3733
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4821 PcDescriptors::kOther, 4839 PcDescriptors::kOther,
4822 locs()); 4840 locs());
4823 __ Drop(2); // Discard type arguments and receiver. 4841 __ Drop(2); // Discard type arguments and receiver.
4824 } 4842 }
4825 4843
4826 } // namespace dart 4844 } // namespace dart
4827 4845
4828 #undef __ 4846 #undef __
4829 4847
4830 #endif // defined TARGET_ARCH_IA32 4848 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698