| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 | 76 |
| 77 | 77 |
| 78 void FlowGraphAllocator::ComputeInitialSets() { | 78 void FlowGraphAllocator::ComputeInitialSets() { |
| 79 const intptr_t block_count = postorder_.length(); | 79 const intptr_t block_count = postorder_.length(); |
| 80 for (intptr_t i = 0; i < block_count; i++) { | 80 for (intptr_t i = 0; i < block_count; i++) { |
| 81 BlockEntryInstr* block = postorder_[i]; | 81 BlockEntryInstr* block = postorder_[i]; |
| 82 | 82 |
| 83 BitVector* kill = kill_[i]; | 83 BitVector* kill = kill_[i]; |
| 84 BitVector* live_in = live_in_[i]; | 84 BitVector* live_in = live_in_[i]; |
| 85 | 85 |
| 86 if (block->IsJoinEntry()) { | 86 // Iterate backwards starting at the last instruction. |
| 87 JoinEntryInstr* join = block->AsJoinEntry(); | 87 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 88 if (join->phis() != NULL) { | 88 Instruction* current = it.Current(); |
| 89 for (intptr_t j = 0; j < join->phis()->length(); j++) { | |
| 90 PhiInstr* phi = (*join->phis())[j]; | |
| 91 if (phi == NULL) continue; | |
| 92 kill->Add(phi->ssa_temp_index()); | |
| 93 | 89 |
| 94 for (intptr_t k = 0; k < phi->InputCount(); k++) { | 90 // Handle definitions. |
| 95 Value* val = phi->InputAt(k); | 91 Definition* current_def = current->AsDefinition(); |
| 96 if (val->IsUse()) { | 92 if ((current_def != NULL) && current_def->HasSSATemp()) { |
| 97 BlockEntryInstr* pred = block->PredecessorAt(k); | 93 kill->Add(current_def->ssa_temp_index()); |
| 98 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); | 94 live_in->Remove(current_def->ssa_temp_index()); |
| 99 live_out_[pred->postorder_number()]->Add(use); | |
| 100 } | |
| 101 } | |
| 102 } | |
| 103 } | 95 } |
| 104 } | |
| 105 | 96 |
| 106 // TODO(vegorov): iterate backwards. | 97 // Handle uses. |
| 107 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | |
| 108 Instruction* current = it.Current(); | |
| 109 for (intptr_t j = 0; j < current->InputCount(); j++) { | 98 for (intptr_t j = 0; j < current->InputCount(); j++) { |
| 110 Value* input = current->InputAt(j); | 99 Value* input = current->InputAt(j); |
| 111 if (input->IsUse()) { | 100 if (input->IsUse()) { |
| 112 const intptr_t use = input->AsUse()->definition()->ssa_temp_index(); | 101 const intptr_t use = input->AsUse()->definition()->ssa_temp_index(); |
| 113 if (!kill->Contains(use)) live_in->Add(use); | 102 live_in->Add(use); |
| 114 } | 103 } |
| 115 } | 104 } |
| 116 | 105 |
| 117 // Add uses from the deoptimization environment. | 106 // Add uses from the deoptimization environment. |
| 118 if (current->env() != NULL) { | 107 if (current->env() != NULL) { |
| 119 const GrowableArray<Value*>& values = current->env()->values(); | 108 const GrowableArray<Value*>& values = current->env()->values(); |
| 120 for (intptr_t j = 0; j < values.length(); j++) { | 109 for (intptr_t j = 0; j < values.length(); j++) { |
| 121 Value* val = values[j]; | 110 Value* val = values[j]; |
| 122 if (val->IsUse()) { | 111 if (val->IsUse()) { |
| 123 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); | 112 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); |
| 124 if (!kill->Contains(use)) live_in->Add(use); | 113 live_in->Add(use); |
| 125 } | 114 } |
| 126 } | 115 } |
| 127 } | 116 } |
| 117 } |
| 128 | 118 |
| 129 Definition* current_def = current->AsDefinition(); | 119 // Handle phis. |
| 130 if ((current_def != NULL) && (current_def->HasSSATemp())) { | 120 if (block->IsJoinEntry()) { |
| 131 kill->Add(current_def->ssa_temp_index()); | 121 JoinEntryInstr* join = block->AsJoinEntry(); |
| 122 if (join->phis() != NULL) { |
| 123 for (intptr_t j = 0; j < join->phis()->length(); j++) { |
| 124 PhiInstr* phi = (*join->phis())[j]; |
| 125 if (phi == NULL) continue; |
| 126 kill->Add(phi->ssa_temp_index()); |
| 127 live_in->Remove(phi->ssa_temp_index()); |
| 128 |
| 129 for (intptr_t k = 0; k < phi->InputCount(); k++) { |
| 130 Value* val = phi->InputAt(k); |
| 131 if (val->IsUse()) { |
| 132 BlockEntryInstr* pred = block->PredecessorAt(k); |
| 133 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); |
| 134 live_out_[pred->postorder_number()]->Add(use); |
| 135 } |
| 136 } |
| 137 } |
| 132 } | 138 } |
| 133 } | 139 } |
| 134 } | 140 } |
| 135 | 141 |
| 136 // Update initial live_in sets to match live_out sets. Has to be | 142 // Update initial live_in sets to match live_out sets. Has to be |
| 137 // done in a separate path because of backwards branches. | 143 // done in a separate path because of backwards branches. |
| 138 for (intptr_t i = 0; i < block_count; i++) { | 144 for (intptr_t i = 0; i < block_count; i++) { |
| 139 UpdateLiveIn(*postorder_[i]); | 145 UpdateLiveIn(*postorder_[i]); |
| 140 } | 146 } |
| 141 } | 147 } |
| (...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 | 1600 |
| 1595 if (FLAG_trace_ssa_allocator) { | 1601 if (FLAG_trace_ssa_allocator) { |
| 1596 OS::Print("-- ir after allocation -------------------------\n"); | 1602 OS::Print("-- ir after allocation -------------------------\n"); |
| 1597 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 1603 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
| 1598 printer.PrintBlocks(); | 1604 printer.PrintBlocks(); |
| 1599 } | 1605 } |
| 1600 } | 1606 } |
| 1601 | 1607 |
| 1602 | 1608 |
| 1603 } // namespace dart | 1609 } // namespace dart |
| OLD | NEW |