| 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(converted); |
| 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 |