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_allocator.h" | 5 #include "vm/flow_graph_allocator.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 #include "vm/il_printer.h" | 9 #include "vm/il_printer.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 93 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
94 Instruction* current = it.Current(); | 94 Instruction* current = it.Current(); |
95 if (current->CanDeoptimize()) { | 95 if (current->CanDeoptimize()) { |
96 ASSERT(current->env() != NULL); | 96 ASSERT(current->env() != NULL); |
97 GrowableArray<Value*>* values = current->env()->values_ptr(); | 97 GrowableArray<Value*>* values = current->env()->values_ptr(); |
98 | 98 |
99 for (intptr_t i = 0; i < values->length(); i++) { | 99 for (intptr_t i = 0; i < values->length(); i++) { |
100 UseVal* use = (*values)[i]->AsUse(); | 100 UseVal* use = (*values)[i]->AsUse(); |
101 if (use == NULL) continue; | 101 if (use == NULL) continue; |
102 | 102 |
103 PhiInstr* phi = use->definition()->AsPhi(); | 103 Definition* def = use->definition(); |
104 if (phi == NULL) continue; | |
105 | 104 |
106 if (!phi->is_alive()) (*values)[i] = null_value; | 105 PushArgumentInstr* push_argument = def->AsPushArgument(); |
106 if ((push_argument != NULL) && push_argument->WasEliminated()) { | |
107 (*values)[i] = push_argument->value(); | |
108 continue; | |
109 } | |
110 | |
111 PhiInstr* phi = def->AsPhi(); | |
112 if ((phi != NULL) && !phi->is_alive()) { | |
113 (*values)[i] = null_value; | |
114 continue; | |
115 } | |
107 } | 116 } |
108 } else { | 117 } else { |
109 current->set_env(NULL); | 118 current->set_env(NULL); |
110 } | 119 } |
111 } | 120 } |
112 } | 121 } |
113 } | 122 } |
114 | 123 |
115 | 124 |
116 void FlowGraphAllocator::ComputeInitialSets() { | 125 void FlowGraphAllocator::ComputeInitialSets() { |
(...skipping 21 matching lines...) Expand all Loading... | |
138 if (input->IsUse()) { | 147 if (input->IsUse()) { |
139 const intptr_t use = input->AsUse()->definition()->ssa_temp_index(); | 148 const intptr_t use = input->AsUse()->definition()->ssa_temp_index(); |
140 live_in->Add(use); | 149 live_in->Add(use); |
141 } | 150 } |
142 } | 151 } |
143 | 152 |
144 // Add uses from the deoptimization environment. | 153 // Add uses from the deoptimization environment. |
145 if (current->env() != NULL) { | 154 if (current->env() != NULL) { |
146 const GrowableArray<Value*>& values = current->env()->values(); | 155 const GrowableArray<Value*>& values = current->env()->values(); |
147 for (intptr_t j = 0; j < values.length(); j++) { | 156 for (intptr_t j = 0; j < values.length(); j++) { |
148 Value* val = values[j]; | 157 Value* val = values[j]; |
srdjan
2012/08/09 20:25:26
I think this looks simpler :
UseVal* use_val = va
Vyacheslav Egorov (Google)
2012/08/10 14:27:46
Agreed.
| |
149 if (val->IsUse()) { | 158 if (!val->IsUse()) continue; |
150 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); | 159 |
151 live_in->Add(use); | 160 Definition* def = val->AsUse()->definition(); |
152 } | 161 if (def->IsPushArgument()) continue; |
162 | |
163 live_in->Add(def->ssa_temp_index()); | |
153 } | 164 } |
154 } | 165 } |
155 } | 166 } |
156 | 167 |
157 // Handle phis. | 168 // Handle phis. |
158 if (block->IsJoinEntry()) { | 169 if (block->IsJoinEntry()) { |
159 JoinEntryInstr* join = block->AsJoinEntry(); | 170 JoinEntryInstr* join = block->AsJoinEntry(); |
160 if (join->phis() != NULL) { | 171 if (join->phis() != NULL) { |
161 for (intptr_t j = 0; j < join->phis()->length(); j++) { | 172 for (intptr_t j = 0; j < join->phis()->length(); j++) { |
162 PhiInstr* phi = (*join->phis())[j]; | 173 PhiInstr* phi = (*join->phis())[j]; |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 // All phi resolution moves are connected. Phi's live range is | 660 // All phi resolution moves are connected. Phi's live range is |
650 // complete. | 661 // complete. |
651 AddToUnallocated(range); | 662 AddToUnallocated(range); |
652 | 663 |
653 move_idx++; | 664 move_idx++; |
654 } | 665 } |
655 } | 666 } |
656 } | 667 } |
657 | 668 |
658 | 669 |
670 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, | |
671 Instruction* current) { | |
672 ASSERT(current->env() != NULL); | |
673 | |
674 Environment* env = current->env(); | |
675 | |
676 // Any value mentioned in the deoptimization environment should survive | |
677 // until the end of instruction but it does not need to be in the register. | |
678 // Expected shape of live range: | |
679 // | |
680 // i i' | |
681 // value -----* | |
682 // | |
683 | |
684 const GrowableArray<Value*>& values = env->values(); | |
685 if (values.length() == 0) return; | |
686 | |
687 const intptr_t block_start_pos = block->start_pos(); | |
688 const intptr_t use_pos = current->lifetime_position() + 1; | |
689 | |
690 Location* locations = | |
691 Isolate::Current()->current_zone()->Alloc<Location>(values.length()); | |
692 | |
693 for (intptr_t i = 0; i < values.length(); ++i) { | |
694 Value* value = values[i]; | |
695 if (value->IsUse()) { | |
696 locations[i] = Location::Any(); | |
697 Definition* def = value->AsUse()->definition(); | |
698 | |
699 if (def->IsPushArgument()) { | |
700 // Frame size is unknown until after allocation. | |
701 locations[i] = Location::NoLocation(); | |
702 continue; | |
703 } | |
704 | |
705 const intptr_t vreg = def->ssa_temp_index(); | |
706 LiveRange* range = GetLiveRange(vreg); | |
707 range->AddUseInterval(block_start_pos, use_pos); | |
708 range->AddUse(use_pos, &locations[i]); | |
709 } else { | |
710 ASSERT(value->IsConstant()); | |
711 locations[i] = Location::NoLocation(); | |
712 } | |
713 } | |
714 | |
715 env->set_locations(locations); | |
716 } | |
717 | |
718 | |
659 // Create and update live ranges corresponding to instruction's inputs, | 719 // Create and update live ranges corresponding to instruction's inputs, |
660 // temporaries and output. | 720 // temporaries and output. |
661 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, | 721 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
662 Instruction* current) { | 722 Instruction* current) { |
663 const intptr_t pos = current->lifetime_position(); | 723 const intptr_t pos = current->lifetime_position(); |
664 ASSERT(IsInstructionStartPosition(pos)); | 724 ASSERT(IsInstructionStartPosition(pos)); |
665 | 725 |
666 LocationSummary* locs = current->locs(); | 726 LocationSummary* locs = current->locs(); |
667 | 727 |
668 // TODO(vegorov): number of inputs must match number of input locations. | 728 // TODO(vegorov): number of inputs must match number of input locations. |
669 if (locs->input_count() != current->InputCount()) { | 729 if (locs->input_count() != current->InputCount()) { |
670 builder_->Bailout("ssa allocator: number of input locations mismatch"); | 730 builder_->Bailout("ssa allocator: number of input locations mismatch"); |
671 } | 731 } |
672 | 732 |
673 // Normalize same-as-first-input output if input is specified as | 733 // Normalize same-as-first-input output if input is specified as |
674 // fixed register. | 734 // fixed register. |
675 if (locs->out().IsUnallocated() && | 735 if (locs->out().IsUnallocated() && |
676 (locs->out().policy() == Location::kSameAsFirstInput) && | 736 (locs->out().policy() == Location::kSameAsFirstInput) && |
677 (locs->in(0).IsRegister())) { | 737 (locs->in(0).IsRegister())) { |
678 locs->set_out(locs->in(0)); | 738 locs->set_out(locs->in(0)); |
679 } | 739 } |
680 | 740 |
681 const bool output_same_as_first_input = | 741 const bool output_same_as_first_input = |
682 locs->out().IsUnallocated() && | 742 locs->out().IsUnallocated() && |
683 (locs->out().policy() == Location::kSameAsFirstInput); | 743 (locs->out().policy() == Location::kSameAsFirstInput); |
684 | 744 |
685 // Add uses from the deoptimization environment. | 745 // Add uses from the deoptimization environment. |
686 Environment* env = current->env(); | 746 if (current->env() != NULL) ProcessEnvironmentUses(block, current); |
687 if (env != NULL) { | |
688 env->InitializeLocations(this, block->start_pos(), pos + 1); | |
689 } | |
690 | 747 |
691 // Process inputs. | 748 // Process inputs. |
692 // Skip the first input if output is specified with kSameAsFirstInput policy, | 749 // Skip the first input if output is specified with kSameAsFirstInput policy, |
693 // they will be processed together at the very end. | 750 // they will be processed together at the very end. |
694 for (intptr_t j = output_same_as_first_input ? 1 : 0; | 751 for (intptr_t j = output_same_as_first_input ? 1 : 0; |
695 j < current->InputCount(); | 752 j < current->InputCount(); |
696 j++) { | 753 j++) { |
697 Value* input = current->InputAt(j); | 754 Value* input = current->InputAt(j); |
698 ASSERT(input->IsUse()); // Can not be a constant currently. | 755 ASSERT(input->IsUse()); // Can not be a constant currently. |
699 const intptr_t vreg = input->AsUse()->definition()->ssa_temp_index(); | 756 const intptr_t vreg = input->AsUse()->definition()->ssa_temp_index(); |
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1887 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 1944 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
1888 function.ToFullyQualifiedCString()); | 1945 function.ToFullyQualifiedCString()); |
1889 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 1946 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
1890 printer.PrintBlocks(); | 1947 printer.PrintBlocks(); |
1891 OS::Print("----------------------------------------------\n"); | 1948 OS::Print("----------------------------------------------\n"); |
1892 } | 1949 } |
1893 } | 1950 } |
1894 | 1951 |
1895 | 1952 |
1896 } // namespace dart | 1953 } // namespace dart |
OLD | NEW |