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

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

Issue 330263002: Eliminate overflow check for non-overflowing smi << operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 case Token::kBIT_OR: 1231 case Token::kBIT_OR:
1232 case Token::kBIT_XOR: 1232 case Token::kBIT_XOR:
1233 return false; 1233 return false;
1234 case Token::kSHR: { 1234 case Token::kSHR: {
1235 // Can't deopt if shift-count is known positive. 1235 // Can't deopt if shift-count is known positive.
1236 Range* right_range = this->right()->definition()->range(); 1236 Range* right_range = this->right()->definition()->range();
1237 return (right_range == NULL) || !right_range->IsPositive(); 1237 return (right_range == NULL) || !right_range->IsPositive();
1238 } 1238 }
1239 case Token::kSHL: { 1239 case Token::kSHL: {
1240 Range* right_range = this->right()->definition()->range(); 1240 Range* right_range = this->right()->definition()->range();
1241 if ((right_range != NULL) && is_truncating()) { 1241 if ((right_range != NULL) && IsTruncating()) {
1242 // Can deoptimize if right can be negative. 1242 // Can deoptimize if right can be negative.
1243 return !right_range->IsPositive(); 1243 return !right_range->IsPositive();
1244 } 1244 }
1245 return true; 1245 return true;
1246 } 1246 }
1247 case Token::kMOD: { 1247 case Token::kMOD: {
1248 Range* right_range = this->right()->definition()->range(); 1248 Range* right_range = this->right()->definition()->range();
1249 return (right_range == NULL) || right_range->Overlaps(0, 0); 1249 return (right_range == NULL) || right_range->Overlaps(0, 0);
1250 } 1250 }
1251 default: 1251 default:
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 // Nothing new. 3200 // Nothing new.
3201 return; 3201 return;
3202 } 3202 }
3203 3203
3204 range_ = possible_range; 3204 range_ = possible_range;
3205 3205
3206 ASSERT(!range_->min().IsUnknown() && !range_->max().IsUnknown()); 3206 ASSERT(!range_->min().IsUnknown() && !range_->max().IsUnknown());
3207 // Calculate overflowed status before clamping. 3207 // Calculate overflowed status before clamping.
3208 const bool overflowed = range_->min().LowerBound().OverflowedSmi() || 3208 const bool overflowed = range_->min().LowerBound().OverflowedSmi() ||
3209 range_->max().UpperBound().OverflowedSmi(); 3209 range_->max().UpperBound().OverflowedSmi();
3210
3211 // Clamp value to be within smi range. 3210 // Clamp value to be within smi range.
3212 range_->Clamp(RangeBoundary::kRangeBoundarySmi); 3211 range_->Clamp(RangeBoundary::kRangeBoundarySmi);
3213 3212
3214 set_overflow(overflowed); 3213 set_overflow(overflowed);
3215 } 3214 }
3216 3215
3217 3216
3218 void BinaryMintOpInstr::InferRange() { 3217 void BinaryMintOpInstr::InferRange() {
3219 // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on 3218 // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on
3220 // the right and a non-constant on the left. 3219 // the right and a non-constant on the left.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
3369 3368
3370 *result_max = RangeBoundary::Shl( 3369 *result_max = RangeBoundary::Shl(
3371 left_max, 3370 left_max,
3372 left_max.ConstantValue() > 0 ? right_max : right_min, 3371 left_max.ConstantValue() > 0 ? right_max : right_min,
3373 left_max.ConstantValue() > 0 3372 left_max.ConstantValue() > 0
3374 ? RangeBoundary::PositiveInfinity() 3373 ? RangeBoundary::PositiveInfinity()
3375 : RangeBoundary::NegativeInfinity()); 3374 : RangeBoundary::NegativeInfinity());
3376 } 3375 }
3377 3376
3378 3377
3378 void Range::Shr(const Range* left,
3379 const Range* right,
3380 RangeBoundary* result_min,
3381 RangeBoundary* result_max) {
3382 RangeBoundary left_max = Range::ConstantMax(left);
3383 RangeBoundary left_min = Range::ConstantMin(left);
3384 // A negative shift count always deoptimizes (and throws), so the minimum
3385 // shift count is zero.
3386 int64_t right_max = Utils::Maximum(Range::ConstantMax(right).ConstantValue(),
3387 static_cast<int64_t>(0));
3388 int64_t right_min = Utils::Maximum(Range::ConstantMin(right).ConstantValue(),
3389 static_cast<int64_t>(0));
3390
3391 *result_min = RangeBoundary::Shr(
3392 left_min,
3393 left_min.ConstantValue() > 0 ? right_max : right_min);
3394
3395 *result_max = RangeBoundary::Shr(
3396 left_max,
3397 left_max.ConstantValue() > 0 ? right_min : right_max);
3398 }
3399
3400
3379 bool Range::And(const Range* left_range, 3401 bool Range::And(const Range* left_range,
3380 const Range* right_range, 3402 const Range* right_range,
3381 RangeBoundary* result_min, 3403 RangeBoundary* result_min,
3382 RangeBoundary* result_max) { 3404 RangeBoundary* result_max) {
3383 ASSERT(left_range != NULL); 3405 ASSERT(left_range != NULL);
3384 ASSERT(right_range != NULL); 3406 ASSERT(right_range != NULL);
3385 ASSERT(result_min != NULL); 3407 ASSERT(result_min != NULL);
3386 ASSERT(result_max != NULL); 3408 ASSERT(result_max != NULL);
3387 3409
3388 if (Range::ConstantMin(right_range).ConstantValue() >= 0) { 3410 if (Range::ConstantMin(right_range).ConstantValue() >= 0) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
3540 case Token::kMUL: { 3562 case Token::kMUL: {
3541 if (!Range::Mul(left_range, right_range, &min, &max)) { 3563 if (!Range::Mul(left_range, right_range, &min, &max)) {
3542 return NULL; 3564 return NULL;
3543 } 3565 }
3544 break; 3566 break;
3545 } 3567 }
3546 case Token::kSHL: { 3568 case Token::kSHL: {
3547 Range::Shl(left_range, right_range, &min, &max); 3569 Range::Shl(left_range, right_range, &min, &max);
3548 break; 3570 break;
3549 } 3571 }
3572 case Token::kSHR: {
3573 Range::Shr(left_range, right_range, &min, &max);
3574 break;
3575 }
3550 case Token::kBIT_AND: 3576 case Token::kBIT_AND:
3551 if (!Range::And(left_range, right_range, &min, &max)) { 3577 if (!Range::And(left_range, right_range, &min, &max)) {
3552 return NULL; 3578 return NULL;
3553 } 3579 }
3554 break; 3580 break;
3555 default: 3581 default:
3556 return NULL; 3582 return NULL;
3557 break; 3583 break;
3558 } 3584 }
3559 3585
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3888 case Token::kTRUNCDIV: return 0; 3914 case Token::kTRUNCDIV: return 0;
3889 case Token::kMOD: return 1; 3915 case Token::kMOD: return 1;
3890 default: UNIMPLEMENTED(); return -1; 3916 default: UNIMPLEMENTED(); return -1;
3891 } 3917 }
3892 } 3918 }
3893 3919
3894 3920
3895 #undef __ 3921 #undef __
3896 3922
3897 } // namespace dart 3923 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698