| 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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 490 |
| 491 | 491 |
| 492 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { | 492 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { |
| 493 const intptr_t class_id = ReceiverClassId(call); | 493 const intptr_t class_id = ReceiverClassId(call); |
| 494 ICData& value_check = ICData::Handle(); | 494 ICData& value_check = ICData::Handle(); |
| 495 switch (class_id) { | 495 switch (class_id) { |
| 496 case kArrayCid: | 496 case kArrayCid: |
| 497 case kGrowableObjectArrayCid: | 497 case kGrowableObjectArrayCid: |
| 498 // Acceptable store index classes. | 498 // Acceptable store index classes. |
| 499 break; | 499 break; |
| 500 case kFloat32ArrayCid: |
| 500 case kFloat64ArrayCid: { | 501 case kFloat64ArrayCid: { |
| 501 // Check that value is always double. | 502 // Check that value is always double. |
| 502 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 503 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 503 if ((value_check.NumberOfChecks() != 1) || | 504 if ((value_check.NumberOfChecks() != 1) || |
| 504 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { | 505 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { |
| 505 return false; | 506 return false; |
| 506 } | 507 } |
| 507 break; | 508 break; |
| 508 } | 509 } |
| 509 default: | 510 default: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 531 instantiator_class.type_arguments_instance_field_offset(); | 532 instantiator_class.type_arguments_instance_field_offset(); |
| 532 LoadFieldInstr* load_type_args = | 533 LoadFieldInstr* load_type_args = |
| 533 new LoadFieldInstr(array->Copy(), | 534 new LoadFieldInstr(array->Copy(), |
| 534 type_arguments_instance_field_offset, | 535 type_arguments_instance_field_offset, |
| 535 Type::ZoneHandle()); // No type. | 536 Type::ZoneHandle()); // No type. |
| 536 InsertBefore(call, load_type_args, NULL, Definition::kValue); | 537 InsertBefore(call, load_type_args, NULL, Definition::kValue); |
| 537 instantiator = array->Copy(); | 538 instantiator = array->Copy(); |
| 538 type_args = new Value(load_type_args); | 539 type_args = new Value(load_type_args); |
| 539 break; | 540 break; |
| 540 } | 541 } |
| 542 case kFloat32ArrayCid: |
| 541 case kFloat64ArrayCid: { | 543 case kFloat64ArrayCid: { |
| 542 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); | 544 ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); |
| 543 InsertBefore(call, null_constant, NULL, Definition::kValue); | 545 InsertBefore(call, null_constant, NULL, Definition::kValue); |
| 544 instantiator = new Value(null_constant); | 546 instantiator = new Value(null_constant); |
| 545 type_args = new Value(null_constant); | 547 type_args = new Value(null_constant); |
| 546 ASSERT(value_type.IsDoubleType()); | 548 ASSERT(value_type.IsDoubleType()); |
| 547 ASSERT(value_type.IsInstantiated()); | 549 ASSERT(value_type.IsInstantiated()); |
| 548 break; | 550 break; |
| 549 } | 551 } |
| 550 default: | 552 default: |
| 551 // TODO(fschneider): Add support for other array types. | 553 // TODO(fschneider): Add support for other array types. |
| 552 UNREACHABLE(); | 554 UNREACHABLE(); |
| 553 } | 555 } |
| 554 AssertAssignableInstr* assert_value = | 556 AssertAssignableInstr* assert_value = |
| 555 new AssertAssignableInstr(call->token_pos(), | 557 new AssertAssignableInstr(call->token_pos(), |
| 556 value->Copy(), | 558 value->Copy(), |
| 557 instantiator, | 559 instantiator, |
| 558 type_args, | 560 type_args, |
| 559 value_type, | 561 value_type, |
| 560 String::ZoneHandle(Symbols::New("value"))); | 562 String::ZoneHandle(Symbols::New("value"))); |
| 561 InsertBefore(call, assert_value, NULL, Definition::kValue); | 563 InsertBefore(call, assert_value, NULL, Definition::kValue); |
| 562 } | 564 } |
| 563 | 565 |
| 564 Value* array = NULL; | 566 Value* array = NULL; |
| 565 Value* index = NULL; | 567 Value* index = NULL; |
| 566 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 568 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 567 Value* value = call->ArgumentAt(2)->value(); | 569 Value* value = call->ArgumentAt(2)->value(); |
| 568 // Check if store barrier is needed. | 570 // Check if store barrier is needed. |
| 569 bool needs_store_barrier = true; | 571 bool needs_store_barrier = true; |
| 570 if (class_id == kFloat64ArrayCid) { | 572 if ((class_id == kFloat32ArrayCid) || (class_id == kFloat64ArrayCid)) { |
| 571 ASSERT(!value_check.IsNull()); | 573 ASSERT(!value_check.IsNull()); |
| 572 InsertBefore(call, | 574 InsertBefore(call, |
| 573 new CheckClassInstr(value->Copy(), | 575 new CheckClassInstr(value->Copy(), |
| 574 call->deopt_id(), | 576 call->deopt_id(), |
| 575 value_check), | 577 value_check), |
| 576 call->env(), | 578 call->env(), |
| 577 Definition::kEffect); | 579 Definition::kEffect); |
| 578 needs_store_barrier = false; | 580 needs_store_barrier = false; |
| 579 } else if (ArgIsAlwaysSmi(*call->ic_data(), 2)) { | 581 } else if (ArgIsAlwaysSmi(*call->ic_data(), 2)) { |
| 580 InsertBefore(call, | 582 InsertBefore(call, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 593 } | 595 } |
| 594 | 596 |
| 595 | 597 |
| 596 | 598 |
| 597 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 599 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 598 const intptr_t class_id = ReceiverClassId(call); | 600 const intptr_t class_id = ReceiverClassId(call); |
| 599 switch (class_id) { | 601 switch (class_id) { |
| 600 case kArrayCid: | 602 case kArrayCid: |
| 601 case kImmutableArrayCid: | 603 case kImmutableArrayCid: |
| 602 case kGrowableObjectArrayCid: | 604 case kGrowableObjectArrayCid: |
| 605 case kFloat32ArrayCid: |
| 603 case kFloat64ArrayCid: | 606 case kFloat64ArrayCid: |
| 604 // Acceptable load index classes. | 607 // Acceptable load index classes. |
| 605 break; | 608 break; |
| 606 default: | 609 default: |
| 607 return false; | 610 return false; |
| 608 } | 611 } |
| 609 Value* array = NULL; | 612 Value* array = NULL; |
| 610 Value* index = NULL; | 613 Value* index = NULL; |
| 611 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 614 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 612 Definition* array_op = new LoadIndexedInstr(array, index, array_cid); | 615 Definition* array_op = new LoadIndexedInstr(array, index, array_cid); |
| (...skipping 2858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3471 | 3474 |
| 3472 if (FLAG_trace_constant_propagation) { | 3475 if (FLAG_trace_constant_propagation) { |
| 3473 OS::Print("\n==== After constant propagation ====\n"); | 3476 OS::Print("\n==== After constant propagation ====\n"); |
| 3474 FlowGraphPrinter printer(*graph_); | 3477 FlowGraphPrinter printer(*graph_); |
| 3475 printer.PrintBlocks(); | 3478 printer.PrintBlocks(); |
| 3476 } | 3479 } |
| 3477 } | 3480 } |
| 3478 | 3481 |
| 3479 | 3482 |
| 3480 } // namespace dart | 3483 } // namespace dart |
| OLD | NEW |