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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10982095: Convert MOD to AND for power-of-two positive constants. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
« no previous file with comments | « no previous file | tests/language/modulo_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 13037)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -468,8 +468,12 @@
}
break;
case Token::kMOD:
- // TODO(vegorov): implement fast path code for modulo.
- return false;
+ if (HasOnlyTwoSmi(ic_data)) {
+ operands_type = kSmiCid;
+ } else {
+ return false;
+ }
+ break;
case Token::kBIT_AND:
if (HasOnlyTwoSmi(ic_data)) {
operands_type = kSmiCid;
@@ -524,6 +528,28 @@
right);
call->ReplaceWith(bin_op, current_iterator());
RemovePushArguments(call);
+ } else if (op_kind == Token::kMOD) {
+ // TODO(vegorov): implement fast path code for modulo.
+ ASSERT(operands_type == kSmiCid);
+ if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false;
+ const Object& obj = call->ArgumentAt(1)->value()->BoundConstant();
+ if (!obj.IsSmi()) return false;
+ const intptr_t value = Smi::Cast(obj).Value();
+ if ((value > 0) && Utils::IsPowerOfTwo(value)) {
+ Value* left = call->ArgumentAt(0)->value();
+ // Insert smi check and attach a copy of the original
+ // environment because the smi operation can still deoptimize.
+ InsertBefore(call,
+ new CheckSmiInstr(left->Copy(), call->deopt_id()),
+ call->env(),
+ Definition::kEffect);
+ ConstantInstr* c = new ConstantInstr(Smi::Handle(Smi::New(value - 1)));
+ InsertBefore(call, c, NULL, Definition::kValue);
+ BinarySmiOpInstr* bin_op =
+ new BinarySmiOpInstr(Token::kBIT_AND, call, left, new Value(c));
+ call->ReplaceWith(bin_op, current_iterator());
+ RemovePushArguments(call);
+ }
} else {
ASSERT(operands_type == kSmiCid);
Value* left = call->ArgumentAt(0)->value();
« no previous file with comments | « no previous file | tests/language/modulo_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698