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.h" | 10 #include "vm/flow_graph.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 // Handle uses. | 142 // Handle uses. |
143 for (intptr_t j = 0; j < current->InputCount(); j++) { | 143 for (intptr_t j = 0; j < current->InputCount(); j++) { |
144 Value* input = current->InputAt(j); | 144 Value* input = current->InputAt(j); |
145 const intptr_t use = input->definition()->ssa_temp_index(); | 145 const intptr_t use = input->definition()->ssa_temp_index(); |
146 live_in->Add(use); | 146 live_in->Add(use); |
147 } | 147 } |
148 | 148 |
149 // Add non-argument uses from the deoptimization environment (pushed | 149 // Add non-argument uses from the deoptimization environment (pushed |
150 // arguments are not allocated by the register allocator). | 150 // arguments are not allocated by the register allocator). |
151 if (current->env() != NULL) { | 151 if (current->env() != NULL) { |
152 for (intptr_t i = 0; i < current->env()->Length(); ++i) { | 152 for (Environment::DeepIterator env_it(current->env()); |
153 Value* value = current->env()->ValueAt(i); | 153 !env_it.Done(); |
154 if (!value->definition()->IsPushArgument()) { | 154 env_it.Advance()) { |
| 155 Value* value = env_it.CurrentValue(); |
| 156 if (!value->definition()->IsPushArgument() && |
| 157 !value->BindsToConstant()) { |
155 live_in->Add(value->definition()->ssa_temp_index()); | 158 live_in->Add(value->definition()->ssa_temp_index()); |
156 } | 159 } |
157 } | 160 } |
158 } | 161 } |
159 } | 162 } |
160 | 163 |
161 // Handle phis. | 164 // Handle phis. |
162 if (block->IsJoinEntry()) { | 165 if (block->IsJoinEntry()) { |
163 JoinEntryInstr* join = block->AsJoinEntry(); | 166 JoinEntryInstr* join = block->AsJoinEntry(); |
164 if (join->phis() != NULL) { | 167 if (join->phis() != NULL) { |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 | 734 |
732 move_idx++; | 735 move_idx++; |
733 } | 736 } |
734 } | 737 } |
735 } | 738 } |
736 | 739 |
737 | 740 |
738 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, | 741 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
739 Instruction* current) { | 742 Instruction* current) { |
740 ASSERT(current->env() != NULL); | 743 ASSERT(current->env() != NULL); |
| 744 Environment* env = current->env(); |
| 745 while (env != NULL) { |
| 746 // Any value mentioned in the deoptimization environment should survive |
| 747 // until the end of instruction but it does not need to be in the register. |
| 748 // Expected shape of live range: |
| 749 // |
| 750 // i i' |
| 751 // value -----* |
| 752 // |
741 | 753 |
742 Environment* env = current->env(); | 754 if (env->Length() == 0) { |
743 | 755 env = env->outer(); |
744 // Any value mentioned in the deoptimization environment should survive | |
745 // until the end of instruction but it does not need to be in the register. | |
746 // Expected shape of live range: | |
747 // | |
748 // i i' | |
749 // value -----* | |
750 // | |
751 | |
752 if (env->Length() == 0) return; | |
753 | |
754 const intptr_t block_start_pos = block->start_pos(); | |
755 const intptr_t use_pos = current->lifetime_position() + 1; | |
756 | |
757 Location* locations = | |
758 Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); | |
759 | |
760 for (intptr_t i = 0; i < env->Length(); ++i) { | |
761 Value* value = env->ValueAt(i); | |
762 locations[i] = Location::Any(); | |
763 Definition* def = value->definition(); | |
764 | |
765 if (def->IsPushArgument()) { | |
766 // Frame size is unknown until after allocation. | |
767 locations[i] = Location::NoLocation(); | |
768 continue; | 756 continue; |
769 } | 757 } |
770 | 758 |
771 ConstantInstr* constant = def->AsConstant(); | 759 const intptr_t block_start_pos = block->start_pos(); |
772 if (constant != NULL) { | 760 const intptr_t use_pos = current->lifetime_position() + 1; |
773 locations[i] = Location::Constant(constant->value()); | 761 |
774 continue; | 762 Location* locations = |
| 763 Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); |
| 764 |
| 765 for (intptr_t i = 0; i < env->Length(); ++i) { |
| 766 Value* value = env->ValueAt(i); |
| 767 locations[i] = Location::Any(); |
| 768 Definition* def = value->definition(); |
| 769 |
| 770 if (def->IsPushArgument()) { |
| 771 // Frame size is unknown until after allocation. |
| 772 locations[i] = Location::NoLocation(); |
| 773 continue; |
| 774 } |
| 775 |
| 776 ConstantInstr* constant = def->AsConstant(); |
| 777 if (constant != NULL) { |
| 778 locations[i] = Location::Constant(constant->value()); |
| 779 continue; |
| 780 } |
| 781 |
| 782 const intptr_t vreg = def->ssa_temp_index(); |
| 783 LiveRange* range = GetLiveRange(vreg); |
| 784 range->AddUseInterval(block_start_pos, use_pos); |
| 785 range->AddUse(use_pos, &locations[i]); |
775 } | 786 } |
776 | 787 |
777 const intptr_t vreg = def->ssa_temp_index(); | 788 env->set_locations(locations); |
778 LiveRange* range = GetLiveRange(vreg); | 789 env = env->outer(); |
779 range->AddUseInterval(block_start_pos, use_pos); | |
780 range->AddUse(use_pos, &locations[i]); | |
781 } | 790 } |
782 | |
783 env->set_locations(locations); | |
784 } | 791 } |
785 | 792 |
786 | 793 |
787 // Create and update live ranges corresponding to instruction's inputs, | 794 // Create and update live ranges corresponding to instruction's inputs, |
788 // temporaries and output. | 795 // temporaries and output. |
789 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, | 796 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
790 Instruction* current) { | 797 Instruction* current) { |
791 LocationSummary* locs = current->locs(); | 798 LocationSummary* locs = current->locs(); |
792 | 799 |
793 Definition* def = current->AsDefinition(); | 800 Definition* def = current->AsDefinition(); |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 UseInterval* first_after_split = interval; | 1371 UseInterval* first_after_split = interval; |
1365 if (!split_at_start && interval->Contains(split_pos)) { | 1372 if (!split_at_start && interval->Contains(split_pos)) { |
1366 first_after_split = new UseInterval(split_pos, | 1373 first_after_split = new UseInterval(split_pos, |
1367 interval->end(), | 1374 interval->end(), |
1368 interval->next()); | 1375 interval->next()); |
1369 interval->end_ = split_pos; | 1376 interval->end_ = split_pos; |
1370 interval->next_ = first_after_split; | 1377 interval->next_ = first_after_split; |
1371 last_before_split = interval; | 1378 last_before_split = interval; |
1372 } | 1379 } |
1373 | 1380 |
| 1381 ASSERT(last_before_split != NULL); |
1374 ASSERT(last_before_split->next() == first_after_split); | 1382 ASSERT(last_before_split->next() == first_after_split); |
1375 ASSERT(last_before_split->end() <= split_pos); | 1383 ASSERT(last_before_split->end() <= split_pos); |
1376 ASSERT(split_pos <= first_after_split->start()); | 1384 ASSERT(split_pos <= first_after_split->start()); |
1377 | 1385 |
1378 UsePosition* first_use_after_split = | 1386 UsePosition* first_use_after_split = |
1379 SplitListOfPositions(&uses_, split_pos, split_at_start); | 1387 SplitListOfPositions(&uses_, split_pos, split_at_start); |
1380 | 1388 |
1381 SafepointPosition* first_safepoint_after_split = | 1389 SafepointPosition* first_safepoint_after_split = |
1382 SplitListOfPositions(&first_safepoint_, split_pos, split_at_start); | 1390 SplitListOfPositions(&first_safepoint_, split_pos, split_at_start); |
1383 | 1391 |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2206 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2214 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
2207 function.ToFullyQualifiedCString()); | 2215 function.ToFullyQualifiedCString()); |
2208 FlowGraphPrinter printer(flow_graph_, true); | 2216 FlowGraphPrinter printer(flow_graph_, true); |
2209 printer.PrintBlocks(); | 2217 printer.PrintBlocks(); |
2210 OS::Print("----------------------------------------------\n"); | 2218 OS::Print("----------------------------------------------\n"); |
2211 } | 2219 } |
2212 } | 2220 } |
2213 | 2221 |
2214 | 2222 |
2215 } // namespace dart | 2223 } // namespace dart |
OLD | NEW |