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

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: 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 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 } 74 }
74 } 75 }
75 } 76 }
76 } 77 }
77 78
78 79
79 static Definition* CreateConversion(Representation from, 80 static Definition* CreateConversion(Representation from,
80 Representation to, 81 Representation to,
81 Definition* def, 82 Definition* def,
82 Instruction* deopt_target) { 83 Instruction* deopt_target) {
83 if ((from == kUnboxedDouble) && (to == kTagged)) { 84 if (from == kTagged && to == kUnboxedInteger) {
85 const intptr_t deopt_id = (deopt_target != NULL) ?
86 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
87 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
88 return new UnboxIntegerInstr(new Value(def), deopt_id);
89 } else if (from == kUnboxedInteger && to == kTagged) {
90 return new BoxIntegerInstr(new Value(def));
91 } else if ((from == kUnboxedDouble) && (to == kTagged)) {
84 return new BoxDoubleInstr(new Value(def), NULL); 92 return new BoxDoubleInstr(new Value(def), NULL);
85 } else if ((from == kTagged) && (to == kUnboxedDouble)) { 93 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
86 const intptr_t deopt_id = (deopt_target != NULL) ? 94 const intptr_t deopt_id = (deopt_target != NULL) ?
87 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 95 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
88 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); 96 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
89 return new UnboxDoubleInstr(new Value(def), deopt_id); 97 return new UnboxDoubleInstr(new Value(def), deopt_id);
90 } else { 98 } else {
91 UNREACHABLE(); 99 UNREACHABLE();
92 return NULL; 100 return NULL;
93 } 101 }
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 if (ShouldSpecializeForDouble(ic_data)) { 485 if (ShouldSpecializeForDouble(ic_data)) {
478 operands_type = kDoubleCid; 486 operands_type = kDoubleCid;
479 } else { 487 } else {
480 return false; 488 return false;
481 } 489 }
482 break; 490 break;
483 case Token::kMOD: 491 case Token::kMOD:
484 // TODO(vegorov): implement fast path code for modulo. 492 // TODO(vegorov): implement fast path code for modulo.
485 return false; 493 return false;
486 case Token::kBIT_AND: 494 case Token::kBIT_AND:
495 case Token::kBIT_OR:
496 case Token::kBIT_XOR:
487 if (HasOnlyTwoSmi(ic_data)) { 497 if (HasOnlyTwoSmi(ic_data)) {
488 operands_type = kSmiCid; 498 operands_type = kSmiCid;
489 } else if (HasTwoMintOrSmi(ic_data)) { 499 } else if (HasTwoMintOrSmi(ic_data) &&
500 FlowGraphCompiler::SupportsUnboxedMints()) {
490 operands_type = kMintCid; 501 operands_type = kMintCid;
491 } else { 502 } else {
492 return false; 503 return false;
493 } 504 }
494 break; 505 break;
495 case Token::kBIT_OR:
496 case Token::kBIT_XOR:
497 case Token::kTRUNCDIV: 506 case Token::kTRUNCDIV:
507 case Token::kSHL:
498 case Token::kSHR: 508 case Token::kSHR:
499 case Token::kSHL:
500 if (HasOnlyTwoSmi(ic_data)) { 509 if (HasOnlyTwoSmi(ic_data)) {
501 operands_type = kSmiCid; 510 operands_type = kSmiCid;
502 } else { 511 } else {
503 return false; 512 return false;
504 } 513 }
505 break; 514 break;
506 default: 515 default:
507 UNREACHABLE(); 516 UNREACHABLE();
508 }; 517 };
509 518
(...skipping 14 matching lines...) Expand all
524 UnboxedDoubleBinaryOpInstr* double_bin_op = 533 UnboxedDoubleBinaryOpInstr* double_bin_op =
525 new UnboxedDoubleBinaryOpInstr(op_kind, 534 new UnboxedDoubleBinaryOpInstr(op_kind,
526 left->Copy(), 535 left->Copy(),
527 right->Copy(), 536 right->Copy(),
528 call); 537 call);
529 call->ReplaceWith(double_bin_op, current_iterator()); 538 call->ReplaceWith(double_bin_op, current_iterator());
530 RemovePushArguments(call); 539 RemovePushArguments(call);
531 } else if (operands_type == kMintCid) { 540 } else if (operands_type == kMintCid) {
532 Value* left = call->ArgumentAt(0)->value(); 541 Value* left = call->ArgumentAt(0)->value();
533 Value* right = call->ArgumentAt(1)->value(); 542 Value* right = call->ArgumentAt(1)->value();
534 BinaryMintOpInstr* bin_op = new BinaryMintOpInstr(op_kind, 543 UnboxedMintBinaryOpInstr* bin_op =
535 call, 544 new UnboxedMintBinaryOpInstr(op_kind, left, right, call);
536 left,
537 right);
538 call->ReplaceWith(bin_op, current_iterator()); 545 call->ReplaceWith(bin_op, current_iterator());
539 RemovePushArguments(call); 546 RemovePushArguments(call);
540 } else { 547 } else {
541 ASSERT(operands_type == kSmiCid); 548 ASSERT(operands_type == kSmiCid);
542 Value* left = call->ArgumentAt(0)->value(); 549 Value* left = call->ArgumentAt(0)->value();
543 Value* right = call->ArgumentAt(1)->value(); 550 Value* right = call->ArgumentAt(1)->value();
544 // Insert two smi checks and attach a copy of the original 551 // Insert two smi checks and attach a copy of the original
545 // environment because the smi operation can still deoptimize. 552 // environment because the smi operation can still deoptimize.
546 InsertBefore(call, 553 InsertBefore(call,
547 new CheckSmiInstr(left->Copy(), call->deopt_id()), 554 new CheckSmiInstr(left->Copy(), call->deopt_id()),
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 new StrictCompareInstr(strict_kind, comp->left(), comp->right()); 984 new StrictCompareInstr(strict_kind, comp->left(), comp->right());
978 instr->ReplaceWith(strict_comp, iterator); 985 instr->ReplaceWith(strict_comp, iterator);
979 return; 986 return;
980 } 987 }
981 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return; 988 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return;
982 if (comp->ic_data()->NumberOfChecks() == 1) { 989 if (comp->ic_data()->NumberOfChecks() == 1) {
983 ASSERT(comp->ic_data()->num_args_tested() == 2); 990 ASSERT(comp->ic_data()->num_args_tested() == 2);
984 GrowableArray<intptr_t> class_ids; 991 GrowableArray<intptr_t> class_ids;
985 Function& target = Function::Handle(); 992 Function& target = Function::Handle();
986 comp->ic_data()->GetCheckAt(0, &class_ids, &target); 993 comp->ic_data()->GetCheckAt(0, &class_ids, &target);
987 // TODO(srdjan): allow for mixed mode comparison. 994 // TODO(srdjan): allow for mixed mode int/double comparison.
995
988 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { 996 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
989 optimizer->InsertBefore( 997 optimizer->InsertBefore(
990 instr, 998 instr,
991 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()), 999 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
992 instr->env(), 1000 instr->env(),
993 Definition::kEffect); 1001 Definition::kEffect);
994 optimizer->InsertBefore( 1002 optimizer->InsertBefore(
995 instr, 1003 instr,
996 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()), 1004 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
997 instr->env(), 1005 instr->env(),
998 Definition::kEffect); 1006 Definition::kEffect);
999 comp->set_receiver_class_id(kSmiCid); 1007 comp->set_receiver_class_id(kSmiCid);
1000 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) { 1008 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) {
1001 comp->set_receiver_class_id(kDoubleCid); 1009 comp->set_receiver_class_id(kDoubleCid);
1010 } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
1011 FlowGraphCompiler::SupportsUnboxedMints()) {
1012 comp->set_receiver_class_id(kMintCid);
1002 } else { 1013 } else {
1003 ASSERT(comp->receiver_class_id() == kIllegalCid); 1014 ASSERT(comp->receiver_class_id() == kIllegalCid);
1004 } 1015 }
1016 } else if (HasTwoMintOrSmi(*comp->ic_data())) {
1017 comp->set_receiver_class_id(kMintCid);
1005 } else if (comp->ic_data()->AllReceiversAreNumbers()) { 1018 } else if (comp->ic_data()->AllReceiversAreNumbers()) {
1006 comp->set_receiver_class_id(kNumberCid); 1019 comp->set_receiver_class_id(kNumberCid);
1007 } 1020 }
1008 } 1021 }
1009 1022
1010 1023
1011 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) { 1024 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
1012 HandleEqualityCompare(this, instr, instr, current_iterator()); 1025 HandleEqualityCompare(this, instr, instr, current_iterator());
1013 } 1026 }
1014 1027
(...skipping 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 SetValue(instr, non_constant_); 2720 SetValue(instr, non_constant_);
2708 } 2721 }
2709 } else { 2722 } else {
2710 // TODO(kmillikin): support other types. 2723 // TODO(kmillikin): support other types.
2711 SetValue(instr, non_constant_); 2724 SetValue(instr, non_constant_);
2712 } 2725 }
2713 } 2726 }
2714 } 2727 }
2715 2728
2716 2729
2717 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) { 2730 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
2718 const Object& left = instr->left()->definition()->constant_value(); 2731 // TODO(kmillikin): Handle box operation.
2719 const Object& right = instr->right()->definition()->constant_value(); 2732 SetValue(instr, non_constant_);
2720 if (IsNonConstant(left) || IsNonConstant(right)) {
2721 SetValue(instr, non_constant_);
2722 } else if (IsConstant(left) && IsConstant(right)) {
2723 // TODO(kmillikin): Handle binary operations.
2724 SetValue(instr, non_constant_);
2725 }
2726 } 2733 }
2727 2734
2728 2735
2736 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
2737 // TODO(kmillikin): Handle unbox operation.
2738 SetValue(instr, non_constant_);
2739 }
2740
2741
2742 void ConstantPropagator::VisitUnboxedMintBinaryOp(
2743 UnboxedMintBinaryOpInstr* instr) {
2744 // TODO(kmillikin): Handle binary operations.
2745 SetValue(instr, non_constant_);
2746 }
2747
2729 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { 2748 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) {
2730 const Object& value = instr->value()->definition()->constant_value(); 2749 const Object& value = instr->value()->definition()->constant_value();
2731 if (IsNonConstant(value)) { 2750 if (IsNonConstant(value)) {
2732 SetValue(instr, non_constant_); 2751 SetValue(instr, non_constant_);
2733 } else if (IsConstant(value)) { 2752 } else if (IsConstant(value)) {
2734 // TODO(kmillikin): Handle unary operations. 2753 // TODO(kmillikin): Handle unary operations.
2735 SetValue(instr, non_constant_); 2754 SetValue(instr, non_constant_);
2736 } 2755 }
2737 } 2756 }
2738 2757
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 } 2987 }
2969 2988
2970 graph_->DiscoverBlocks(); 2989 graph_->DiscoverBlocks();
2971 GrowableArray<BitVector*> dominance_frontier; 2990 GrowableArray<BitVector*> dominance_frontier;
2972 graph_->ComputeDominators(&dominance_frontier); 2991 graph_->ComputeDominators(&dominance_frontier);
2973 graph_->ComputeUseLists(); 2992 graph_->ComputeUseLists();
2974 } 2993 }
2975 2994
2976 2995
2977 } // namespace dart 2996 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698