| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 Definition* current_def = current->AsDefinition(); | 114 Definition* current_def = current->AsDefinition(); |
| 115 if ((current_def != NULL) && (current_def->ssa_temp_index() >= 0)) { | 115 if ((current_def != NULL) && (current_def->ssa_temp_index() >= 0)) { |
| 116 kill->Add(current_def->ssa_temp_index()); | 116 kill->Add(current_def->ssa_temp_index()); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 // Update initial live_in sets to match live_out sets. Has to be | 121 // Update initial live_in sets to match live_out sets. Has to be |
| 122 // done in a separate path because of backwards branches. | 122 // done in a separate path because of backwards branches. |
| 123 for (intptr_t i = 0; i < block_count; i++) { | 123 for (intptr_t i = 0; i < block_count; i++) { |
| 124 UpdateLiveIn(postorder_[i]); | 124 UpdateLiveIn(*postorder_[i]); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 bool FlowGraphAllocator::UpdateLiveOut(BlockEntryInstr* instr) { | 129 bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) { |
| 130 BitVector* live_out = live_out_[instr->postorder_number()]; | 130 BitVector* live_out = live_out_[instr.postorder_number()]; |
| 131 bool changed = false; | 131 bool changed = false; |
| 132 Instruction* last = instr->last_instruction(); | 132 Instruction* last = instr.last_instruction(); |
| 133 ASSERT(last != NULL); | 133 ASSERT(last != NULL); |
| 134 for (intptr_t i = 0; i < last->SuccessorCount(); i++) { | 134 for (intptr_t i = 0; i < last->SuccessorCount(); i++) { |
| 135 BlockEntryInstr* succ = last->SuccessorAt(i); | 135 BlockEntryInstr* succ = last->SuccessorAt(i); |
| 136 ASSERT(succ != NULL); | 136 ASSERT(succ != NULL); |
| 137 if (live_out->AddAll(live_in_[succ->postorder_number()])) { | 137 if (live_out->AddAll(live_in_[succ->postorder_number()])) { |
| 138 changed = true; | 138 changed = true; |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 return changed; | 141 return changed; |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 bool FlowGraphAllocator::UpdateLiveIn(BlockEntryInstr* instr) { | 145 bool FlowGraphAllocator::UpdateLiveIn(const BlockEntryInstr& instr) { |
| 146 BitVector* live_out = live_out_[instr->postorder_number()]; | 146 BitVector* live_out = live_out_[instr.postorder_number()]; |
| 147 BitVector* kill = kill_[instr->postorder_number()]; | 147 BitVector* kill = kill_[instr.postorder_number()]; |
| 148 BitVector* live_in = live_in_[instr->postorder_number()]; | 148 BitVector* live_in = live_in_[instr.postorder_number()]; |
| 149 return live_in->KillAndAdd(kill, live_out); | 149 return live_in->KillAndAdd(kill, live_out); |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() { | 153 void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() { |
| 154 const intptr_t block_count = postorder_.length(); | 154 const intptr_t block_count = postorder_.length(); |
| 155 bool changed; | 155 bool changed; |
| 156 do { | 156 do { |
| 157 changed = false; | 157 changed = false; |
| 158 | 158 |
| 159 for (intptr_t i = 0; i < block_count; i++) { | 159 for (intptr_t i = 0; i < block_count; i++) { |
| 160 BlockEntryInstr* block = postorder_[i]; | 160 const BlockEntryInstr& block = *postorder_[i]; |
| 161 | 161 |
| 162 // Live-in set depends only on kill set which does not | 162 // Live-in set depends only on kill set which does not |
| 163 // change in this loop and live-out set. If live-out | 163 // change in this loop and live-out set. If live-out |
| 164 // set does not change there is no need to recompute | 164 // set does not change there is no need to recompute |
| 165 // live-in set. | 165 // live-in set. |
| 166 if (UpdateLiveOut(block) && UpdateLiveIn(block)) { | 166 if (UpdateLiveOut(block) && UpdateLiveIn(block)) { |
| 167 changed = true; | 167 changed = true; |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 } while (changed); | 170 } while (changed); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // instruction numbers to parallel moves. | 404 // instruction numbers to parallel moves. |
| 405 ParallelMoveInstr* parallel_move = current->AsParallelMove(); | 405 ParallelMoveInstr* parallel_move = current->AsParallelMove(); |
| 406 if (parallel_move != NULL) { | 406 if (parallel_move != NULL) { |
| 407 JoinEntryInstr* join = goto_instr->successor(); | 407 JoinEntryInstr* join = goto_instr->successor(); |
| 408 ASSERT(join != NULL); | 408 ASSERT(join != NULL); |
| 409 | 409 |
| 410 // Search for the index of the current block in the predecessors of | 410 // Search for the index of the current block in the predecessors of |
| 411 // the join. | 411 // the join. |
| 412 // TODO(kmillikin): record the predecessor index in the goto when | 412 // TODO(kmillikin): record the predecessor index in the goto when |
| 413 // building the predecessor list to avoid this search. | 413 // building the predecessor list to avoid this search. |
| 414 intptr_t pred_idx = 0; | 414 intptr_t pred_idx = join->IndexOfPredecessor(block); |
| 415 for (; pred_idx < join->PredecessorCount(); pred_idx++) { | 415 ASSERT(pred_idx >= 0); |
| 416 if (join->PredecessorAt(pred_idx) == block) break; | |
| 417 } | |
| 418 ASSERT(pred_idx < join->PredecessorCount()); | |
| 419 | 416 |
| 420 // Record the corresponding phi input use for each phi. | 417 // Record the corresponding phi input use for each phi. |
| 421 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); | 418 ZoneGrowableArray<PhiInstr*>* phis = join->phis(); |
| 422 intptr_t move_idx = 0; | 419 intptr_t move_idx = 0; |
| 423 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { | 420 for (intptr_t phi_idx = 0; phi_idx < phis->length(); phi_idx++) { |
| 424 PhiInstr* phi = (*phis)[phi_idx]; | 421 PhiInstr* phi = (*phis)[phi_idx]; |
| 425 if (phi == NULL) continue; | 422 if (phi == NULL) continue; |
| 426 | 423 |
| 427 Value* val = phi->InputAt(pred_idx); | 424 Value* val = phi->InputAt(pred_idx); |
| 428 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); | 425 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 FinalizeInterval(a, | 854 FinalizeInterval(a, |
| 858 Location::RegisterLocation(static_cast<Register>(reg))); | 855 Location::RegisterLocation(static_cast<Register>(reg))); |
| 859 a = a->next_allocated(); | 856 a = a->next_allocated(); |
| 860 } | 857 } |
| 861 | 858 |
| 862 cpu_regs_[reg] = a; | 859 cpu_regs_[reg] = a; |
| 863 } | 860 } |
| 864 } | 861 } |
| 865 | 862 |
| 866 | 863 |
| 867 static inline bool ShouldBeAllocatedBefore(UseInterval* a, UseInterval* b) { | 864 static inline bool ShouldBeAllocatedBefore(const UseInterval& a, |
| 868 return a->start() <= b->start(); | 865 const UseInterval& b) { |
| 866 return a.start() <= b.start(); |
| 869 } | 867 } |
| 870 | 868 |
| 871 | 869 |
| 872 void FlowGraphAllocator::AddToUnallocated(UseInterval* chain) { | 870 void FlowGraphAllocator::AddToUnallocated(UseInterval* chain) { |
| 873 if (unallocated_.is_empty()) { | 871 if (unallocated_.is_empty()) { |
| 874 unallocated_.Add(chain); | 872 unallocated_.Add(chain); |
| 875 return; | 873 return; |
| 876 } | 874 } |
| 877 | 875 |
| 878 for (intptr_t i = unallocated_.length() - 1; i >= 0; i--) { | 876 for (intptr_t i = unallocated_.length() - 1; i >= 0; i--) { |
| 879 if (ShouldBeAllocatedBefore(chain, unallocated_[i])) { | 877 if (ShouldBeAllocatedBefore(*chain, *unallocated_[i])) { |
| 880 unallocated_.InsertAt(i + 1, chain); | 878 unallocated_.InsertAt(i + 1, chain); |
| 881 return; | 879 return; |
| 882 } | 880 } |
| 883 } | 881 } |
| 884 unallocated_.InsertAt(0, chain); | 882 unallocated_.InsertAt(0, chain); |
| 885 } | 883 } |
| 886 | 884 |
| 887 | 885 |
| 888 bool FlowGraphAllocator::UnallocatedIsSorted() { | 886 bool FlowGraphAllocator::UnallocatedIsSorted() { |
| 889 for (intptr_t i = unallocated_.length() - 1; i >= 1; i--) { | 887 for (intptr_t i = unallocated_.length() - 1; i >= 1; i--) { |
| 890 UseInterval* a = unallocated_[i]; | 888 UseInterval* a = unallocated_[i]; |
| 891 UseInterval* b = unallocated_[i - 1]; | 889 UseInterval* b = unallocated_[i - 1]; |
| 892 if (!ShouldBeAllocatedBefore(a, b)) return false; | 890 if (!ShouldBeAllocatedBefore(*a, *b)) return false; |
| 893 } | 891 } |
| 894 return true; | 892 return true; |
| 895 } | 893 } |
| 896 | 894 |
| 897 | 895 |
| 898 void FlowGraphAllocator::AllocateCPURegisters() { | 896 void FlowGraphAllocator::AllocateCPURegisters() { |
| 899 ASSERT(UnallocatedIsSorted()); | 897 ASSERT(UnallocatedIsSorted()); |
| 900 | 898 |
| 901 while (!unallocated_.is_empty()) { | 899 while (!unallocated_.is_empty()) { |
| 902 UseInterval* range = unallocated_.Last(); | 900 UseInterval* range = unallocated_.Last(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 | 948 |
| 951 if (FLAG_trace_ssa_allocator) { | 949 if (FLAG_trace_ssa_allocator) { |
| 952 OS::Print("-- ir after allocation -------------------------\n"); | 950 OS::Print("-- ir after allocation -------------------------\n"); |
| 953 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 951 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
| 954 printer.PrintBlocks(); | 952 printer.PrintBlocks(); |
| 955 } | 953 } |
| 956 } | 954 } |
| 957 | 955 |
| 958 | 956 |
| 959 } // namespace dart | 957 } // namespace dart |
| OLD | NEW |