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

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

Issue 81623003: Use range information to omit checks in TRUNCDIV/MOD operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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/intermediate_language.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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 2356 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 } 2367 }
2368 2368
2369 default: 2369 default:
2370 UNREACHABLE(); 2370 UNREACHABLE();
2371 break; 2371 break;
2372 } 2372 }
2373 return; 2373 return;
2374 } 2374 }
2375 2375
2376 Register right = locs()->in(1).reg(); 2376 Register right = locs()->in(1).reg();
2377 Range* right_range = this->right()->definition()->range();
2377 switch (op_kind()) { 2378 switch (op_kind()) {
2378 case Token::kADD: { 2379 case Token::kADD: {
2379 if (deopt == NULL) { 2380 if (deopt == NULL) {
2380 __ add(result, left, ShifterOperand(right)); 2381 __ add(result, left, ShifterOperand(right));
2381 } else { 2382 } else {
2382 __ adds(result, left, ShifterOperand(right)); 2383 __ adds(result, left, ShifterOperand(right));
2383 __ b(deopt, VS); 2384 __ b(deopt, VS);
2384 } 2385 }
2385 break; 2386 break;
2386 } 2387 }
(...skipping 27 matching lines...) Expand all
2414 // No overflow check. 2415 // No overflow check.
2415 __ orr(result, left, ShifterOperand(right)); 2416 __ orr(result, left, ShifterOperand(right));
2416 break; 2417 break;
2417 } 2418 }
2418 case Token::kBIT_XOR: { 2419 case Token::kBIT_XOR: {
2419 // No overflow check. 2420 // No overflow check.
2420 __ eor(result, left, ShifterOperand(right)); 2421 __ eor(result, left, ShifterOperand(right));
2421 break; 2422 break;
2422 } 2423 }
2423 case Token::kTRUNCDIV: { 2424 case Token::kTRUNCDIV: {
2424 // Handle divide by zero in runtime. 2425 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
2425 __ cmp(right, ShifterOperand(0)); 2426 // Handle divide by zero in runtime.
2426 __ b(deopt, EQ); 2427 __ cmp(right, ShifterOperand(0));
2428 __ b(deopt, EQ);
2429 }
2427 Register temp = locs()->temp(0).reg(); 2430 Register temp = locs()->temp(0).reg();
2428 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 2431 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
2429 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2432 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2430 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2433 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2431 2434
2432 __ IntegerDivide(result, temp, IP, dtemp, DTMP); 2435 __ IntegerDivide(result, temp, IP, dtemp, DTMP);
2433 2436
2434 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2437 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2435 // case we cannot tag the result. 2438 // case we cannot tag the result.
2436 __ CompareImmediate(result, 0x40000000); 2439 __ CompareImmediate(result, 0x40000000);
2437 __ b(deopt, EQ); 2440 __ b(deopt, EQ);
2438 __ SmiTag(result); 2441 __ SmiTag(result);
2439 break; 2442 break;
2440 } 2443 }
2441 case Token::kMOD: { 2444 case Token::kMOD: {
2442 // Handle divide by zero in runtime. 2445 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
2443 __ cmp(right, ShifterOperand(0)); 2446 // Handle divide by zero in runtime.
2444 __ b(deopt, EQ); 2447 __ cmp(right, ShifterOperand(0));
2448 __ b(deopt, EQ);
2449 }
2445 Register temp = locs()->temp(0).reg(); 2450 Register temp = locs()->temp(0).reg();
2446 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 2451 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
2447 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2452 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2448 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2453 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2449 2454
2450 __ IntegerDivide(result, temp, IP, dtemp, DTMP); 2455 __ IntegerDivide(result, temp, IP, dtemp, DTMP);
2451 2456
2452 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2457 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2453 __ mls(result, IP, result, temp); // result <- left - right * result 2458 __ mls(result, IP, result, temp); // result <- left - right * result
2454 __ SmiTag(result); 2459 __ SmiTag(result);
(...skipping 16 matching lines...) Expand all
2471 break; 2476 break;
2472 } 2477 }
2473 case Token::kSHR: { 2478 case Token::kSHR: {
2474 if (CanDeoptimize()) { 2479 if (CanDeoptimize()) {
2475 __ CompareImmediate(right, 0); 2480 __ CompareImmediate(right, 0);
2476 __ b(deopt, LT); 2481 __ b(deopt, LT);
2477 } 2482 }
2478 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2483 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2479 // sarl operation masks the count to 5 bits. 2484 // sarl operation masks the count to 5 bits.
2480 const intptr_t kCountLimit = 0x1F; 2485 const intptr_t kCountLimit = 0x1F;
2481 Range* right_range = this->right()->definition()->range();
2482 if ((right_range == NULL) || 2486 if ((right_range == NULL) ||
2483 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 2487 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2484 __ CompareImmediate(IP, kCountLimit); 2488 __ CompareImmediate(IP, kCountLimit);
2485 __ LoadImmediate(IP, kCountLimit, GT); 2489 __ LoadImmediate(IP, kCountLimit, GT);
2486 } 2490 }
2487 Register temp = locs()->temp(0).reg(); 2491 Register temp = locs()->temp(0).reg();
2488 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2492 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2489 __ Asr(result, temp, IP); 2493 __ Asr(result, temp, IP);
2490 __ SmiTag(result); 2494 __ SmiTag(result);
2491 break; 2495 break;
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 4085
4082 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4086 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4083 Label* deopt = NULL; 4087 Label* deopt = NULL;
4084 if (CanDeoptimize()) { 4088 if (CanDeoptimize()) {
4085 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4089 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4086 } 4090 }
4087 if (kind() == MergedMathInstr::kTruncDivMod) { 4091 if (kind() == MergedMathInstr::kTruncDivMod) {
4088 Register left = locs()->in(0).reg(); 4092 Register left = locs()->in(0).reg();
4089 Register right = locs()->in(1).reg(); 4093 Register right = locs()->in(1).reg();
4090 Register result = locs()->out().reg(); 4094 Register result = locs()->out().reg();
4091 // Handle divide by zero in runtime. 4095 Range* right_range = InputAt(1)->definition()->range();
4092 __ cmp(right, ShifterOperand(0)); 4096 if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
4093 __ b(deopt, EQ); 4097 // Handle divide by zero in runtime.
4098 __ cmp(right, ShifterOperand(0));
4099 __ b(deopt, EQ);
4100 }
4094 Register temp = locs()->temp(0).reg(); 4101 Register temp = locs()->temp(0).reg();
4095 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 4102 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
4096 Register result_div = locs()->temp(2).reg(); 4103 Register result_div = locs()->temp(2).reg();
4097 Register result_mod = locs()->temp(3).reg(); 4104 Register result_mod = locs()->temp(3).reg();
4098 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 4105 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
4099 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 4106 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
4100 4107
4101 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); 4108 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP);
4102 4109
4103 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 4110 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
4620 compiler->GenerateCall(token_pos(), 4627 compiler->GenerateCall(token_pos(),
4621 &label, 4628 &label,
4622 PcDescriptors::kOther, 4629 PcDescriptors::kOther,
4623 locs()); 4630 locs());
4624 __ Drop(2); // Discard type arguments and receiver. 4631 __ Drop(2); // Discard type arguments and receiver.
4625 } 4632 }
4626 4633
4627 } // namespace dart 4634 } // namespace dart
4628 4635
4629 #endif // defined TARGET_ARCH_ARM 4636 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698