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

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 564843002: Initial steps towards cleaning up integer arithmetic IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language_x64.cc
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index dc2cd69f20148e0cc209ae22a15f0ef1f195471b..6c904558cebaca95589fec80ba53028959a8a5fd 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2542,7 +2542,6 @@ static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler,
static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
BinarySmiOpInstr* shift_left) {
- const bool is_truncating = shift_left->IsTruncating();
const LocationSummary& locs = *shift_left->locs();
Register left = locs.in(0).reg();
Register result = locs.out(0).reg();
@@ -2556,30 +2555,18 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
// shlq operation masks the count to 6 bits.
const intptr_t kCountLimit = 0x3F;
const intptr_t value = Smi::Cast(constant).Value();
- if (value == 0) {
- // No code needed.
- } else if ((value < 0) || (value >= kCountLimit)) {
- // This condition may not be known earlier in some cases because
- // of constant propagation, inlining, etc.
- if ((value >= kCountLimit) && is_truncating) {
- __ xorq(result, result);
- } else {
- // Result is Mint or exception.
- __ jmp(deopt);
- }
- } else {
- if (!is_truncating) {
- // Check for overflow.
- Register temp = locs.temp(0).reg();
- __ movq(temp, left);
- __ shlq(left, Immediate(value));
- __ sarq(left, Immediate(value));
- __ cmpq(left, temp);
- __ j(NOT_EQUAL, deopt); // Overflow.
- }
- // Shift for result now we know there is no overflow.
+ ASSERT((0 < value) && (value < kCountLimit));
+ if (shift_left->can_overflow()) {
+ // Check for overflow.
+ Register temp = locs.temp(0).reg();
+ __ movq(temp, left);
__ shlq(left, Immediate(value));
+ __ sarq(left, Immediate(value));
+ __ cmpq(left, temp);
+ __ j(NOT_EQUAL, deopt); // Overflow.
}
+ // Shift for result now we know there is no overflow.
+ __ shlq(left, Immediate(value));
if (FLAG_throw_on_javascript_int_overflow) {
EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
}
@@ -2589,7 +2576,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
// Right (locs.in(1)) is not constant.
Register right = locs.in(1).reg();
Range* right_range = shift_left->right()->definition()->range();
- if (shift_left->left()->BindsToConstant() && !is_truncating) {
+ if (shift_left->left()->BindsToConstant() && shift_left->can_overflow()) {
// TODO(srdjan): Implement code below for is_truncating().
// If left is constant, we know the maximal allowed size for right.
const Object& obj = shift_left->left()->BoundConstant();
@@ -2620,7 +2607,7 @@ static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
const bool right_needs_check =
!RangeUtils::IsWithin(right_range, 0, (Smi::kBits - 1));
ASSERT(right == RCX); // Count must be in RCX
- if (is_truncating) {
+ if (!shift_left->can_overflow()) {
if (right_needs_check) {
const bool right_may_be_negative =
(right_range == NULL) || !right_range->IsPositive();
@@ -2734,12 +2721,12 @@ LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Isolate* isolate,
summary->set_out(0, Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
- const intptr_t kNumTemps = !IsTruncating() ? 1 : 0;
+ const intptr_t kNumTemps = can_overflow() ? 1 : 0;
LocationSummary* summary = new(isolate) LocationSummary(
isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
- if (!IsTruncating()) {
+ if (can_overflow()) {
summary->set_temp(0, Location::RequiresRegister());
}
summary->set_out(0, Location::SameAsFirstInput());
@@ -2780,46 +2767,24 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const int64_t imm = reinterpret_cast<int64_t>(constant.raw());
switch (op_kind()) {
case Token::kADD: {
- if (imm != 0) {
- // Checking overflow without emitting an instruction would be wrong.
- __ AddImmediate(left, Immediate(imm), PP);
- if (deopt != NULL) __ j(OVERFLOW, deopt);
- }
+ __ AddImmediate(left, Immediate(imm), PP);
+ if (deopt != NULL) __ j(OVERFLOW, deopt);
Cutch 2014/09/11 17:41:53 Please use curlies (here and elsewhere): if (deop
break;
}
case Token::kSUB: {
- if (imm != 0) {
- // Checking overflow without emitting an instruction would be wrong.
- __ SubImmediate(left, Immediate(imm), PP);
- if (deopt != NULL) __ j(OVERFLOW, deopt);
- }
+ __ SubImmediate(left, Immediate(imm), PP);
+ if (deopt != NULL) __ j(OVERFLOW, deopt);
break;
}
case Token::kMUL: {
// Keep left value tagged and untag right value.
const intptr_t value = Smi::Cast(constant).Value();
- if (value == 2) {
- __ shlq(left, Immediate(1));
- } else {
- __ MulImmediate(left, Immediate(value), PP);
- }
+ __ MulImmediate(left, Immediate(value), PP);
if (deopt != NULL) __ j(OVERFLOW, deopt);
break;
}
case Token::kTRUNCDIV: {
const intptr_t value = Smi::Cast(constant).Value();
- if (value == 1) {
- // Do nothing.
- break;
- } else if (value == -1) {
- // Check the corner case of dividing the 'MIN_SMI' with -1, in which
- // case we cannot negate the result.
- __ CompareImmediate(left, Immediate(0x8000000000000000), PP);
- __ j(EQUAL, deopt);
- __ negq(left);
- break;
- }
-
ASSERT(Utils::IsPowerOfTwo(Utils::Abs(value)));
const intptr_t shift_count =
Utils::ShiftForPowerOfTwo(Utils::Abs(value)) + kSmiTagSize;
@@ -2857,21 +2822,9 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
case Token::kSHR: {
// sarq operation masks the count to 6 bits.
const intptr_t kCountLimit = 0x3F;
- intptr_t value = Smi::Cast(constant).Value();
-
- if (value == 0) {
- // TODO(vegorov): should be handled outside.
- break;
- } else if (value < 0) {
- // TODO(vegorov): should be handled outside.
- __ jmp(deopt);
- break;
- }
-
- value = value + kSmiTagSize;
- if (value >= kCountLimit) value = kCountLimit;
-
- __ sarq(left, Immediate(value));
+ const intptr_t value = Smi::Cast(constant).Value();
+ __ sarq(left, Immediate(
+ Utils::Minimum(value + kSmiTagSize, kCountLimit)));
__ SmiTag(left);
break;
}

Powered by Google App Engine
This is Rietveld 408576698