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

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

Issue 10968059: Support for unboxed 64-bit integer bitwise operations and equality on ia32. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments, added tests and flags 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
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/flow_graph_compiler.h"
10 #include "vm/hash_map.h" 11 #include "vm/hash_map.h"
11 #include "vm/il_printer.h" 12 #include "vm/il_printer.h"
12 #include "vm/intermediate_language.h" 13 #include "vm/intermediate_language.h"
13 #include "vm/object_store.h" 14 #include "vm/object_store.h"
14 #include "vm/parser.h" 15 #include "vm/parser.h"
15 #include "vm/scopes.h" 16 #include "vm/scopes.h"
16 #include "vm/symbols.h" 17 #include "vm/symbols.h"
17 18
18 namespace dart { 19 namespace dart {
19 20
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } 77 }
77 } 78 }
78 } 79 }
79 } 80 }
80 81
81 82
82 static Definition* CreateConversion(Representation from, 83 static Definition* CreateConversion(Representation from,
83 Representation to, 84 Representation to,
84 Definition* def, 85 Definition* def,
85 Instruction* deopt_target) { 86 Instruction* deopt_target) {
86 if ((from == kUnboxedDouble) && (to == kTagged)) { 87 if ((from == kTagged) && (to == kUnboxedInteger)) {
88 const intptr_t deopt_id = (deopt_target != NULL) ?
89 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
90 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
91 return new UnboxIntegerInstr(new Value(def), deopt_id);
92 } else if ((from == kUnboxedInteger) && (to == kTagged)) {
93 return new BoxIntegerInstr(new Value(def));
94 } else if ((from == kUnboxedDouble) && (to == kTagged)) {
87 return new BoxDoubleInstr(new Value(def), NULL); 95 return new BoxDoubleInstr(new Value(def), NULL);
88 } else if ((from == kTagged) && (to == kUnboxedDouble)) { 96 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
89 const intptr_t deopt_id = (deopt_target != NULL) ? 97 const intptr_t deopt_id = (deopt_target != NULL) ?
90 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 98 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
91 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); 99 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
92 return new UnboxDoubleInstr(new Value(def), deopt_id); 100 return new UnboxDoubleInstr(new Value(def), deopt_id);
93 } else { 101 } else {
94 UNREACHABLE(); 102 UNREACHABLE();
95 return NULL; 103 return NULL;
96 } 104 }
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 if (ShouldSpecializeForDouble(ic_data)) { 472 if (ShouldSpecializeForDouble(ic_data)) {
465 operands_type = kDoubleCid; 473 operands_type = kDoubleCid;
466 } else { 474 } else {
467 return false; 475 return false;
468 } 476 }
469 break; 477 break;
470 case Token::kMOD: 478 case Token::kMOD:
471 // TODO(vegorov): implement fast path code for modulo. 479 // TODO(vegorov): implement fast path code for modulo.
472 return false; 480 return false;
473 case Token::kBIT_AND: 481 case Token::kBIT_AND:
482 case Token::kBIT_OR:
483 case Token::kBIT_XOR:
474 if (HasOnlyTwoSmi(ic_data)) { 484 if (HasOnlyTwoSmi(ic_data)) {
475 operands_type = kSmiCid; 485 operands_type = kSmiCid;
476 } else if (HasTwoMintOrSmi(ic_data)) { 486 } else if (HasTwoMintOrSmi(ic_data) &&
487 FlowGraphCompiler::SupportsUnboxedMints()) {
477 operands_type = kMintCid; 488 operands_type = kMintCid;
478 } else { 489 } else {
479 return false; 490 return false;
480 } 491 }
481 break; 492 break;
482 case Token::kBIT_OR:
483 case Token::kBIT_XOR:
484 case Token::kTRUNCDIV: 493 case Token::kTRUNCDIV:
485 case Token::kSHR: 494 case Token::kSHR:
486 case Token::kSHL: 495 case Token::kSHL:
487 if (HasOnlyTwoSmi(ic_data)) { 496 if (HasOnlyTwoSmi(ic_data)) {
488 operands_type = kSmiCid; 497 operands_type = kSmiCid;
489 } else { 498 } else {
490 return false; 499 return false;
491 } 500 }
492 break; 501 break;
493 default: 502 default:
(...skipping 17 matching lines...) Expand all
511 UnboxedDoubleBinaryOpInstr* double_bin_op = 520 UnboxedDoubleBinaryOpInstr* double_bin_op =
512 new UnboxedDoubleBinaryOpInstr(op_kind, 521 new UnboxedDoubleBinaryOpInstr(op_kind,
513 left->Copy(), 522 left->Copy(),
514 right->Copy(), 523 right->Copy(),
515 call); 524 call);
516 call->ReplaceWith(double_bin_op, current_iterator()); 525 call->ReplaceWith(double_bin_op, current_iterator());
517 RemovePushArguments(call); 526 RemovePushArguments(call);
518 } else if (operands_type == kMintCid) { 527 } else if (operands_type == kMintCid) {
519 Value* left = call->ArgumentAt(0)->value(); 528 Value* left = call->ArgumentAt(0)->value();
520 Value* right = call->ArgumentAt(1)->value(); 529 Value* right = call->ArgumentAt(1)->value();
521 BinaryMintOpInstr* bin_op = new BinaryMintOpInstr(op_kind, 530 UnboxedMintBinaryOpInstr* bin_op =
522 call, 531 new UnboxedMintBinaryOpInstr(op_kind, left, right, call);
523 left,
524 right);
525 call->ReplaceWith(bin_op, current_iterator()); 532 call->ReplaceWith(bin_op, current_iterator());
526 RemovePushArguments(call); 533 RemovePushArguments(call);
527 } else { 534 } else {
528 ASSERT(operands_type == kSmiCid); 535 ASSERT(operands_type == kSmiCid);
529 Value* left = call->ArgumentAt(0)->value(); 536 Value* left = call->ArgumentAt(0)->value();
530 Value* right = call->ArgumentAt(1)->value(); 537 Value* right = call->ArgumentAt(1)->value();
531 // Insert two smi checks and attach a copy of the original 538 // Insert two smi checks and attach a copy of the original
532 // environment because the smi operation can still deoptimize. 539 // environment because the smi operation can still deoptimize.
533 InsertBefore(call, 540 InsertBefore(call,
534 new CheckSmiInstr(left->Copy(), call->deopt_id()), 541 new CheckSmiInstr(left->Copy(), call->deopt_id()),
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 new StrictCompareInstr(strict_kind, comp->left(), comp->right()); 971 new StrictCompareInstr(strict_kind, comp->left(), comp->right());
965 instr->ReplaceWith(strict_comp, iterator); 972 instr->ReplaceWith(strict_comp, iterator);
966 return; 973 return;
967 } 974 }
968 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return; 975 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return;
969 if (comp->ic_data()->NumberOfChecks() == 1) { 976 if (comp->ic_data()->NumberOfChecks() == 1) {
970 ASSERT(comp->ic_data()->num_args_tested() == 2); 977 ASSERT(comp->ic_data()->num_args_tested() == 2);
971 GrowableArray<intptr_t> class_ids; 978 GrowableArray<intptr_t> class_ids;
972 Function& target = Function::Handle(); 979 Function& target = Function::Handle();
973 comp->ic_data()->GetCheckAt(0, &class_ids, &target); 980 comp->ic_data()->GetCheckAt(0, &class_ids, &target);
974 // TODO(srdjan): allow for mixed mode comparison. 981 // TODO(srdjan): allow for mixed mode int/double comparison.
982
975 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { 983 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
976 optimizer->InsertBefore( 984 optimizer->InsertBefore(
977 instr, 985 instr,
978 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()), 986 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
979 instr->env(), 987 instr->env(),
980 Definition::kEffect); 988 Definition::kEffect);
981 optimizer->InsertBefore( 989 optimizer->InsertBefore(
982 instr, 990 instr,
983 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()), 991 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
984 instr->env(), 992 instr->env(),
985 Definition::kEffect); 993 Definition::kEffect);
986 comp->set_receiver_class_id(kSmiCid); 994 comp->set_receiver_class_id(kSmiCid);
987 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) { 995 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) {
988 comp->set_receiver_class_id(kDoubleCid); 996 comp->set_receiver_class_id(kDoubleCid);
997 } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
998 FlowGraphCompiler::SupportsUnboxedMints()) {
999 comp->set_receiver_class_id(kMintCid);
989 } else { 1000 } else {
990 ASSERT(comp->receiver_class_id() == kIllegalCid); 1001 ASSERT(comp->receiver_class_id() == kIllegalCid);
991 } 1002 }
1003 } else if (HasTwoMintOrSmi(*comp->ic_data())) {
1004 comp->set_receiver_class_id(kMintCid);
992 } else if (comp->ic_data()->AllReceiversAreNumbers()) { 1005 } else if (comp->ic_data()->AllReceiversAreNumbers()) {
993 comp->set_receiver_class_id(kNumberCid); 1006 comp->set_receiver_class_id(kNumberCid);
994 } 1007 }
995 } 1008 }
996 1009
997 1010
998 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) { 1011 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
999 HandleEqualityCompare(this, instr, instr, current_iterator()); 1012 HandleEqualityCompare(this, instr, instr, current_iterator());
1000 } 1013 }
1001 1014
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
2776 SetValue(instr, non_constant_); 2789 SetValue(instr, non_constant_);
2777 } 2790 }
2778 } else { 2791 } else {
2779 // TODO(kmillikin): support other types. 2792 // TODO(kmillikin): support other types.
2780 SetValue(instr, non_constant_); 2793 SetValue(instr, non_constant_);
2781 } 2794 }
2782 } 2795 }
2783 } 2796 }
2784 2797
2785 2798
2799 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
2800 // TODO(kmillikin): Handle box operation.
2801 SetValue(instr, non_constant_);
2802 }
2803
2804
2805 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
2806 // TODO(kmillikin): Handle unbox operation.
2807 SetValue(instr, non_constant_);
2808 }
2809
2810
2811 void ConstantPropagator::VisitUnboxedMintBinaryOp(
2812 UnboxedMintBinaryOpInstr* instr) {
2813 // TODO(kmillikin): Handle binary operations.
2814 SetValue(instr, non_constant_);
2815 }
2816
2817
2786 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) { 2818 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
2787 const Object& left = instr->left()->definition()->constant_value(); 2819 const Object& left = instr->left()->definition()->constant_value();
2788 const Object& right = instr->right()->definition()->constant_value(); 2820 const Object& right = instr->right()->definition()->constant_value();
2789 if (IsNonConstant(left) || IsNonConstant(right)) { 2821 if (IsNonConstant(left) || IsNonConstant(right)) {
2790 SetValue(instr, non_constant_); 2822 SetValue(instr, non_constant_);
2791 } else if (IsConstant(left) && IsConstant(right)) { 2823 } else if (IsConstant(left) && IsConstant(right)) {
2792 // TODO(kmillikin): Handle binary operations. 2824 // TODO(kmillikin): Handle binary operations.
2793 SetValue(instr, non_constant_); 2825 SetValue(instr, non_constant_);
2794 } 2826 }
2795 } 2827 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3031 3063
3032 if (FLAG_trace_constant_propagation) { 3064 if (FLAG_trace_constant_propagation) {
3033 OS::Print("\n==== After constant propagation ====\n"); 3065 OS::Print("\n==== After constant propagation ====\n");
3034 FlowGraphPrinter printer(*graph_); 3066 FlowGraphPrinter printer(*graph_);
3035 printer.PrintBlocks(); 3067 printer.PrintBlocks();
3036 } 3068 }
3037 } 3069 }
3038 3070
3039 3071
3040 } // namespace dart 3072 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698