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

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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3337 matching lines...) Expand 10 before | Expand all | Expand 10 after
3348 3348
3349 3349
3350 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { 3350 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const {
3351 if (result_cid() == kDoubleCid) { 3351 if (result_cid() == kDoubleCid) {
3352 const intptr_t kNumInputs = 2; 3352 const intptr_t kNumInputs = 2;
3353 const intptr_t kNumTemps = 1; 3353 const intptr_t kNumTemps = 1;
3354 LocationSummary* summary = 3354 LocationSummary* summary =
3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3355 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3356 summary->set_in(0, Location::RequiresFpuRegister()); 3356 summary->set_in(0, Location::RequiresFpuRegister());
3357 summary->set_in(1, Location::RequiresFpuRegister()); 3357 summary->set_in(1, Location::RequiresFpuRegister());
3358 // Reuse the left register so that code can be made shorter.
3359 summary->set_out(Location::SameAsFirstInput());
3358 summary->set_temp(0, Location::RequiresRegister()); 3360 summary->set_temp(0, Location::RequiresRegister());
3359 summary->set_out(Location::RequiresFpuRegister());
3360 return summary; 3361 return summary;
3361 } 3362 }
3362 ASSERT(result_cid() == kSmiCid); 3363 ASSERT(result_cid() == kSmiCid);
3363 UNIMPLEMENTED(); 3364 const intptr_t kNumInputs = 2;
3364 return NULL; 3365 const intptr_t kNumTemps = 0;
3366 LocationSummary* summary =
3367 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3368 summary->set_in(0, Location::RequiresRegister());
3369 summary->set_in(1, Location::RequiresRegister());
3370 // Reuse the left register so that code can be made shorter.
3371 summary->set_out(Location::SameAsFirstInput());
3372 return summary;
3365 } 3373 }
3366 3374
3367 3375
3368 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3376 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3369 ASSERT((op_kind() == MethodRecognizer::kMathMin) || 3377 ASSERT((op_kind() == MethodRecognizer::kMathMin) ||
3370 (op_kind() == MethodRecognizer::kMathMax)); 3378 (op_kind() == MethodRecognizer::kMathMax));
3379 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3371 if (result_cid() == kDoubleCid) { 3380 if (result_cid() == kDoubleCid) {
3372 Label done, returns_nan, are_equal; 3381 Label done, returns_nan, are_equal;
3373 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg()); 3382 DRegister left = EvenDRegisterOf(locs()->in(0).fpu_reg());
3374 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg()); 3383 DRegister right = EvenDRegisterOf(locs()->in(1).fpu_reg());
3375 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 3384 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
3376 Register temp = locs()->temp(0).reg(); 3385 Register temp = locs()->temp(0).reg();
3377 __ vcmpd(left, right); 3386 __ vcmpd(left, right);
3378 __ vmstat(); 3387 __ vmstat();
3379 __ b(&returns_nan, VS); 3388 __ b(&returns_nan, VS);
3380 __ b(&are_equal, EQ); 3389 __ b(&are_equal, EQ);
3381 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin);
3382 const Condition double_condition =
3383 is_min ? TokenKindToDoubleCondition(Token::kLT)
3384 : TokenKindToDoubleCondition(Token::kGT);
3385 const Condition neg_double_condition = 3390 const Condition neg_double_condition =
3386 is_min ? TokenKindToDoubleCondition(Token::kGTE) 3391 is_min ? TokenKindToDoubleCondition(Token::kGTE)
3387 : TokenKindToDoubleCondition(Token::kLTE); 3392 : TokenKindToDoubleCondition(Token::kLTE);
3388 __ vmovd(result, left, double_condition); 3393 ASSERT(left == result);
3389 __ vmovd(result, right, neg_double_condition); 3394 __ vmovd(result, right, neg_double_condition);
3390 __ b(&done); 3395 __ b(&done);
3391 3396
3392 __ Bind(&returns_nan); 3397 __ Bind(&returns_nan);
3393 __ LoadDImmediate(result, NAN, temp); 3398 __ LoadDImmediate(result, NAN, temp);
3394 __ b(&done); 3399 __ b(&done);
3395 3400
3396 __ Bind(&are_equal); 3401 __ Bind(&are_equal);
3397 // Check for negative zero: -0.0 is equal 0.0 but min or max must return 3402 // Check for negative zero: -0.0 is equal 0.0 but min or max must return
3398 // -0.0 or 0.0 respectively. 3403 // -0.0 or 0.0 respectively.
3399 // Check for negative left value (get the sign bit): 3404 // Check for negative left value (get the sign bit):
3400 // - min -> left is negative ? left : right. 3405 // - min -> left is negative ? left : right.
3401 // - max -> left is negative ? right : left 3406 // - max -> left is negative ? right : left
3402 // Check the sign bit. 3407 // Check the sign bit.
3403 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp. 3408 __ vmovrrd(IP, temp, left); // Sign bit is in bit 31 of temp.
3404 __ cmp(temp, ShifterOperand(0)); 3409 __ cmp(temp, ShifterOperand(0));
3405 if (is_min) { 3410 if (is_min) {
3406 __ vmovd(result, left, LT); 3411 ASSERT(left == result);
3407 __ vmovd(result, right, GE); 3412 __ vmovd(result, right, GE);
3408 } else { 3413 } else {
3409 __ vmovd(result, right, LT); 3414 __ vmovd(result, right, LT);
3410 __ vmovd(result, left, GE); 3415 ASSERT(left == result);
3411 } 3416 }
3412 __ Bind(&done); 3417 __ Bind(&done);
3413 return; 3418 return;
3414 } 3419 }
3420
3415 ASSERT(result_cid() == kSmiCid); 3421 ASSERT(result_cid() == kSmiCid);
3416 UNIMPLEMENTED(); 3422 Register left = locs()->in(0).reg();
3423 Register right = locs()->in(1).reg();
3424 Register result = locs()->out().reg();
3425 __ cmp(left, ShifterOperand(right));
3426 ASSERT(result == left);
3427 if (is_min) {
3428 __ mov(result, ShifterOperand(right), GE);
regis 2013/07/23 19:45:47 GT would be more intuitive than GE, but it does no
srdjan 2013/07/23 20:34:01 Done.
3429 } else {
3430 __ mov(result, ShifterOperand(right), LT);
3431 }
3417 } 3432 }
3418 3433
3419 3434
3420 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 3435 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const {
3421 const intptr_t kNumInputs = 1; 3436 const intptr_t kNumInputs = 1;
3422 const intptr_t kNumTemps = 0; 3437 const intptr_t kNumTemps = 0;
3423 LocationSummary* summary = 3438 LocationSummary* summary =
3424 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3439 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3425 summary->set_in(0, Location::RequiresRegister()); 3440 summary->set_in(0, Location::RequiresRegister());
3426 // We make use of 3-operand instructions by not requiring result register 3441 // We make use of 3-operand instructions by not requiring result register
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
4108 compiler->GenerateCall(token_pos(), 4123 compiler->GenerateCall(token_pos(),
4109 &label, 4124 &label,
4110 PcDescriptors::kOther, 4125 PcDescriptors::kOther,
4111 locs()); 4126 locs());
4112 __ Drop(2); // Discard type arguments and receiver. 4127 __ Drop(2); // Discard type arguments and receiver.
4113 } 4128 }
4114 4129
4115 } // namespace dart 4130 } // namespace dart
4116 4131
4117 #endif // defined TARGET_ARCH_ARM 4132 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698