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

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
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 2362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 } 2373 }
2374 2374
2375 default: 2375 default:
2376 UNREACHABLE(); 2376 UNREACHABLE();
2377 break; 2377 break;
2378 } 2378 }
2379 return; 2379 return;
2380 } 2380 }
2381 2381
2382 Register right = locs()->in(1).reg(); 2382 Register right = locs()->in(1).reg();
2383 Range* right_range = this->right()->definition()->range();
2383 switch (op_kind()) { 2384 switch (op_kind()) {
2384 case Token::kADD: { 2385 case Token::kADD: {
2385 if (deopt == NULL) { 2386 if (deopt == NULL) {
2386 __ add(result, left, ShifterOperand(right)); 2387 __ add(result, left, ShifterOperand(right));
2387 } else { 2388 } else {
2388 __ adds(result, left, ShifterOperand(right)); 2389 __ adds(result, left, ShifterOperand(right));
2389 __ b(deopt, VS); 2390 __ b(deopt, VS);
2390 } 2391 }
2391 break; 2392 break;
2392 } 2393 }
(...skipping 27 matching lines...) Expand all
2420 // No overflow check. 2421 // No overflow check.
2421 __ orr(result, left, ShifterOperand(right)); 2422 __ orr(result, left, ShifterOperand(right));
2422 break; 2423 break;
2423 } 2424 }
2424 case Token::kBIT_XOR: { 2425 case Token::kBIT_XOR: {
2425 // No overflow check. 2426 // No overflow check.
2426 __ eor(result, left, ShifterOperand(right)); 2427 __ eor(result, left, ShifterOperand(right));
2427 break; 2428 break;
2428 } 2429 }
2429 case Token::kTRUNCDIV: { 2430 case Token::kTRUNCDIV: {
2430 // Handle divide by zero in runtime. 2431 if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
2431 __ cmp(right, ShifterOperand(0)); 2432 // Handle divide by zero in runtime.
2432 __ b(deopt, EQ); 2433 __ cmp(right, ShifterOperand(0));
2434 __ b(deopt, EQ);
2435 }
2433 Register temp = locs()->temp(0).reg(); 2436 Register temp = locs()->temp(0).reg();
2434 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 2437 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
2435 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2438 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2436 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2439 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2437 2440
2438 __ IntegerDivide(result, temp, IP, dtemp, DTMP); 2441 __ IntegerDivide(result, temp, IP, dtemp, DTMP);
2439 2442
2440 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 2443 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
2441 // case we cannot tag the result. 2444 // case we cannot tag the result.
2442 __ CompareImmediate(result, 0x40000000); 2445 __ CompareImmediate(result, 0x40000000);
2443 __ b(deopt, EQ); 2446 __ b(deopt, EQ);
2444 __ SmiTag(result); 2447 __ SmiTag(result);
2445 break; 2448 break;
2446 } 2449 }
2447 case Token::kMOD: { 2450 case Token::kMOD: {
2448 // Handle divide by zero in runtime. 2451 if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
2449 __ cmp(right, ShifterOperand(0)); 2452 // Handle divide by zero in runtime.
2450 __ b(deopt, EQ); 2453 __ cmp(right, ShifterOperand(0));
2454 __ b(deopt, EQ);
2455 }
2451 Register temp = locs()->temp(0).reg(); 2456 Register temp = locs()->temp(0).reg();
2452 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 2457 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
2453 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2458 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2454 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2459 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2455 2460
2456 __ IntegerDivide(result, temp, IP, dtemp, DTMP); 2461 __ IntegerDivide(result, temp, IP, dtemp, DTMP);
2457 2462
2458 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2463 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2459 __ mls(result, IP, result, temp); // result <- left - right * result 2464 __ mls(result, IP, result, temp); // result <- left - right * result
2460 __ SmiTag(result); 2465 __ SmiTag(result);
(...skipping 16 matching lines...) Expand all
2477 break; 2482 break;
2478 } 2483 }
2479 case Token::kSHR: { 2484 case Token::kSHR: {
2480 if (CanDeoptimize()) { 2485 if (CanDeoptimize()) {
2481 __ CompareImmediate(right, 0); 2486 __ CompareImmediate(right, 0);
2482 __ b(deopt, LT); 2487 __ b(deopt, LT);
2483 } 2488 }
2484 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 2489 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
2485 // sarl operation masks the count to 5 bits. 2490 // sarl operation masks the count to 5 bits.
2486 const intptr_t kCountLimit = 0x1F; 2491 const intptr_t kCountLimit = 0x1F;
2487 Range* right_range = this->right()->definition()->range();
2488 if ((right_range == NULL) || 2492 if ((right_range == NULL) ||
2489 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) { 2493 !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
2490 __ CompareImmediate(IP, kCountLimit); 2494 __ CompareImmediate(IP, kCountLimit);
2491 __ LoadImmediate(IP, kCountLimit, GT); 2495 __ LoadImmediate(IP, kCountLimit, GT);
2492 } 2496 }
2493 Register temp = locs()->temp(0).reg(); 2497 Register temp = locs()->temp(0).reg();
2494 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 2498 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
2495 __ Asr(result, temp, IP); 2499 __ Asr(result, temp, IP);
2496 __ SmiTag(result); 2500 __ SmiTag(result);
2497 break; 2501 break;
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after
4087 4091
4088 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4092 void MergedMathInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4089 Label* deopt = NULL; 4093 Label* deopt = NULL;
4090 if (CanDeoptimize()) { 4094 if (CanDeoptimize()) {
4091 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp); 4095 deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
4092 } 4096 }
4093 if (kind() == MergedMathInstr::kTruncDivMod) { 4097 if (kind() == MergedMathInstr::kTruncDivMod) {
4094 Register left = locs()->in(0).reg(); 4098 Register left = locs()->in(0).reg();
4095 Register right = locs()->in(1).reg(); 4099 Register right = locs()->in(1).reg();
4096 Register result = locs()->out().reg(); 4100 Register result = locs()->out().reg();
4097 // Handle divide by zero in runtime. 4101 Range* right_range = InputAt(1)->definition()->range();
4098 __ cmp(right, ShifterOperand(0)); 4102 if ((right_range == NULL) || right_range->IsWithin(0, 0)) {
4099 __ b(deopt, EQ); 4103 // Handle divide by zero in runtime.
4104 __ cmp(right, ShifterOperand(0));
4105 __ b(deopt, EQ);
4106 }
4100 Register temp = locs()->temp(0).reg(); 4107 Register temp = locs()->temp(0).reg();
4101 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg()); 4108 DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
4102 Register result_div = locs()->temp(2).reg(); 4109 Register result_div = locs()->temp(2).reg();
4103 Register result_mod = locs()->temp(3).reg(); 4110 Register result_mod = locs()->temp(3).reg();
4104 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp. 4111 __ Asr(temp, left, kSmiTagSize); // SmiUntag left into temp.
4105 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP. 4112 __ Asr(IP, right, kSmiTagSize); // SmiUntag right into IP.
4106 4113
4107 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP); 4114 __ IntegerDivide(result_div, temp, IP, dtemp, DTMP);
4108 4115
4109 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 4116 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
4629 compiler->GenerateCall(token_pos(), 4636 compiler->GenerateCall(token_pos(),
4630 &label, 4637 &label,
4631 PcDescriptors::kOther, 4638 PcDescriptors::kOther,
4632 locs()); 4639 locs());
4633 __ Drop(2); // Discard type arguments and receiver. 4640 __ Drop(2); // Discard type arguments and receiver.
4634 } 4641 }
4635 4642
4636 } // namespace dart 4643 } // namespace dart
4637 4644
4638 #endif // defined TARGET_ARCH_ARM 4645 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_ia32.cc » ('j') | runtime/vm/intermediate_language_ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698