Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 return class_id; | 541 return class_id; |
| 542 } | 542 } |
| 543 | 543 |
| 544 | 544 |
| 545 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { | 545 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { |
| 546 const intptr_t class_id = ReceiverClassId(call); | 546 const intptr_t class_id = ReceiverClassId(call); |
| 547 ICData& value_check = ICData::ZoneHandle(); | 547 ICData& value_check = ICData::ZoneHandle(); |
| 548 switch (class_id) { | 548 switch (class_id) { |
| 549 case kArrayCid: | 549 case kArrayCid: |
| 550 case kGrowableObjectArrayCid: | 550 case kGrowableObjectArrayCid: |
| 551 // Acceptable store index classes. | 551 if (ArgIsAlwaysSmi(*call->ic_data(), 2)) { |
| 552 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | |
| 553 } | |
| 552 break; | 554 break; |
| 555 case kUint8ArrayCid: | |
| 556 // Check that value is always smi. | |
| 557 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | |
| 558 if ((value_check.NumberOfChecks() != 1) || | |
| 559 (value_check.GetReceiverClassIdAt(0) != kSmiCid)) { | |
| 560 return false; | |
| 561 } | |
| 562 break; | |
| 563 | |
| 553 case kFloat32ArrayCid: | 564 case kFloat32ArrayCid: |
| 554 case kFloat64ArrayCid: { | 565 case kFloat64ArrayCid: { |
| 555 // Check that value is always double. | 566 // Check that value is always double. |
| 556 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 567 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 557 if ((value_check.NumberOfChecks() != 1) || | 568 if ((value_check.NumberOfChecks() != 1) || |
| 558 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { | 569 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { |
| 559 return false; | 570 return false; |
| 560 } | 571 } |
| 561 break; | 572 break; |
| 562 } | 573 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 585 instantiator_class.type_arguments_field_offset(); | 596 instantiator_class.type_arguments_field_offset(); |
| 586 LoadFieldInstr* load_type_args = | 597 LoadFieldInstr* load_type_args = |
| 587 new LoadFieldInstr(array->Copy(), | 598 new LoadFieldInstr(array->Copy(), |
| 588 type_arguments_field_offset, | 599 type_arguments_field_offset, |
| 589 Type::ZoneHandle()); // No type. | 600 Type::ZoneHandle()); // No type. |
| 590 InsertBefore(call, load_type_args, NULL, Definition::kValue); | 601 InsertBefore(call, load_type_args, NULL, Definition::kValue); |
| 591 instantiator = array->Copy(); | 602 instantiator = array->Copy(); |
| 592 type_args = new Value(load_type_args); | 603 type_args = new Value(load_type_args); |
| 593 break; | 604 break; |
| 594 } | 605 } |
| 606 case kUint8ArrayCid: | |
| 595 case kFloat32ArrayCid: | 607 case kFloat32ArrayCid: |
| 596 case kFloat64ArrayCid: { | 608 case kFloat64ArrayCid: { |
| 597 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); | 609 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); |
| 598 InsertBefore(call, null_constant, NULL, Definition::kValue); | 610 InsertBefore(call, null_constant, NULL, Definition::kValue); |
| 599 instantiator = new Value(null_constant); | 611 instantiator = new Value(null_constant); |
| 600 type_args = new Value(null_constant); | 612 type_args = new Value(null_constant); |
| 601 ASSERT(value_type.IsDoubleType()); | 613 ASSERT(value_type.IsDoubleType() || value_type.IsIntType()); |
|
srdjan
2013/01/11 17:02:38
Maybe you want to split the ASSERT: double type is
Florian Schneider
2013/01/14 10:03:10
Done.
| |
| 602 ASSERT(value_type.IsInstantiated()); | 614 ASSERT(value_type.IsInstantiated()); |
| 603 break; | 615 break; |
| 604 } | 616 } |
| 605 default: | 617 default: |
| 606 // TODO(fschneider): Add support for other array types. | 618 // TODO(fschneider): Add support for other array types. |
| 607 UNREACHABLE(); | 619 UNREACHABLE(); |
| 608 } | 620 } |
| 609 AssertAssignableInstr* assert_value = | 621 AssertAssignableInstr* assert_value = |
| 610 new AssertAssignableInstr(call->token_pos(), | 622 new AssertAssignableInstr(call->token_pos(), |
| 611 value->Copy(), | 623 value->Copy(), |
| 612 instantiator, | 624 instantiator, |
| 613 type_args, | 625 type_args, |
| 614 value_type, | 626 value_type, |
| 615 Symbols::Value()); | 627 Symbols::Value()); |
| 616 InsertBefore(call, assert_value, NULL, Definition::kValue); | 628 InsertBefore(call, assert_value, NULL, Definition::kValue); |
| 617 } | 629 } |
| 618 | 630 |
| 619 Value* array = NULL; | 631 Value* array = NULL; |
| 620 Value* index = NULL; | 632 Value* index = NULL; |
| 621 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 633 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 622 Value* value = call->ArgumentAt(2)->value(); | 634 Value* value = call->ArgumentAt(2)->value(); |
| 623 // Check if store barrier is needed. | 635 // Check if store barrier is needed. |
| 624 bool needs_store_barrier = true; | 636 bool needs_store_barrier = true; |
| 625 if ((class_id == kFloat32ArrayCid) || (class_id == kFloat64ArrayCid)) { | 637 if (!value_check.IsNull()) { |
| 626 ASSERT(!value_check.IsNull()); | 638 ASSERT(value_check.NumberOfChecks() == 1); |
| 627 InsertBefore(call, | 639 if (value_check.GetReceiverClassIdAt(0) == kSmiCid) { |
| 628 new CheckClassInstr(value->Copy(), | 640 InsertBefore(call, |
| 629 call->deopt_id(), | 641 new CheckSmiInstr(value->Copy(), call->deopt_id()), |
| 630 value_check), | 642 call->env(), |
| 631 call->env(), | 643 Definition::kEffect); |
| 632 Definition::kEffect); | 644 needs_store_barrier = false; |
| 633 needs_store_barrier = false; | 645 } else { |
| 634 } else if (ArgIsAlwaysSmi(*call->ic_data(), 2)) { | 646 ASSERT(value_check.GetReceiverClassIdAt(0) == kDoubleCid); |
| 635 InsertBefore(call, | 647 InsertBefore(call, |
| 636 new CheckSmiInstr(value->Copy(), call->deopt_id()), | 648 new CheckClassInstr(value->Copy(), |
| 637 call->env(), | 649 call->deopt_id(), |
| 638 Definition::kEffect); | 650 value_check), |
| 639 needs_store_barrier = false; | 651 call->env(), |
| 652 Definition::kEffect); | |
| 653 needs_store_barrier = false; | |
| 654 } | |
| 640 } | 655 } |
| 641 | 656 |
| 642 Definition* array_op = | 657 Definition* array_op = |
| 643 new StoreIndexedInstr(array, index, value, | 658 new StoreIndexedInstr(array, index, value, |
| 644 needs_store_barrier, array_cid, call->deopt_id()); | 659 needs_store_barrier, array_cid, call->deopt_id()); |
| 645 call->ReplaceWith(array_op, current_iterator()); | 660 call->ReplaceWith(array_op, current_iterator()); |
| 646 RemovePushArguments(call); | 661 RemovePushArguments(call); |
| 647 return true; | 662 return true; |
| 648 } | 663 } |
| 649 | 664 |
| (...skipping 3764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4414 | 4429 |
| 4415 if (FLAG_trace_constant_propagation) { | 4430 if (FLAG_trace_constant_propagation) { |
| 4416 OS::Print("\n==== After constant propagation ====\n"); | 4431 OS::Print("\n==== After constant propagation ====\n"); |
| 4417 FlowGraphPrinter printer(*graph_); | 4432 FlowGraphPrinter printer(*graph_); |
| 4418 printer.PrintBlocks(); | 4433 printer.PrintBlocks(); |
| 4419 } | 4434 } |
| 4420 } | 4435 } |
| 4421 | 4436 |
| 4422 | 4437 |
| 4423 } // namespace dart | 4438 } // namespace dart |
| OLD | NEW |