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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 11363141: Improve smi shift operations and avoid repeated deoptimizations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 14704)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -1732,15 +1732,13 @@
summary->set_out(Location::SameAsFirstInput());
return summary;
} else if (op_kind() == Token::kSHL) {
- // Two Smi operands can easily overflow into Mint.
- const intptr_t kNumTemps = 2;
+ const intptr_t kNumTemps = 1;
LocationSummary* summary =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- summary->set_in(0, Location::RegisterLocation(EAX));
- summary->set_in(1, Location::RegisterLocation(EDX));
- summary->set_temp(0, Location::RegisterLocation(EBX));
- summary->set_temp(1, Location::RegisterLocation(ECX));
- summary->set_out(Location::RegisterLocation(EAX));
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::FixedRegisterOrConstant(right(), ECX));
+ summary->set_temp(0, Location::RequiresRegister());
+ summary->set_out(Location::SameAsFirstInput());
return summary;
} else {
const intptr_t kNumTemps = 0;
@@ -1822,6 +1820,27 @@
__ SmiTag(left);
break;
}
+ case Token::kSHL: {
+ // shll operation masks the count to 5 bits.
+ const intptr_t kCountLimit = 0x1F;
+ intptr_t value = Smi::Cast(constant).Value();
+ if (value == 0) break;
+ if ((value < 0) || (value >= kCountLimit)) {
+ // This condition may not be known earlier in some cases because
+ // of constant propagation, inlining, etc.
+ __ jmp(deopt);
+ break;
+ }
+ Register temp = locs()->temp(0).reg();
+ __ movl(temp, left);
+ __ shll(left, Immediate(value));
+ __ sarl(left, Immediate(value));
+ __ cmpl(left, temp);
+ __ j(NOT_EQUAL, deopt); // Overflow.
+ // Shift for result now we know there is no overflow.
+ __ shll(left, Immediate(value));
+ break;
+ }
default:
UNREACHABLE();
@@ -1906,7 +1925,6 @@
}
case Token::kSHL: {
Register temp = locs()->temp(0).reg();
- Label call_method, done;
// Check if count too large for handling it inlined.
__ movl(temp, left);
Range* right_range = this->right()->definition()->range();
@@ -1915,38 +1933,17 @@
if (right_needs_check) {
__ cmpl(right,
Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
- __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
+ __ j(ABOVE_EQUAL, deopt);
}
- Register right_temp = locs()->temp(1).reg();
- ASSERT(right_temp == ECX); // Count must be in ECX
- __ movl(right_temp, right);
- __ SmiUntag(right_temp);
+ ASSERT(right == ECX); // Count must be in ECX
+ __ SmiUntag(right);
// Overflow test (preserve temp and right);
- __ shll(left, right_temp);
- __ sarl(left, right_temp);
+ __ shll(left, right);
+ __ sarl(left, right);
__ cmpl(left, temp);
- __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
+ __ j(NOT_EQUAL, deopt); // Overflow.
// Shift for result now we know there is no overflow.
- __ shll(left, right_temp);
- __ jmp(&done);
- {
- __ Bind(&call_method);
- Function& target = Function::ZoneHandle(
- ic_data()->GetTargetForReceiverClassId(kSmiCid));
- ASSERT(!target.IsNull());
- const intptr_t kArgumentCount = 2;
- __ pushl(temp);
- __ pushl(right);
- compiler->GenerateStaticCall(
- deopt_id(),
- instance_call()->token_pos(),
- target,
- kArgumentCount,
- Array::Handle(), // No argument names.
- locs());
- ASSERT(result == EAX);
- }
- __ Bind(&done);
+ __ shll(left, right);
break;
}
case Token::kDIV: {
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698