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

Side by Side 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, 2 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 | « no previous file | tests/language/modulo_test.dart » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/hash_map.h" 10 #include "vm/hash_map.h"
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } 461 }
462 break; 462 break;
463 case Token::kDIV: 463 case Token::kDIV:
464 if (ShouldSpecializeForDouble(ic_data)) { 464 if (ShouldSpecializeForDouble(ic_data)) {
465 operands_type = kDoubleCid; 465 operands_type = kDoubleCid;
466 } else { 466 } else {
467 return false; 467 return false;
468 } 468 }
469 break; 469 break;
470 case Token::kMOD: 470 case Token::kMOD:
471 // TODO(vegorov): implement fast path code for modulo. 471 if (HasOnlyTwoSmi(ic_data)) {
472 return false; 472 operands_type = kSmiCid;
473 } else {
474 return false;
475 }
476 break;
473 case Token::kBIT_AND: 477 case Token::kBIT_AND:
474 if (HasOnlyTwoSmi(ic_data)) { 478 if (HasOnlyTwoSmi(ic_data)) {
475 operands_type = kSmiCid; 479 operands_type = kSmiCid;
476 } else if (HasTwoMintOrSmi(ic_data)) { 480 } else if (HasTwoMintOrSmi(ic_data)) {
477 operands_type = kMintCid; 481 operands_type = kMintCid;
478 } else { 482 } else {
479 return false; 483 return false;
480 } 484 }
481 break; 485 break;
482 case Token::kBIT_OR: 486 case Token::kBIT_OR:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 RemovePushArguments(call); 521 RemovePushArguments(call);
518 } else if (operands_type == kMintCid) { 522 } else if (operands_type == kMintCid) {
519 Value* left = call->ArgumentAt(0)->value(); 523 Value* left = call->ArgumentAt(0)->value();
520 Value* right = call->ArgumentAt(1)->value(); 524 Value* right = call->ArgumentAt(1)->value();
521 BinaryMintOpInstr* bin_op = new BinaryMintOpInstr(op_kind, 525 BinaryMintOpInstr* bin_op = new BinaryMintOpInstr(op_kind,
522 call, 526 call,
523 left, 527 left,
524 right); 528 right);
525 call->ReplaceWith(bin_op, current_iterator()); 529 call->ReplaceWith(bin_op, current_iterator());
526 RemovePushArguments(call); 530 RemovePushArguments(call);
531 } else if (op_kind == Token::kMOD) {
532 // TODO(vegorov): implement fast path code for modulo.
533 ASSERT(operands_type == kSmiCid);
534 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false;
535 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant();
536 if (!obj.IsSmi()) return false;
537 const intptr_t value = Smi::Cast(obj).Value();
538 if ((value > 0) && Utils::IsPowerOfTwo(value)) {
539 Value* left = call->ArgumentAt(0)->value();
540 // Insert smi check and attach a copy of the original
541 // environment because the smi operation can still deoptimize.
542 InsertBefore(call,
543 new CheckSmiInstr(left->Copy(), call->deopt_id()),
544 call->env(),
545 Definition::kEffect);
546 ConstantInstr* c = new ConstantInstr(Smi::Handle(Smi::New(value - 1)));
547 InsertBefore(call, c, NULL, Definition::kValue);
548 BinarySmiOpInstr* bin_op =
549 new BinarySmiOpInstr(Token::kBIT_AND, call, left, new Value(c));
550 call->ReplaceWith(bin_op, current_iterator());
551 RemovePushArguments(call);
552 }
527 } else { 553 } else {
528 ASSERT(operands_type == kSmiCid); 554 ASSERT(operands_type == kSmiCid);
529 Value* left = call->ArgumentAt(0)->value(); 555 Value* left = call->ArgumentAt(0)->value();
530 Value* right = call->ArgumentAt(1)->value(); 556 Value* right = call->ArgumentAt(1)->value();
531 // Insert two smi checks and attach a copy of the original 557 // Insert two smi checks and attach a copy of the original
532 // environment because the smi operation can still deoptimize. 558 // environment because the smi operation can still deoptimize.
533 InsertBefore(call, 559 InsertBefore(call,
534 new CheckSmiInstr(left->Copy(), call->deopt_id()), 560 new CheckSmiInstr(left->Copy(), call->deopt_id()),
535 call->env(), 561 call->env(),
536 Definition::kEffect); 562 Definition::kEffect);
(...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after
3091 3117
3092 if (FLAG_trace_constant_propagation) { 3118 if (FLAG_trace_constant_propagation) {
3093 OS::Print("\n==== After constant propagation ====\n"); 3119 OS::Print("\n==== After constant propagation ====\n");
3094 FlowGraphPrinter printer(*graph_); 3120 FlowGraphPrinter printer(*graph_);
3095 printer.PrintBlocks(); 3121 printer.PrintBlocks();
3096 } 3122 }
3097 } 3123 }
3098 3124
3099 3125
3100 } // namespace dart 3126 } // namespace dart
OLDNEW
« 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