| 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((class_id != kUint8ArrayCid) || value_type.IsIntType()); |
| 614 ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) || |
| 615 value_type.IsDoubleType()); |
| 602 ASSERT(value_type.IsInstantiated()); | 616 ASSERT(value_type.IsInstantiated()); |
| 603 break; | 617 break; |
| 604 } | 618 } |
| 605 default: | 619 default: |
| 606 // TODO(fschneider): Add support for other array types. | 620 // TODO(fschneider): Add support for other array types. |
| 607 UNREACHABLE(); | 621 UNREACHABLE(); |
| 608 } | 622 } |
| 609 AssertAssignableInstr* assert_value = | 623 AssertAssignableInstr* assert_value = |
| 610 new AssertAssignableInstr(call->token_pos(), | 624 new AssertAssignableInstr(call->token_pos(), |
| 611 value->Copy(), | 625 value->Copy(), |
| 612 instantiator, | 626 instantiator, |
| 613 type_args, | 627 type_args, |
| 614 value_type, | 628 value_type, |
| 615 Symbols::Value()); | 629 Symbols::Value()); |
| 616 InsertBefore(call, assert_value, NULL, Definition::kValue); | 630 InsertBefore(call, assert_value, NULL, Definition::kValue); |
| 617 } | 631 } |
| 618 | 632 |
| 619 Value* array = NULL; | 633 Value* array = NULL; |
| 620 Value* index = NULL; | 634 Value* index = NULL; |
| 621 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 635 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 622 Value* value = call->ArgumentAt(2)->value(); | 636 Value* value = call->ArgumentAt(2)->value(); |
| 623 // Check if store barrier is needed. | 637 // Check if store barrier is needed. |
| 624 bool needs_store_barrier = true; | 638 bool needs_store_barrier = true; |
| 625 if ((class_id == kFloat32ArrayCid) || (class_id == kFloat64ArrayCid)) { | 639 if (!value_check.IsNull()) { |
| 626 ASSERT(!value_check.IsNull()); | 640 ASSERT(value_check.NumberOfChecks() == 1); |
| 627 InsertBefore(call, | 641 if (value_check.GetReceiverClassIdAt(0) == kSmiCid) { |
| 628 new CheckClassInstr(value->Copy(), | 642 InsertBefore(call, |
| 629 call->deopt_id(), | 643 new CheckSmiInstr(value->Copy(), call->deopt_id()), |
| 630 value_check), | 644 call->env(), |
| 631 call->env(), | 645 Definition::kEffect); |
| 632 Definition::kEffect); | 646 needs_store_barrier = false; |
| 633 needs_store_barrier = false; | 647 } else { |
| 634 } else if (ArgIsAlwaysSmi(*call->ic_data(), 2)) { | 648 ASSERT(value_check.GetReceiverClassIdAt(0) == kDoubleCid); |
| 635 InsertBefore(call, | 649 InsertBefore(call, |
| 636 new CheckSmiInstr(value->Copy(), call->deopt_id()), | 650 new CheckClassInstr(value->Copy(), |
| 637 call->env(), | 651 call->deopt_id(), |
| 638 Definition::kEffect); | 652 value_check), |
| 639 needs_store_barrier = false; | 653 call->env(), |
| 654 Definition::kEffect); |
| 655 needs_store_barrier = false; |
| 656 } |
| 640 } | 657 } |
| 641 | 658 |
| 642 Definition* array_op = | 659 Definition* array_op = |
| 643 new StoreIndexedInstr(array, index, value, | 660 new StoreIndexedInstr(array, index, value, |
| 644 needs_store_barrier, array_cid, call->deopt_id()); | 661 needs_store_barrier, array_cid, call->deopt_id()); |
| 645 call->ReplaceWith(array_op, current_iterator()); | 662 call->ReplaceWith(array_op, current_iterator()); |
| 646 RemovePushArguments(call); | 663 RemovePushArguments(call); |
| 647 return true; | 664 return true; |
| 648 } | 665 } |
| 649 | 666 |
| (...skipping 3764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4414 | 4431 |
| 4415 if (FLAG_trace_constant_propagation) { | 4432 if (FLAG_trace_constant_propagation) { |
| 4416 OS::Print("\n==== After constant propagation ====\n"); | 4433 OS::Print("\n==== After constant propagation ====\n"); |
| 4417 FlowGraphPrinter printer(*graph_); | 4434 FlowGraphPrinter printer(*graph_); |
| 4418 printer.PrintBlocks(); | 4435 printer.PrintBlocks(); |
| 4419 } | 4436 } |
| 4420 } | 4437 } |
| 4421 | 4438 |
| 4422 | 4439 |
| 4423 } // namespace dart | 4440 } // namespace dart |
| OLD | NEW |