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

Side by Side Diff: runtime/vm/intermediate_language_x64.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, 4 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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 3690 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 3701
3702 3702
3703 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3703 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const {
3704 if (result_cid() == kDoubleCid) { 3704 if (result_cid() == kDoubleCid) {
3705 const intptr_t kNumInputs = 2; 3705 const intptr_t kNumInputs = 2;
3706 const intptr_t kNumTemps = 1; 3706 const intptr_t kNumTemps = 1;
3707 LocationSummary* summary = 3707 LocationSummary* summary =
3708 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3708 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3709 summary->set_in(0, Location::RequiresFpuRegister()); 3709 summary->set_in(0, Location::RequiresFpuRegister());
3710 summary->set_in(1, Location::RequiresFpuRegister()); 3710 summary->set_in(1, Location::RequiresFpuRegister());
3711 // Reuse the left register so that code can be made shorter.
3712 summary->set_out(Location::SameAsFirstInput());
3711 summary->set_temp(0, Location::RequiresRegister()); 3713 summary->set_temp(0, Location::RequiresRegister());
3712 summary->set_out(Location::RequiresFpuRegister());
3713 return summary; 3714 return summary;
3714 } 3715 }
3715 ASSERT(result_cid() == kSmiCid); 3716 ASSERT(result_cid() == kSmiCid);
3716 UNIMPLEMENTED(); 3717 const intptr_t kNumInputs = 2;
3717 return NULL; 3718 const intptr_t kNumTemps = 0;
3719 LocationSummary* summary =
3720 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3721 summary->set_in(0, Location::RequiresRegister());
3722 summary->set_in(1, Location::RequiresRegister());
3723 // Reuse the left register so that code can be made shorter.
3724 summary->set_out(Location::SameAsFirstInput());
3725 return summary;
3718 } 3726 }
3719 3727
3720 3728
3721 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3729 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3722 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3730 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3723 (op_kind() == MethodRecognizer::kMathMax)); 3731 (op_kind() == MethodRecognizer::kMathMax));
3732 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3724 if (result_cid() == kDoubleCid) { 3733 if (result_cid() == kDoubleCid) {
3725 Label done, returns_left, returns_nan, are_equal; 3734 Label done, returns_nan, are_equal;
3726 XmmRegister left = locs()->in(0).fpu_reg(); 3735 XmmRegister left = locs()->in(0).fpu_reg();
3727 XmmRegister right = locs()->in(1).fpu_reg(); 3736 XmmRegister right = locs()->in(1).fpu_reg();
3728 XmmRegister result = locs()->out().fpu_reg(); 3737 XmmRegister result = locs()->out().fpu_reg();
3729 Register temp = locs()->temp(0).reg(); 3738 Register temp = locs()->temp(0).reg();
3730 __ comisd(left, right); 3739 __ comisd(left, right);
3731 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump); 3740 __ j(PARITY_EVEN, &returns_nan, Assembler::kNearJump);
3732 __ j(EQUAL, &are_equal, Assembler::kNearJump); 3741 __ j(EQUAL, &are_equal, Assembler::kNearJump);
3733 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3734 const Condition double_condition = 3742 const Condition double_condition =
3735 is_min ? TokenKindToDoubleCondition(Token::kLT) 3743 is_min ? TokenKindToDoubleCondition(Token::kLT)
3736 : TokenKindToDoubleCondition(Token::kGT); 3744 : TokenKindToDoubleCondition(Token::kGT);
3737 __ j(double_condition, &returns_left, Assembler::kNearJump); 3745 ASSERT(left == result);
3746 __ j(double_condition, &done, Assembler::kNearJump);
3738 __ movsd(result, right); 3747 __ movsd(result, right);
3739 __ jmp(&done, Assembler::kNearJump); 3748 __ jmp(&done, Assembler::kNearJump);
3740 3749
3741 __ Bind(&returns_left);
3742 __ movsd(result, left);
3743 __ jmp(&done, Assembler::kNearJump);
3744
3745 __ Bind(&returns_nan); 3750 __ Bind(&returns_nan);
3746 static double kNaN = NAN; 3751 static double kNaN = NAN;
3747 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN))); 3752 __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)));
3748 __ movsd(result, Address(temp, 0)); 3753 __ movsd(result, Address(temp, 0));
3749 __ jmp(&done, Assembler::kNearJump); 3754 __ jmp(&done, Assembler::kNearJump);
3750 3755
3751 __ Bind(&are_equal); 3756 __ Bind(&are_equal);
3752 Label left_is_negative; 3757 Label left_is_negative;
3753 // Check for negative zero: -0.0 is equal 0.0 but min or max must return 3758 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3754 // -0.0 or 0.0 respectively. 3759 // -0.0 or 0.0 respectively.
3755 // Check for negative left value (get the sign bit): 3760 // Check for negative left value (get the sign bit):
3756 // - min -> left is negative ? left : right. 3761 // - min -> left is negative ? left : right.
3757 // - max -> left is negative ? right : left 3762 // - max -> left is negative ? right : left
3758 // Check the sign bit. 3763 // Check the sign bit.
3759 __ movmskpd(temp, left); 3764 __ movmskpd(temp, left);
3760 __ testq(temp, Immediate(1)); 3765 __ testq(temp, Immediate(1));
3761 __ j(NOT_ZERO, &left_is_negative, Assembler::kNearJump); 3766 if (is_min) {
3762 // Left is positive. 3767 ASSERT(left == result);
3763 __ movsd(result, (is_min ? right : left)); 3768 __ j(NOT_ZERO, &done, Assembler::kNearJump); // Negative -> return left.
3764 __ jmp(&done, Assembler::kNearJump); 3769 } else {
3765 3770 ASSERT(left == result);
3766 __ Bind(&left_is_negative); 3771 __ j(ZERO, &done, Assembler::kNearJump); // Positive -> return left.
3767 __ movsd(result, (is_min ? left : right)); 3772 }
3773 __ movsd(result, right);
3768 __ Bind(&done); 3774 __ Bind(&done);
3769 return; 3775 return;
3770 } 3776 }
3777
3778 Label done;
3771 ASSERT(result_cid() == kSmiCid); 3779 ASSERT(result_cid() == kSmiCid);
3772 UNIMPLEMENTED(); 3780 Register left = locs()->in(0).reg();
3781 Register right = locs()->in(1).reg();
3782 Register result = locs()->out().reg();
3783 __ cmpq(left, right);
3784 ASSERT(result == left);
3785 if (is_min) {
3786 __ j(LESS_EQUAL, &done, Assembler::kNearJump);
3787 } else {
3788 __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
3789 }
3790 __ movq(result, right);
3791 __ Bind(&done);
3773 } 3792 }
3774 3793
3775 3794
3776 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3795 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3777 Register value = locs()->in(0).reg(); 3796 Register value = locs()->in(0).reg();
3778 ASSERT(value == locs()->out().reg()); 3797 ASSERT(value == locs()->out().reg());
3779 switch (op_kind()) { 3798 switch (op_kind()) {
3780 case Token::kNEGATE: { 3799 case Token::kNEGATE: {
3781 Label* deopt = compiler->AddDeoptStub(deopt_id(), 3800 Label* deopt = compiler->AddDeoptStub(deopt_id(),
3782 kDeoptUnaryOp); 3801 kDeoptUnaryOp);
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
4493 PcDescriptors::kOther, 4512 PcDescriptors::kOther,
4494 locs()); 4513 locs());
4495 __ Drop(2); // Discard type arguments and receiver. 4514 __ Drop(2); // Discard type arguments and receiver.
4496 } 4515 }
4497 4516
4498 } // namespace dart 4517 } // namespace dart
4499 4518
4500 #undef __ 4519 #undef __
4501 4520
4502 #endif // defined TARGET_ARCH_X64 4521 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/intermediate_language_ia32.cc ('K') | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698