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

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, 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 | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('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/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 == kUnboxedMint)) {
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 == kUnboxedMint) && (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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 476 }
469 break; 477 break;
470 case Token::kMOD: 478 case Token::kMOD:
471 if (HasOnlyTwoSmi(ic_data)) { 479 if (HasOnlyTwoSmi(ic_data)) {
472 operands_type = kSmiCid; 480 operands_type = kSmiCid;
473 } else { 481 } else {
474 return false; 482 return false;
475 } 483 }
476 break; 484 break;
477 case Token::kBIT_AND: 485 case Token::kBIT_AND:
486 case Token::kBIT_OR:
487 case Token::kBIT_XOR:
478 if (HasOnlyTwoSmi(ic_data)) { 488 if (HasOnlyTwoSmi(ic_data)) {
479 operands_type = kSmiCid; 489 operands_type = kSmiCid;
480 } else if (HasTwoMintOrSmi(ic_data)) { 490 } else if (HasTwoMintOrSmi(ic_data) &&
491 FlowGraphCompiler::SupportsUnboxedMints()) {
481 operands_type = kMintCid; 492 operands_type = kMintCid;
482 } else { 493 } else {
483 return false; 494 return false;
484 } 495 }
485 break; 496 break;
486 case Token::kBIT_OR:
487 case Token::kBIT_XOR:
488 case Token::kTRUNCDIV: 497 case Token::kTRUNCDIV:
489 case Token::kSHR: 498 case Token::kSHR:
490 case Token::kSHL: 499 case Token::kSHL:
491 if (HasOnlyTwoSmi(ic_data)) { 500 if (HasOnlyTwoSmi(ic_data)) {
492 operands_type = kSmiCid; 501 operands_type = kSmiCid;
493 } else { 502 } else {
494 return false; 503 return false;
495 } 504 }
496 break; 505 break;
497 default: 506 default:
(...skipping 17 matching lines...) Expand all
515 UnboxedDoubleBinaryOpInstr* double_bin_op = 524 UnboxedDoubleBinaryOpInstr* double_bin_op =
516 new UnboxedDoubleBinaryOpInstr(op_kind, 525 new UnboxedDoubleBinaryOpInstr(op_kind,
517 left->Copy(), 526 left->Copy(),
518 right->Copy(), 527 right->Copy(),
519 call); 528 call);
520 call->ReplaceWith(double_bin_op, current_iterator()); 529 call->ReplaceWith(double_bin_op, current_iterator());
521 RemovePushArguments(call); 530 RemovePushArguments(call);
522 } else if (operands_type == kMintCid) { 531 } else if (operands_type == kMintCid) {
523 Value* left = call->ArgumentAt(0)->value(); 532 Value* left = call->ArgumentAt(0)->value();
524 Value* right = call->ArgumentAt(1)->value(); 533 Value* right = call->ArgumentAt(1)->value();
525 BinaryMintOpInstr* bin_op = new BinaryMintOpInstr(op_kind, 534 UnboxedMintBinaryOpInstr* bin_op =
526 call, 535 new UnboxedMintBinaryOpInstr(op_kind, left, right, call);
527 left,
528 right);
529 call->ReplaceWith(bin_op, current_iterator()); 536 call->ReplaceWith(bin_op, current_iterator());
530 RemovePushArguments(call); 537 RemovePushArguments(call);
531 } else if (op_kind == Token::kMOD) { 538 } else if (op_kind == Token::kMOD) {
532 // TODO(vegorov): implement fast path code for modulo. 539 // TODO(vegorov): implement fast path code for modulo.
533 ASSERT(operands_type == kSmiCid); 540 ASSERT(operands_type == kSmiCid);
534 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; 541 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false;
535 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); 542 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant();
536 if (!obj.IsSmi()) return false; 543 if (!obj.IsSmi()) return false;
537 const intptr_t value = Smi::Cast(obj).Value(); 544 const intptr_t value = Smi::Cast(obj).Value();
538 if ((value > 0) && Utils::IsPowerOfTwo(value)) { 545 if ((value > 0) && Utils::IsPowerOfTwo(value)) {
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 new StrictCompareInstr(strict_kind, comp->left(), comp->right()); 1057 new StrictCompareInstr(strict_kind, comp->left(), comp->right());
1051 instr->ReplaceWith(strict_comp, iterator); 1058 instr->ReplaceWith(strict_comp, iterator);
1052 return; 1059 return;
1053 } 1060 }
1054 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return; 1061 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return;
1055 if (comp->ic_data()->NumberOfChecks() == 1) { 1062 if (comp->ic_data()->NumberOfChecks() == 1) {
1056 ASSERT(comp->ic_data()->num_args_tested() == 2); 1063 ASSERT(comp->ic_data()->num_args_tested() == 2);
1057 GrowableArray<intptr_t> class_ids; 1064 GrowableArray<intptr_t> class_ids;
1058 Function& target = Function::Handle(); 1065 Function& target = Function::Handle();
1059 comp->ic_data()->GetCheckAt(0, &class_ids, &target); 1066 comp->ic_data()->GetCheckAt(0, &class_ids, &target);
1060 // TODO(srdjan): allow for mixed mode comparison. 1067 // TODO(srdjan): allow for mixed mode int/double comparison.
1068
1061 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { 1069 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
1062 optimizer->InsertBefore( 1070 optimizer->InsertBefore(
1063 instr, 1071 instr,
1064 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()), 1072 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
1065 instr->env(), 1073 instr->env(),
1066 Definition::kEffect); 1074 Definition::kEffect);
1067 optimizer->InsertBefore( 1075 optimizer->InsertBefore(
1068 instr, 1076 instr,
1069 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()), 1077 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
1070 instr->env(), 1078 instr->env(),
1071 Definition::kEffect); 1079 Definition::kEffect);
1072 comp->set_receiver_class_id(kSmiCid); 1080 comp->set_receiver_class_id(kSmiCid);
1073 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) { 1081 } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) {
1074 comp->set_receiver_class_id(kDoubleCid); 1082 comp->set_receiver_class_id(kDoubleCid);
1083 } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
1084 FlowGraphCompiler::SupportsUnboxedMints()) {
1085 comp->set_receiver_class_id(kMintCid);
1075 } else { 1086 } else {
1076 ASSERT(comp->receiver_class_id() == kIllegalCid); 1087 ASSERT(comp->receiver_class_id() == kIllegalCid);
1077 } 1088 }
1089 } else if (HasTwoMintOrSmi(*comp->ic_data())) {
1090 comp->set_receiver_class_id(kMintCid);
1078 } else if (comp->ic_data()->AllReceiversAreNumbers()) { 1091 } else if (comp->ic_data()->AllReceiversAreNumbers()) {
1079 comp->set_receiver_class_id(kNumberCid); 1092 comp->set_receiver_class_id(kNumberCid);
1080 } 1093 }
1081 } 1094 }
1082 1095
1083 1096
1084 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) { 1097 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
1085 HandleEqualityCompare(this, instr, instr, current_iterator()); 1098 HandleEqualityCompare(this, instr, instr, current_iterator());
1086 } 1099 }
1087 1100
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 SetValue(instr, non_constant_); 2875 SetValue(instr, non_constant_);
2863 } 2876 }
2864 } else { 2877 } else {
2865 // TODO(kmillikin): support other types. 2878 // TODO(kmillikin): support other types.
2866 SetValue(instr, non_constant_); 2879 SetValue(instr, non_constant_);
2867 } 2880 }
2868 } 2881 }
2869 } 2882 }
2870 2883
2871 2884
2885 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
2886 // TODO(kmillikin): Handle box operation.
2887 SetValue(instr, non_constant_);
2888 }
2889
2890
2891 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
2892 // TODO(kmillikin): Handle unbox operation.
2893 SetValue(instr, non_constant_);
2894 }
2895
2896
2897 void ConstantPropagator::VisitUnboxedMintBinaryOp(
2898 UnboxedMintBinaryOpInstr* instr) {
2899 // TODO(kmillikin): Handle binary operations.
2900 SetValue(instr, non_constant_);
2901 }
2902
2903
2872 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) { 2904 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
2873 const Object& left = instr->left()->definition()->constant_value(); 2905 const Object& left = instr->left()->definition()->constant_value();
2874 const Object& right = instr->right()->definition()->constant_value(); 2906 const Object& right = instr->right()->definition()->constant_value();
2875 if (IsNonConstant(left) || IsNonConstant(right)) { 2907 if (IsNonConstant(left) || IsNonConstant(right)) {
2876 SetValue(instr, non_constant_); 2908 SetValue(instr, non_constant_);
2877 } else if (IsConstant(left) && IsConstant(right)) { 2909 } else if (IsConstant(left) && IsConstant(right)) {
2878 // TODO(kmillikin): Handle binary operations. 2910 // TODO(kmillikin): Handle binary operations.
2879 SetValue(instr, non_constant_); 2911 SetValue(instr, non_constant_);
2880 } 2912 }
2881 } 2913 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 3149
3118 if (FLAG_trace_constant_propagation) { 3150 if (FLAG_trace_constant_propagation) {
3119 OS::Print("\n==== After constant propagation ====\n"); 3151 OS::Print("\n==== After constant propagation ====\n");
3120 FlowGraphPrinter printer(*graph_); 3152 FlowGraphPrinter printer(*graph_);
3121 printer.PrintBlocks(); 3153 printer.PrintBlocks();
3122 } 3154 }
3123 } 3155 }
3124 3156
3125 3157
3126 } // namespace dart 3158 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698