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

Side by Side Diff: runtime/vm/intermediate_language_arm.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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 3581 matching lines...) Expand 10 before | Expand all | Expand 10 after
3592 3592
3593 3593
3594 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3594 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const {
3595 if (result_cid() == kDoubleCid) { 3595 if (result_cid() == kDoubleCid) {
3596 const intptr_t kNumInputs = 2; 3596 const intptr_t kNumInputs = 2;
3597 const intptr_t kNumTemps = 1; 3597 const intptr_t kNumTemps = 1;
3598 LocationSummary* summary = 3598 LocationSummary* summary =
3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3599 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3600 summary->set_in(0, Location::RequiresFpuRegister()); 3600 summary->set_in(0, Location::RequiresFpuRegister());
3601 summary->set_in(1, Location::RequiresFpuRegister()); 3601 summary->set_in(1, Location::RequiresFpuRegister());
3602 // Reuse the left register so that code can be made shorter.
3603 summary->set_out(Location::SameAsFirstInput());
3602 summary->set_temp(0, Location::RequiresRegister()); 3604 summary->set_temp(0, Location::RequiresRegister());
3603 summary->set_out(Location::RequiresFpuRegister());
3604 return summary; 3605 return summary;
3605 } 3606 }
3606 ASSERT(result_cid() == kSmiCid); 3607 ASSERT(result_cid() == kSmiCid);
3607 UNIMPLEMENTED(); 3608 const intptr_t kNumInputs = 2;
3608 return NULL; 3609 const intptr_t kNumTemps = 0;
3610 LocationSummary* summary =
3611 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3612 summary->set_in(0, Location::RequiresRegister());
3613 summary->set_in(1, Location::RequiresRegister());
3614 // Reuse the left register so that code can be made shorter.
3615 summary->set_out(Location::SameAsFirstInput());
3616 return summary;
3609 } 3617 }
3610 3618
3611 3619
3612 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3620 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3613 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3621 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3614 (op_kind() == MethodRecognizer::kMathMax)); 3622 (op_kind() == MethodRecognizer::kMathMax));
3623 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3615 if (result_cid() == kDoubleCid) { 3624 if (result_cid() == kDoubleCid) {
3616 Label done, returns_nan, are_equal; 3625 Label done, returns_nan, are_equal;
3617 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 3626 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
3618 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 3627 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
3619 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 3628 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
3620 Register temp = locs()->temp(0).reg(); 3629 Register temp = locs()->temp(0).reg();
3621 __ vcmpd(left, right); 3630 __ vcmpd(left, right);
3622 __ vmstat(); 3631 __ vmstat();
3623 __ b(&returns_nan, VS); 3632 __ b(&returns_nan, VS);
3624 __ b(&are_equal, EQ); 3633 __ b(&are_equal, EQ);
3625 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3626 const Condition double_condition =
3627 is_min ? TokenKindToDoubleCondition(Token::kLT)
3628 : TokenKindToDoubleCondition(Token::kGT);
3629 const Condition neg_double_condition = 3634 const Condition neg_double_condition =
3630 is_min ? TokenKindToDoubleCondition(Token::kGTE) 3635 is_min ? TokenKindToDoubleCondition(Token::kGTE)
3631 : TokenKindToDoubleCondition(Token::kLTE); 3636 : TokenKindToDoubleCondition(Token::kLTE);
3632 __ vmovd(result, left, double_condition); 3637 ASSERT(left == result);
3633 __ vmovd(result, right, neg_double_condition); 3638 __ vmovd(result, right, neg_double_condition);
3634 __ b(&done); 3639 __ b(&done);
3635 3640
3636 __ Bind(&returns_nan); 3641 __ Bind(&returns_nan);
3637 __ LoadDImmediate(result, NAN, temp); 3642 __ LoadDImmediate(result, NAN, temp);
3638 __ b(&done); 3643 __ b(&done);
3639 3644
3640 __ Bind(&are_equal); 3645 __ Bind(&are_equal);
3641 // Check for negative zero: -0.0 is equal 0.0 but min or max must return 3646 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3642 // -0.0 or 0.0 respectively. 3647 // -0.0 or 0.0 respectively.
3643 // Check for negative left value (get the sign bit): 3648 // Check for negative left value (get the sign bit):
3644 // - min -> left is negative ? left : right. 3649 // - min -> left is negative ? left : right.
3645 // - max -> left is negative ? right : left 3650 // - max -> left is negative ? right : left
3646 // Check the sign bit. 3651 // Check the sign bit.
3647 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. 3652 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp.
3648 __ cmp(temp, ShifterOperand(0)); 3653 __ cmp(temp, ShifterOperand(0));
3649 if (is_min) { 3654 if (is_min) {
3650 __ vmovd(result, left, LT); 3655 ASSERT(left == result);
3651 __ vmovd(result, right, GE); 3656 __ vmovd(result, right, GE);
3652 } else { 3657 } else {
3653 __ vmovd(result, right, LT); 3658 __ vmovd(result, right, LT);
3654 __ vmovd(result, left, GE); 3659 ASSERT(left == result);
3655 } 3660 }
3656 __ Bind(&done); 3661 __ Bind(&done);
3657 return; 3662 return;
3658 } 3663 }
3664
3659 ASSERT(result_cid() == kSmiCid); 3665 ASSERT(result_cid() == kSmiCid);
3660 UNIMPLEMENTED(); 3666 Register left = locs()->in(0).reg();
3667 Register right = locs()->in(1).reg();
3668 Register result = locs()->out().reg();
3669 __ cmp(left, ShifterOperand(right));
3670 ASSERT(result == left);
3671 if (is_min) {
3672 __ mov(result, ShifterOperand(right), GT);
3673 } else {
3674 __ mov(result, ShifterOperand(right), LT);
3675 }
3661 } 3676 }
3662 3677
3663 3678
3664 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3679 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
3665 const intptr_t kNumInputs = 1; 3680 const intptr_t kNumInputs = 1;
3666 const intptr_t kNumTemps = 0; 3681 const intptr_t kNumTemps = 0;
3667 LocationSummary* summary = 3682 LocationSummary* summary =
3668 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3669 summary->set_in(0, Location::RequiresRegister()); 3684 summary->set_in(0, Location::RequiresRegister());
3670 // We make use of 3-operand instructions by not requiring result register 3685 // We make use of 3-operand instructions by not requiring result register
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
4352 compiler->GenerateCall(token_pos(), 4367 compiler->GenerateCall(token_pos(),
4353 &label, 4368 &label,
4354 PcDescriptors::kOther, 4369 PcDescriptors::kOther,
4355 locs()); 4370 locs());
4356 __ Drop(2); // Discard type arguments and receiver. 4371 __ Drop(2); // Discard type arguments and receiver.
4357 } 4372 }
4358 4373
4359 } // namespace dart 4374 } // namespace dart
4360 4375
4361 #endif // defined TARGET_ARCH_ARM 4376 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698