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

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

Issue 11027060: Faster 64-bit right-shift for the ia32 compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments 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/disassembler_ia32.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/flow_graph_compiler.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 141
142 void FlowGraphOptimizer::SelectRepresentations() { 142 void FlowGraphOptimizer::SelectRepresentations() {
143 // Convervatively unbox all phis that were proven to be of type Double. 143 // Convervatively unbox all phis that were proven to be of type Double.
144 for (intptr_t i = 0; i < block_order_.length(); ++i) { 144 for (intptr_t i = 0; i < block_order_.length(); ++i) {
145 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 145 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
146 if (join_entry == NULL) continue; 146 if (join_entry == NULL) continue;
147 147
148 if (join_entry->phis() != NULL) { 148 if (join_entry->phis() != NULL) {
149 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { 149 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
150 PhiInstr* phi = (*join_entry->phis())[i]; 150 PhiInstr* phi = (*join_entry->phis())[i];
151 if ((phi != NULL) && (phi->GetPropagatedCid() == kDoubleCid)) { 151 if (phi == NULL) continue;
152 if (phi->GetPropagatedCid() == kDoubleCid) {
152 phi->set_representation(kUnboxedDouble); 153 phi->set_representation(kUnboxedDouble);
153 } 154 }
154 } 155 }
155 } 156 }
156 } 157 }
157 158
158 // Process all instructions and insert conversions where needed. 159 // Process all instructions and insert conversions where needed.
159 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry(); 160 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry();
160 161
161 // Visit incoming parameters and constants. 162 // Visit incoming parameters and constants.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 if (ic_data.NumberOfChecks() == 1) { 262 if (ic_data.NumberOfChecks() == 1) {
262 return ICDataHasReceiverClassId(ic_data, kSmiCid) 263 return ICDataHasReceiverClassId(ic_data, kSmiCid)
263 || ICDataHasReceiverClassId(ic_data, kMintCid); 264 || ICDataHasReceiverClassId(ic_data, kMintCid);
264 } 265 }
265 return (ic_data.NumberOfChecks() == 2) 266 return (ic_data.NumberOfChecks() == 2)
266 && ICDataHasReceiverClassId(ic_data, kSmiCid) 267 && ICDataHasReceiverClassId(ic_data, kSmiCid)
267 && ICDataHasReceiverClassId(ic_data, kMintCid); 268 && ICDataHasReceiverClassId(ic_data, kMintCid);
268 } 269 }
269 270
270 271
271 static bool HasOnlyTwoSmi(const ICData& ic_data) { 272 static bool HasOnlyTwoSmis(const ICData& ic_data) {
272 return (ic_data.NumberOfChecks() == 1) && 273 return (ic_data.NumberOfChecks() == 1) &&
273 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid); 274 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
274 } 275 }
275 276
276 277
277 // Returns false if the ICData contains anything other than the 4 combinations 278 // Returns false if the ICData contains anything other than the 4 combinations
278 // of Mint and Smi for the receiver and argument classes. 279 // of Mint and Smi for the receiver and argument classes.
279 static bool HasTwoMintOrSmi(const ICData& ic_data) { 280 static bool HasTwoMintOrSmi(const ICData& ic_data) {
280 GrowableArray<intptr_t> class_ids(2); 281 GrowableArray<intptr_t> class_ids(2);
281 class_ids.Add(kSmiCid); 282 class_ids.Add(kSmiCid);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 468
468 469
469 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, 470 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
470 Token::Kind op_kind) { 471 Token::Kind op_kind) {
471 intptr_t operands_type = kIllegalCid; 472 intptr_t operands_type = kIllegalCid;
472 ASSERT(call->HasICData()); 473 ASSERT(call->HasICData());
473 const ICData& ic_data = *call->ic_data(); 474 const ICData& ic_data = *call->ic_data();
474 switch (op_kind) { 475 switch (op_kind) {
475 case Token::kADD: 476 case Token::kADD:
476 case Token::kSUB: 477 case Token::kSUB:
477 if (HasOnlyTwoSmi(ic_data)) { 478 if (HasOnlyTwoSmis(ic_data)) {
478 operands_type = kSmiCid; 479 operands_type = kSmiCid;
479 } else if (HasTwoMintOrSmi(ic_data) && 480 } else if (HasTwoMintOrSmi(ic_data) &&
480 FlowGraphCompiler::SupportsUnboxedMints()) { 481 FlowGraphCompiler::SupportsUnboxedMints()) {
481 operands_type = kMintCid; 482 operands_type = kMintCid;
482 } else if (ShouldSpecializeForDouble(ic_data)) { 483 } else if (ShouldSpecializeForDouble(ic_data)) {
483 operands_type = kDoubleCid; 484 operands_type = kDoubleCid;
484 } else { 485 } else {
485 return false; 486 return false;
486 } 487 }
487 break; 488 break;
488 case Token::kMUL: 489 case Token::kMUL:
489 if (HasOnlyTwoSmi(ic_data)) { 490 if (HasOnlyTwoSmis(ic_data)) {
490 operands_type = kSmiCid; 491 operands_type = kSmiCid;
491 } else if (ShouldSpecializeForDouble(ic_data)) { 492 } else if (ShouldSpecializeForDouble(ic_data)) {
492 operands_type = kDoubleCid; 493 operands_type = kDoubleCid;
493 } else { 494 } else {
494 return false; 495 return false;
495 } 496 }
496 break; 497 break;
497 case Token::kDIV: 498 case Token::kDIV:
498 if (ShouldSpecializeForDouble(ic_data)) { 499 if (ShouldSpecializeForDouble(ic_data)) {
499 operands_type = kDoubleCid; 500 operands_type = kDoubleCid;
500 } else { 501 } else {
501 return false; 502 return false;
502 } 503 }
503 break; 504 break;
504 case Token::kMOD: 505 case Token::kMOD:
505 if (HasOnlyTwoSmi(ic_data)) { 506 if (HasOnlyTwoSmis(ic_data)) {
506 operands_type = kSmiCid; 507 operands_type = kSmiCid;
507 } else { 508 } else {
508 return false; 509 return false;
509 } 510 }
510 break; 511 break;
511 case Token::kBIT_AND: 512 case Token::kBIT_AND:
512 case Token::kBIT_OR: 513 case Token::kBIT_OR:
513 case Token::kBIT_XOR: 514 case Token::kBIT_XOR:
514 if (HasOnlyTwoSmi(ic_data)) { 515 if (HasOnlyTwoSmis(ic_data)) {
515 operands_type = kSmiCid; 516 operands_type = kSmiCid;
516 } else if (HasTwoMintOrSmi(ic_data) && 517 } else if (HasTwoMintOrSmi(ic_data) &&
517 FlowGraphCompiler::SupportsUnboxedMints()) { 518 FlowGraphCompiler::SupportsUnboxedMints()) {
518 operands_type = kMintCid; 519 operands_type = kMintCid;
519 } else { 520 } else {
520 return false; 521 return false;
521 } 522 }
522 break; 523 break;
524 case Token::kSHR:
525 if (HasOnlyTwoSmis(ic_data)) {
526 operands_type = kSmiCid;
527 } else if (HasTwoMintOrSmi(ic_data) &&
528 FlowGraphCompiler::SupportsUnboxedMints()) {
529 operands_type = kMintCid;
530 } else {
531 return false;
532 }
533 break;
523 case Token::kTRUNCDIV: 534 case Token::kTRUNCDIV:
524 case Token::kSHR:
525 case Token::kSHL: 535 case Token::kSHL:
526 if (HasOnlyTwoSmi(ic_data)) { 536 if (HasOnlyTwoSmis(ic_data)) {
527 operands_type = kSmiCid; 537 operands_type = kSmiCid;
528 } else { 538 } else {
529 return false; 539 return false;
530 } 540 }
531 break; 541 break;
532 default: 542 default:
533 UNREACHABLE(); 543 UNREACHABLE();
534 }; 544 };
535 545
536 ASSERT(call->ArgumentCount() == 2); 546 ASSERT(call->ArgumentCount() == 2);
(...skipping 10 matching lines...) Expand all
547 call->env(), 557 call->env(),
548 Definition::kEffect); 558 Definition::kEffect);
549 559
550 BinaryDoubleOpInstr* double_bin_op = 560 BinaryDoubleOpInstr* double_bin_op =
551 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call); 561 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call);
552 call->ReplaceWith(double_bin_op, current_iterator()); 562 call->ReplaceWith(double_bin_op, current_iterator());
553 RemovePushArguments(call); 563 RemovePushArguments(call);
554 } else if (operands_type == kMintCid) { 564 } else if (operands_type == kMintCid) {
555 Value* left = call->ArgumentAt(0)->value(); 565 Value* left = call->ArgumentAt(0)->value();
556 Value* right = call->ArgumentAt(1)->value(); 566 Value* right = call->ArgumentAt(1)->value();
557 BinaryMintOpInstr* bin_op = 567 if (op_kind == Token::kSHR) {
558 new BinaryMintOpInstr(op_kind, left, right, call); 568 ShiftMintOpInstr* shift_op =
559 call->ReplaceWith(bin_op, current_iterator()); 569 new ShiftMintOpInstr(op_kind, left, right, call);
570 call->ReplaceWith(shift_op, current_iterator());
571 } else {
572 BinaryMintOpInstr* bin_op =
573 new BinaryMintOpInstr(op_kind, left, right, call);
574 call->ReplaceWith(bin_op, current_iterator());
575 }
560 RemovePushArguments(call); 576 RemovePushArguments(call);
561 } else if (op_kind == Token::kMOD) { 577 } else if (op_kind == Token::kMOD) {
562 // TODO(vegorov): implement fast path code for modulo. 578 // TODO(vegorov): implement fast path code for modulo.
563 ASSERT(operands_type == kSmiCid); 579 ASSERT(operands_type == kSmiCid);
564 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; 580 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false;
565 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); 581 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant();
566 if (!obj.IsSmi()) return false; 582 if (!obj.IsSmi()) return false;
567 const intptr_t value = Smi::Cast(obj).Value(); 583 const intptr_t value = Smi::Cast(obj).Value();
568 if ((value > 0) && Utils::IsPowerOfTwo(value)) { 584 if ((value > 0) && Utils::IsPowerOfTwo(value)) {
569 Value* left = call->ArgumentAt(0)->value(); 585 Value* left = call->ArgumentAt(0)->value();
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 RelationalOpInstr* comp, 1051 RelationalOpInstr* comp,
1036 Instruction* instr) { 1052 Instruction* instr) {
1037 if (!comp->HasICData()) return; 1053 if (!comp->HasICData()) return;
1038 1054
1039 const ICData& ic_data = *comp->ic_data(); 1055 const ICData& ic_data = *comp->ic_data();
1040 if (ic_data.NumberOfChecks() == 0) return; 1056 if (ic_data.NumberOfChecks() == 0) return;
1041 // TODO(srdjan): Add multiple receiver type support. 1057 // TODO(srdjan): Add multiple receiver type support.
1042 if (ic_data.NumberOfChecks() != 1) return; 1058 if (ic_data.NumberOfChecks() != 1) return;
1043 ASSERT(ic_data.HasOneTarget()); 1059 ASSERT(ic_data.HasOneTarget());
1044 1060
1045 if (HasOnlyTwoSmi(ic_data)) { 1061 if (HasOnlyTwoSmis(ic_data)) {
1046 optimizer->InsertBefore( 1062 optimizer->InsertBefore(
1047 instr, 1063 instr,
1048 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()), 1064 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
1049 instr->env(), 1065 instr->env(),
1050 Definition::kEffect); 1066 Definition::kEffect);
1051 optimizer->InsertBefore( 1067 optimizer->InsertBefore(
1052 instr, 1068 instr,
1053 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()), 1069 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
1054 instr->env(), 1070 instr->env(),
1055 Definition::kEffect); 1071 Definition::kEffect);
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
2976 } 2992 }
2977 2993
2978 2994
2979 void ConstantPropagator::VisitBinaryMintOp( 2995 void ConstantPropagator::VisitBinaryMintOp(
2980 BinaryMintOpInstr* instr) { 2996 BinaryMintOpInstr* instr) {
2981 // TODO(kmillikin): Handle binary operations. 2997 // TODO(kmillikin): Handle binary operations.
2982 SetValue(instr, non_constant_); 2998 SetValue(instr, non_constant_);
2983 } 2999 }
2984 3000
2985 3001
3002 void ConstantPropagator::VisitShiftMintOp(
3003 ShiftMintOpInstr* instr) {
3004 // TODO(kmillikin): Handle shift operations.
3005 SetValue(instr, non_constant_);
3006 }
3007
3008
2986 void ConstantPropagator::VisitUnaryMintOp( 3009 void ConstantPropagator::VisitUnaryMintOp(
2987 UnaryMintOpInstr* instr) { 3010 UnaryMintOpInstr* instr) {
2988 // TODO(kmillikin): Handle unary operations. 3011 // TODO(kmillikin): Handle unary operations.
2989 SetValue(instr, non_constant_); 3012 SetValue(instr, non_constant_);
2990 } 3013 }
2991 3014
2992 3015
2993 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { 3016 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) {
2994 const Object& value = instr->value()->definition()->constant_value(); 3017 const Object& value = instr->value()->definition()->constant_value();
2995 if (IsNonConstant(value)) { 3018 if (IsNonConstant(value)) {
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 3249
3227 if (FLAG_trace_constant_propagation) { 3250 if (FLAG_trace_constant_propagation) {
3228 OS::Print("\n==== After constant propagation ====\n"); 3251 OS::Print("\n==== After constant propagation ====\n");
3229 FlowGraphPrinter printer(*graph_); 3252 FlowGraphPrinter printer(*graph_);
3230 printer.PrintBlocks(); 3253 printer.PrintBlocks();
3231 } 3254 }
3232 } 3255 }
3233 3256
3234 3257
3235 } // namespace dart 3258 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_ia32.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698