OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 } | 531 } |
532 } | 532 } |
533 } | 533 } |
534 return changed; | 534 return changed; |
535 } | 535 } |
536 | 536 |
537 | 537 |
538 void FlowGraphOptimizer::InsertConversion(Representation from, | 538 void FlowGraphOptimizer::InsertConversion(Representation from, |
539 Representation to, | 539 Representation to, |
540 Value* use, | 540 Value* use, |
541 Instruction* insert_before, | 541 bool is_environment_use) { |
542 Instruction* deopt_target) { | 542 Instruction* insert_before; |
| 543 Instruction* deopt_target; |
| 544 PhiInstr* phi = use->instruction()->AsPhi(); |
| 545 if (phi != NULL) { |
| 546 ASSERT(phi->is_alive()); |
| 547 // For phis conversions have to be inserted in the predecessor. |
| 548 insert_before = |
| 549 phi->block()->PredecessorAt(use->use_index())->last_instruction(); |
| 550 deopt_target = NULL; |
| 551 } else { |
| 552 deopt_target = insert_before = use->instruction(); |
| 553 } |
| 554 |
543 Definition* converted = NULL; | 555 Definition* converted = NULL; |
544 if ((from == kTagged) && (to == kUnboxedMint)) { | 556 if ((from == kTagged) && (to == kUnboxedMint)) { |
545 ASSERT((deopt_target != NULL) || | 557 ASSERT((deopt_target != NULL) || |
546 (use->Type()->ToCid() == kDoubleCid)); | 558 (use->Type()->ToCid() == kDoubleCid)); |
547 const intptr_t deopt_id = (deopt_target != NULL) ? | 559 const intptr_t deopt_id = (deopt_target != NULL) ? |
548 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 560 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
549 converted = new UnboxIntegerInstr(use->CopyWithType(), deopt_id); | 561 converted = new UnboxIntegerInstr(use->CopyWithType(), deopt_id); |
550 | 562 |
551 } else if ((from == kUnboxedMint) && (to == kTagged)) { | 563 } else if ((from == kUnboxedMint) && (to == kTagged)) { |
552 converted = new BoxIntegerInstr(use->CopyWithType()); | 564 converted = new BoxIntegerInstr(use->CopyWithType()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 converted = new UnboxInt32x4Instr(to_value, deopt_id); | 637 converted = new UnboxInt32x4Instr(to_value, deopt_id); |
626 } else if (to == kUnboxedFloat32x4) { | 638 } else if (to == kUnboxedFloat32x4) { |
627 converted = new UnboxFloat32x4Instr(to_value, deopt_id); | 639 converted = new UnboxFloat32x4Instr(to_value, deopt_id); |
628 } else if (to == kUnboxedMint) { | 640 } else if (to == kUnboxedMint) { |
629 converted = new UnboxIntegerInstr(to_value, deopt_id); | 641 converted = new UnboxIntegerInstr(to_value, deopt_id); |
630 } else { | 642 } else { |
631 UNIMPLEMENTED(); | 643 UNIMPLEMENTED(); |
632 } | 644 } |
633 } | 645 } |
634 ASSERT(converted != NULL); | 646 ASSERT(converted != NULL); |
635 use->BindTo(converted); | |
636 InsertBefore(insert_before, converted, use->instruction()->env(), | 647 InsertBefore(insert_before, converted, use->instruction()->env(), |
637 Definition::kValue); | 648 Definition::kValue); |
| 649 if (is_environment_use) { |
| 650 use->BindToEnvironment(); |
| 651 } else { |
| 652 use->BindTo(converted); |
| 653 } |
638 } | 654 } |
639 | 655 |
640 | 656 |
641 void FlowGraphOptimizer::ConvertUse(Value* use, Representation from_rep) { | 657 void FlowGraphOptimizer::ConvertUse(Value* use, Representation from_rep) { |
642 const Representation to_rep = | 658 const Representation to_rep = |
643 use->instruction()->RequiredInputRepresentation(use->use_index()); | 659 use->instruction()->RequiredInputRepresentation(use->use_index()); |
644 if (from_rep == to_rep || to_rep == kNoRepresentation) { | 660 if (from_rep == to_rep || to_rep == kNoRepresentation) { |
645 return; | 661 return; |
646 } | 662 } |
647 | 663 InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ false); |
648 Instruction* insert_before; | |
649 Instruction* deopt_target; | |
650 PhiInstr* phi = use->instruction()->AsPhi(); | |
651 if (phi != NULL) { | |
652 ASSERT(phi->is_alive()); | |
653 // For phis conversions have to be inserted in the predecessor. | |
654 insert_before = | |
655 phi->block()->PredecessorAt(use->use_index())->last_instruction(); | |
656 deopt_target = NULL; | |
657 } else { | |
658 deopt_target = insert_before = use->instruction(); | |
659 } | |
660 | |
661 InsertConversion(from_rep, to_rep, use, insert_before, deopt_target); | |
662 } | 664 } |
663 | 665 |
664 | 666 |
| 667 void FlowGraphOptimizer::ConvertEnvironmentUse(Value* use, |
| 668 Representation from_rep) { |
| 669 const Representation to_rep = kTagged; |
| 670 if (from_rep == to_rep || to_rep == kNoRepresentation) { |
| 671 return; |
| 672 } |
| 673 InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ true); |
| 674 } |
| 675 |
| 676 |
665 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { | 677 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { |
666 const Representation from_rep = def->representation(); | 678 const Representation from_rep = def->representation(); |
667 | 679 |
668 for (Value::Iterator it(def->input_use_list()); | 680 for (Value::Iterator it(def->input_use_list()); |
669 !it.Done(); | 681 !it.Done(); |
670 it.Advance()) { | 682 it.Advance()) { |
671 ConvertUse(it.Current(), from_rep); | 683 ConvertUse(it.Current(), from_rep); |
672 } | 684 } |
| 685 |
| 686 for (Value::Iterator it(def->env_use_list()); |
| 687 !it.Done(); |
| 688 it.Advance()) { |
| 689 Value* use = it.Current(); |
| 690 if (use->instruction()->MayThrow() && |
| 691 use->instruction()->GetBlock()->InsideTryBlock()) { |
| 692 // Environment uses at calls inside try-blocks must be converted to |
| 693 // tagged representation. |
| 694 ConvertEnvironmentUse(it.Current(), from_rep); |
| 695 } |
| 696 } |
673 } | 697 } |
674 | 698 |
675 | 699 |
676 // Returns true if phi's representation was changed. | 700 // Returns true if phi's representation was changed. |
677 static bool UnboxPhi(PhiInstr* phi) { | 701 static bool UnboxPhi(PhiInstr* phi) { |
678 Representation current = phi->representation(); | 702 Representation current = phi->representation(); |
679 Representation unboxed = current; | 703 Representation unboxed = current; |
680 | 704 |
681 switch (phi->Type()->ToCid()) { | 705 switch (phi->Type()->ToCid()) { |
682 case kDoubleCid: | 706 case kDoubleCid: |
(...skipping 4382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5065 // this value is stored in a field, escapes to another function or | 5089 // this value is stored in a field, escapes to another function or |
5066 // participates in a phi. | 5090 // participates in a phi. |
5067 static bool CanBeAliased(AllocateObjectInstr* alloc) { | 5091 static bool CanBeAliased(AllocateObjectInstr* alloc) { |
5068 if (alloc->identity() == AllocateObjectInstr::kUnknown) { | 5092 if (alloc->identity() == AllocateObjectInstr::kUnknown) { |
5069 bool escapes = false; | 5093 bool escapes = false; |
5070 for (Value* use = alloc->input_use_list(); | 5094 for (Value* use = alloc->input_use_list(); |
5071 use != NULL; | 5095 use != NULL; |
5072 use = use->next_use()) { | 5096 use = use->next_use()) { |
5073 Instruction* instr = use->instruction(); | 5097 Instruction* instr = use->instruction(); |
5074 if (instr->IsPushArgument() || | 5098 if (instr->IsPushArgument() || |
5075 (instr->IsStoreVMField() && (use->use_index() != 1)) || | 5099 (instr->IsStoreVMField() |
5076 (instr->IsStoreInstanceField() && (use->use_index() != 0)) || | 5100 && (use->use_index() != StoreVMFieldInstr::kObjectPos)) || |
| 5101 (instr->IsStoreInstanceField() |
| 5102 && (use->use_index() != StoreInstanceFieldInstr::kInstancePos)) || |
5077 instr->IsStoreStaticField() || | 5103 instr->IsStoreStaticField() || |
5078 instr->IsPhi() || | 5104 instr->IsPhi() || |
5079 instr->IsAssertAssignable() || | 5105 instr->IsAssertAssignable() || |
5080 instr->IsRedefinition()) { | 5106 instr->IsRedefinition()) { |
5081 escapes = true; | 5107 escapes = true; |
5082 break; | 5108 break; |
5083 } | 5109 } |
5084 } | 5110 } |
5085 | 5111 |
5086 alloc->set_identity(escapes ? AllocateObjectInstr::kAliased | 5112 alloc->set_identity(escapes ? AllocateObjectInstr::kAliased |
(...skipping 3202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8289 } | 8315 } |
8290 | 8316 |
8291 // Insert materializations at environment uses. | 8317 // Insert materializations at environment uses. |
8292 for (intptr_t i = 0; i < exits.length(); i++) { | 8318 for (intptr_t i = 0; i < exits.length(); i++) { |
8293 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 8319 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
8294 } | 8320 } |
8295 } | 8321 } |
8296 | 8322 |
8297 | 8323 |
8298 } // namespace dart | 8324 } // namespace dart |
OLD | NEW |