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_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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 } | 215 } |
216 } | 216 } |
217 } | 217 } |
218 } | 218 } |
219 } | 219 } |
220 | 220 |
221 // Handle phis. | 221 // Handle phis. |
222 if (block->IsJoinEntry()) { | 222 if (block->IsJoinEntry()) { |
223 JoinEntryInstr* join = block->AsJoinEntry(); | 223 JoinEntryInstr* join = block->AsJoinEntry(); |
224 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 224 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
225 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
226 PhiInstr* phi = it.Current(); | 225 PhiInstr* phi = it.Current(); |
227 ASSERT(phi != NULL); | 226 ASSERT(phi != NULL); |
228 kill->Add(phi->ssa_temp_index()); | 227 kill->Add(phi->ssa_temp_index()); |
229 live_in->Remove(phi->ssa_temp_index()); | 228 live_in->Remove(phi->ssa_temp_index()); |
229 if (phi->HasPairRepresentation()) { | |
230 kill->Add(ToSecondPairVreg(phi->ssa_temp_index())); | |
231 live_in->Remove(ToSecondPairVreg(phi->ssa_temp_index())); | |
232 } | |
230 | 233 |
231 // If a phi input is not defined by the corresponding predecessor it | 234 // If a phi input is not defined by the corresponding predecessor it |
232 // must be marked live-in for that predecessor. | 235 // must be marked live-in for that predecessor. |
233 for (intptr_t k = 0; k < phi->InputCount(); k++) { | 236 for (intptr_t k = 0; k < phi->InputCount(); k++) { |
234 Value* val = phi->InputAt(k); | 237 Value* val = phi->InputAt(k); |
235 if (val->BindsToConstant()) continue; | 238 if (val->BindsToConstant()) continue; |
236 | 239 |
237 BlockEntryInstr* pred = block->PredecessorAt(k); | 240 BlockEntryInstr* pred = block->PredecessorAt(k); |
238 const intptr_t use = val->definition()->ssa_temp_index(); | 241 const intptr_t use = val->definition()->ssa_temp_index(); |
239 if (!kill_[pred->postorder_number()]->Contains(use)) { | 242 if (!kill_[pred->postorder_number()]->Contains(use)) { |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 ParallelMoveInstr* parallel_move = goto_instr->parallel_move(); | 770 ParallelMoveInstr* parallel_move = goto_instr->parallel_move(); |
768 | 771 |
769 // All uses are recorded at the position of parallel move preceding goto. | 772 // All uses are recorded at the position of parallel move preceding goto. |
770 const intptr_t pos = goto_instr->lifetime_position(); | 773 const intptr_t pos = goto_instr->lifetime_position(); |
771 | 774 |
772 JoinEntryInstr* join = goto_instr->successor(); | 775 JoinEntryInstr* join = goto_instr->successor(); |
773 ASSERT(join != NULL); | 776 ASSERT(join != NULL); |
774 | 777 |
775 // Search for the index of the current block in the predecessors of | 778 // Search for the index of the current block in the predecessors of |
776 // the join. | 779 // the join. |
777 const intptr_t pred_idx = join->IndexOfPredecessor(block); | 780 const intptr_t pred_index = join->IndexOfPredecessor(block); |
778 | 781 |
779 // Record the corresponding phi input use for each phi. | 782 // Record the corresponding phi input use for each phi. |
780 intptr_t move_idx = 0; | 783 intptr_t move_index = 0; |
781 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 784 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
782 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
783 PhiInstr* phi = it.Current(); | 785 PhiInstr* phi = it.Current(); |
784 Value* val = phi->InputAt(pred_idx); | 786 Value* val = phi->InputAt(pred_index); |
785 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); | 787 MoveOperands* move = parallel_move->MoveOperandsAt(move_index++); |
786 | 788 |
787 ConstantInstr* constant = val->definition()->AsConstant(); | 789 ConstantInstr* constant = val->definition()->AsConstant(); |
788 if (constant != NULL) { | 790 if (constant != NULL) { |
789 move->set_src(Location::Constant(constant)); | 791 move->set_src(Location::Constant(constant)); |
790 move_idx++; | |
791 continue; | 792 continue; |
792 } | 793 } |
793 | 794 |
794 // Expected shape of live ranges: | 795 // Expected shape of live ranges: |
795 // | 796 // |
796 // g g' | 797 // g g' |
797 // value --* | 798 // value --* |
798 // | 799 // |
799 | 800 intptr_t vreg = val->definition()->ssa_temp_index(); |
800 const intptr_t vreg = val->definition()->ssa_temp_index(); | |
801 LiveRange* range = GetLiveRange(vreg); | 801 LiveRange* range = GetLiveRange(vreg); |
802 if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg); | 802 if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg); |
803 | 803 |
804 range->AddUseInterval(block->start_pos(), pos); | 804 range->AddUseInterval(block->start_pos(), pos); |
805 range->AddHintedUse( | 805 range->AddHintedUse( |
806 pos, | 806 pos, |
807 move->src_slot(), | 807 move->src_slot(), |
808 GetLiveRange(phi->ssa_temp_index())->assigned_location_slot()); | 808 GetLiveRange(phi->ssa_temp_index())->assigned_location_slot()); |
809 move->set_src(Location::PrefersRegister()); | |
809 | 810 |
810 move->set_src(Location::PrefersRegister()); | 811 if (val->definition()->HasPairRepresentation()) { |
811 move_idx++; | 812 move = parallel_move->MoveOperandsAt(move_index++); |
813 vreg = ToSecondPairVreg(vreg); | |
814 range = GetLiveRange(vreg); | |
Cutch
2015/10/01 17:27:41
This code is the same as the first vreg code. Coul
Florian Schneider
2015/10/01 18:27:38
It would need to take vreg, block, interfere_at_ba
| |
815 if (interfere_at_backedge != NULL) { | |
816 interfere_at_backedge->Add(vreg); | |
817 } | |
818 range->AddUseInterval(block->start_pos(), pos); | |
819 range->AddHintedUse( | |
820 pos, | |
821 move->src_slot(), | |
822 GetLiveRange(ToSecondPairVreg( | |
823 phi->ssa_temp_index()))->assigned_location_slot()); | |
824 move->set_src(Location::PrefersRegister()); | |
825 } | |
812 } | 826 } |
813 | 827 |
814 // Begin backward iteration with the instruction before the parallel | 828 // Begin backward iteration with the instruction before the parallel |
815 // move. | 829 // move. |
816 return goto_instr->previous(); | 830 return goto_instr->previous(); |
817 } | 831 } |
818 | 832 |
819 | 833 |
820 void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) { | 834 void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) { |
821 // For join blocks we need to add destinations of phi resolution moves | 835 // For join blocks we need to add destinations of phi resolution moves |
822 // to phi's live range so that register allocator will fill them with moves. | 836 // to phi's live range so that register allocator will fill them with moves. |
823 | 837 |
824 // All uses are recorded at the start position in the block. | 838 // All uses are recorded at the start position in the block. |
825 const intptr_t pos = join->start_pos(); | 839 const intptr_t pos = join->start_pos(); |
826 const bool is_loop_header = BlockInfoAt(join->start_pos())->is_loop_header(); | 840 const bool is_loop_header = BlockInfoAt(join->start_pos())->is_loop_header(); |
827 intptr_t move_idx = 0; | 841 intptr_t move_idx = 0; |
828 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 842 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
829 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
830 PhiInstr* phi = it.Current(); | 843 PhiInstr* phi = it.Current(); |
831 ASSERT(phi != NULL); | 844 ASSERT(phi != NULL); |
832 const intptr_t vreg = phi->ssa_temp_index(); | 845 const intptr_t vreg = phi->ssa_temp_index(); |
833 ASSERT(vreg >= 0); | 846 ASSERT(vreg >= 0); |
847 bool is_pair_phi = phi->HasPairRepresentation(); | |
Cutch
2015/10/01 17:27:41
const bool....
Florian Schneider
2015/10/01 18:27:39
Done.
| |
834 | 848 |
835 // Expected shape of live range: | 849 // Expected shape of live range: |
836 // | 850 // |
837 // B | 851 // B |
838 // phi [-------- | 852 // phi [-------- |
839 // | 853 // |
840 LiveRange* range = GetLiveRange(vreg); | 854 LiveRange* range = GetLiveRange(vreg); |
841 range->DefineAt(pos); // Shorten live range. | 855 range->DefineAt(pos); // Shorten live range. |
856 if (is_loop_header) range->mark_loop_phi(); | |
842 | 857 |
843 if (is_loop_header) range->mark_loop_phi(); | 858 if (is_pair_phi) { |
859 LiveRange* range = GetLiveRange(ToSecondPairVreg(vreg)); | |
Cutch
2015/10/01 17:27:41
Could you rename range here, it is confusing that
Florian Schneider
2015/10/01 18:27:38
Otoh, it prevents from accidentally using the oute
| |
860 range->DefineAt(pos); // Shorten live range. | |
861 if (is_loop_header) range->mark_loop_phi(); | |
862 } | |
844 | 863 |
845 for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) { | 864 for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) { |
846 BlockEntryInstr* pred = join->PredecessorAt(pred_idx); | 865 BlockEntryInstr* pred = join->PredecessorAt(pred_idx); |
847 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); | 866 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); |
848 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); | 867 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); |
849 MoveOperands* move = | 868 MoveOperands* move = |
850 goto_instr->parallel_move()->MoveOperandsAt(move_idx); | 869 goto_instr->parallel_move()->MoveOperandsAt(move_idx); |
851 move->set_dest(Location::PrefersRegister()); | 870 move->set_dest(Location::PrefersRegister()); |
852 range->AddUse(pos, move->dest_slot()); | 871 range->AddUse(pos, move->dest_slot()); |
872 if (is_pair_phi) { | |
873 LiveRange* range = GetLiveRange(ToSecondPairVreg(vreg)); | |
874 MoveOperands* move = | |
875 goto_instr->parallel_move()->MoveOperandsAt(move_idx + 1); | |
Cutch
2015/10/01 17:27:41
More duplicate code- how difficult would be to fac
Florian Schneider
2015/10/01 18:27:38
Same as above... I think 2 common lines don't seem
| |
876 move->set_dest(Location::PrefersRegister()); | |
877 range->AddUse(pos, move->dest_slot()); | |
878 } | |
853 } | 879 } |
854 | 880 |
855 // All phi resolution moves are connected. Phi's live range is | 881 // All phi resolution moves are connected. Phi's live range is |
856 // complete. | 882 // complete. |
857 AssignSafepoints(phi, range); | 883 AssignSafepoints(phi, range); |
884 CompleteRange(range, RegisterKindForResult(phi)); | |
885 if (is_pair_phi) { | |
886 LiveRange* range = GetLiveRange(ToSecondPairVreg(vreg)); | |
Cutch
2015/10/01 17:27:41
This shadow of range confused me.
Florian Schneider
2015/10/01 18:27:38
I can rename it.
| |
887 AssignSafepoints(phi, range); | |
888 CompleteRange(range, RegisterKindForResult(phi)); | |
889 } | |
858 | 890 |
859 CompleteRange(range, RegisterKindForResult(phi)); | 891 move_idx += is_pair_phi ? 2 : 1; |
860 | |
861 move_idx++; | |
862 } | 892 } |
863 } | 893 } |
864 | 894 |
865 | 895 |
866 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, | 896 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
867 Instruction* current) { | 897 Instruction* current) { |
868 ASSERT(current->env() != NULL); | 898 ASSERT(current->env() != NULL); |
869 Environment* env = current->env(); | 899 Environment* env = current->env(); |
870 while (env != NULL) { | 900 while (env != NULL) { |
871 // Any value mentioned in the deoptimization environment should survive | 901 // Any value mentioned in the deoptimization environment should survive |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1492 } | 1522 } |
1493 | 1523 |
1494 // Create parallel moves in join predecessors. This must be done after | 1524 // Create parallel moves in join predecessors. This must be done after |
1495 // all instructions are numbered. | 1525 // all instructions are numbered. |
1496 for (intptr_t i = block_count - 1; i >= 0; i--) { | 1526 for (intptr_t i = block_count - 1; i >= 0; i--) { |
1497 BlockEntryInstr* block = postorder_[i]; | 1527 BlockEntryInstr* block = postorder_[i]; |
1498 | 1528 |
1499 // For join entry predecessors create phi resolution moves if | 1529 // For join entry predecessors create phi resolution moves if |
1500 // necessary. They will be populated by the register allocator. | 1530 // necessary. They will be populated by the register allocator. |
1501 JoinEntryInstr* join = block->AsJoinEntry(); | 1531 JoinEntryInstr* join = block->AsJoinEntry(); |
1502 if ((join != NULL) && | 1532 if (join != NULL) { |
1503 (join->phis() != NULL) && | 1533 intptr_t move_count = 0; |
1504 !join->phis()->is_empty()) { | 1534 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
1505 const intptr_t phi_count = join->phis()->length(); | 1535 move_count += it.Current()->HasPairRepresentation() ? 2 : 1; |
1536 } | |
1506 for (intptr_t i = 0; i < block->PredecessorCount(); i++) { | 1537 for (intptr_t i = 0; i < block->PredecessorCount(); i++) { |
1507 // Insert the move between the last two instructions of the | 1538 // Insert the move between the last two instructions of the |
1508 // predecessor block (all such blocks have at least two instructions: | 1539 // predecessor block (all such blocks have at least two instructions: |
1509 // the block entry and goto instructions.) | 1540 // the block entry and goto instructions.) |
1510 Instruction* last = block->PredecessorAt(i)->last_instruction(); | 1541 Instruction* last = block->PredecessorAt(i)->last_instruction(); |
1511 ASSERT(last->IsGoto()); | 1542 ASSERT(last->IsGoto()); |
1512 | 1543 |
1513 ParallelMoveInstr* move = last->AsGoto()->GetParallelMove(); | 1544 ParallelMoveInstr* move = last->AsGoto()->GetParallelMove(); |
1514 | 1545 |
1515 // Populate the ParallelMove with empty moves. | 1546 // Populate the ParallelMove with empty moves. |
1516 for (intptr_t j = 0; j < phi_count; j++) { | 1547 for (intptr_t j = 0; j < move_count; j++) { |
1517 move->AddMove(Location::NoLocation(), Location::NoLocation()); | 1548 move->AddMove(Location::NoLocation(), Location::NoLocation()); |
1518 } | 1549 } |
1519 } | 1550 } |
1520 } | 1551 } |
1521 } | 1552 } |
1522 } | 1553 } |
1523 | 1554 |
1524 | 1555 |
1525 // Discover structural (reducible) loops nesting structure. | 1556 // Discover structural (reducible) loops nesting structure. |
1526 void FlowGraphAllocator::DiscoverLoops() { | 1557 void FlowGraphAllocator::DiscoverLoops() { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2016 const intptr_t pos = FirstIntersection( | 2047 const intptr_t pos = FirstIntersection( |
2017 unallocated->finger()->first_pending_use_interval(), | 2048 unallocated->finger()->first_pending_use_interval(), |
2018 allocated_head); | 2049 allocated_head); |
2019 if (pos < intersection) intersection = pos; | 2050 if (pos < intersection) intersection = pos; |
2020 } | 2051 } |
2021 return intersection; | 2052 return intersection; |
2022 } | 2053 } |
2023 | 2054 |
2024 | 2055 |
2025 void ReachingDefs::AddPhi(PhiInstr* phi) { | 2056 void ReachingDefs::AddPhi(PhiInstr* phi) { |
2026 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2027 if (phi->reaching_defs() == NULL) { | 2057 if (phi->reaching_defs() == NULL) { |
2028 Zone* zone = flow_graph_.zone(); | 2058 Zone* zone = flow_graph_.zone(); |
2029 phi->set_reaching_defs(new(zone) BitVector( | 2059 phi->set_reaching_defs(new(zone) BitVector( |
2030 zone, flow_graph_.max_virtual_register_number())); | 2060 zone, flow_graph_.max_virtual_register_number())); |
2031 | 2061 |
2032 // Compute initial set reaching defs set. | 2062 // Compute initial set reaching defs set. |
2033 bool depends_on_phi = false; | 2063 bool depends_on_phi = false; |
2034 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 2064 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
2035 Definition* input = phi->InputAt(i)->definition(); | 2065 Definition* input = phi->InputAt(i)->definition(); |
2036 if (input->IsPhi()) { | 2066 if (input->IsPhi()) { |
2037 depends_on_phi = true; | 2067 depends_on_phi = true; |
2038 } | 2068 } |
2039 phi->reaching_defs()->Add(input->ssa_temp_index()); | 2069 phi->reaching_defs()->Add(input->ssa_temp_index()); |
2070 if (phi->HasPairRepresentation()) { | |
2071 phi->reaching_defs()->Add(ToSecondPairVreg(input->ssa_temp_index())); | |
2072 } | |
2040 } | 2073 } |
2041 | 2074 |
2042 // If this phi depends on another phi then we need fix point iteration. | 2075 // If this phi depends on another phi then we need fix point iteration. |
2043 if (depends_on_phi) phis_.Add(phi); | 2076 if (depends_on_phi) phis_.Add(phi); |
2044 } | 2077 } |
2045 } | 2078 } |
2046 | 2079 |
2047 | 2080 |
2048 void ReachingDefs::Compute() { | 2081 void ReachingDefs::Compute() { |
2049 // Transitively collect all phis that are used by the given phi. | 2082 // Transitively collect all phis that are used by the given phi. |
2050 for (intptr_t i = 0; i < phis_.length(); i++) { | 2083 for (intptr_t i = 0; i < phis_.length(); i++) { |
2051 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2052 PhiInstr* phi = phis_[i]; | 2084 PhiInstr* phi = phis_[i]; |
2053 | 2085 |
2054 // Add all phis that affect this phi to the list. | 2086 // Add all phis that affect this phi to the list. |
2055 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 2087 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
2056 PhiInstr* input_phi = phi->InputAt(i)->definition()->AsPhi(); | 2088 PhiInstr* input_phi = phi->InputAt(i)->definition()->AsPhi(); |
2057 if (input_phi != NULL) { | 2089 if (input_phi != NULL) { |
2058 AddPhi(input_phi); | 2090 AddPhi(input_phi); |
2059 } | 2091 } |
2060 } | 2092 } |
2061 } | 2093 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2146 (free_until >= loop_header->last_block()->end_pos()) && | 2178 (free_until >= loop_header->last_block()->end_pos()) && |
2147 loop_header->backedge_interference()->Contains(unallocated->vreg())) { | 2179 loop_header->backedge_interference()->Contains(unallocated->vreg())) { |
2148 GrowableArray<bool> used_on_backedge(number_of_registers_); | 2180 GrowableArray<bool> used_on_backedge(number_of_registers_); |
2149 for (intptr_t i = 0; i < number_of_registers_; i++) { | 2181 for (intptr_t i = 0; i < number_of_registers_; i++) { |
2150 used_on_backedge.Add(false); | 2182 used_on_backedge.Add(false); |
2151 } | 2183 } |
2152 | 2184 |
2153 for (PhiIterator it(loop_header->entry()->AsJoinEntry()); | 2185 for (PhiIterator it(loop_header->entry()->AsJoinEntry()); |
2154 !it.Done(); | 2186 !it.Done(); |
2155 it.Advance()) { | 2187 it.Advance()) { |
2156 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2157 PhiInstr* phi = it.Current(); | 2188 PhiInstr* phi = it.Current(); |
2158 ASSERT(phi->is_alive()); | 2189 ASSERT(phi->is_alive()); |
2159 const intptr_t phi_vreg = phi->ssa_temp_index(); | 2190 intptr_t phi_vreg = phi->ssa_temp_index(); |
2160 LiveRange* range = GetLiveRange(phi_vreg); | 2191 LiveRange* range = GetLiveRange(phi_vreg); |
2161 if (range->assigned_location().kind() == register_kind_) { | 2192 if (range->assigned_location().kind() == register_kind_) { |
2162 const intptr_t reg = range->assigned_location().register_code(); | 2193 const intptr_t reg = range->assigned_location().register_code(); |
2163 | |
2164 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { | 2194 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { |
2165 used_on_backedge[reg] = true; | 2195 used_on_backedge[reg] = true; |
2166 } | 2196 } |
2167 } | 2197 } |
2198 if (phi->HasPairRepresentation()) { | |
2199 phi_vreg = ToSecondPairVreg(phi_vreg); | |
2200 range = GetLiveRange(phi_vreg); | |
2201 if (range->assigned_location().kind() == register_kind_) { | |
2202 const intptr_t reg = range->assigned_location().register_code(); | |
2203 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { | |
Cutch
2015/10/01 17:27:41
Factor into another helper routine?
Florian Schneider
2015/10/01 18:27:38
Renamed locals like above.
| |
2204 used_on_backedge[reg] = true; | |
2205 } | |
2206 } | |
2207 } | |
2168 } | 2208 } |
2169 | 2209 |
2170 if (used_on_backedge[candidate]) { | 2210 if (used_on_backedge[candidate]) { |
2171 TRACE_ALLOC(THR_Print( | 2211 TRACE_ALLOC(THR_Print( |
2172 "considering %s for v%" Pd ": has interference on the back edge" | 2212 "considering %s for v%" Pd ": has interference on the back edge" |
2173 " {loop [%" Pd ", %" Pd ")}\n", | 2213 " {loop [%" Pd ", %" Pd ")}\n", |
2174 MakeRegisterLocation(candidate).Name(), | 2214 MakeRegisterLocation(candidate).Name(), |
2175 unallocated->vreg(), | 2215 unallocated->vreg(), |
2176 loop_header->entry()->start_pos(), | 2216 loop_header->entry()->start_pos(), |
2177 loop_header->last_block()->end_pos())); | 2217 loop_header->last_block()->end_pos())); |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2870 Definition* def = (*catch_entry->initial_definitions())[i]; | 2910 Definition* def = (*catch_entry->initial_definitions())[i]; |
2871 ASSERT(!def->HasPairRepresentation()); | 2911 ASSERT(!def->HasPairRepresentation()); |
2872 value_representations_[def->ssa_temp_index()] = | 2912 value_representations_[def->ssa_temp_index()] = |
2873 RepresentationForRange(def->representation()); | 2913 RepresentationForRange(def->representation()); |
2874 } | 2914 } |
2875 } | 2915 } |
2876 // Phis. | 2916 // Phis. |
2877 if (block->IsJoinEntry()) { | 2917 if (block->IsJoinEntry()) { |
2878 JoinEntryInstr* join = block->AsJoinEntry(); | 2918 JoinEntryInstr* join = block->AsJoinEntry(); |
2879 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 2919 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
2880 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2881 PhiInstr* phi = it.Current(); | 2920 PhiInstr* phi = it.Current(); |
2882 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { | 2921 ASSERT(phi != NULL && phi->ssa_temp_index() >= 0); |
2883 ASSERT(!phi->HasPairRepresentation()); | 2922 value_representations_[phi->ssa_temp_index()] = |
2884 value_representations_[phi->ssa_temp_index()] = | 2923 RepresentationForRange(phi->representation()); |
2924 if (phi->HasPairRepresentation()) { | |
2925 value_representations_[ToSecondPairVreg(phi->ssa_temp_index())] = | |
2885 RepresentationForRange(phi->representation()); | 2926 RepresentationForRange(phi->representation()); |
2886 } | 2927 } |
2887 } | 2928 } |
2888 } | 2929 } |
2889 // Normal instructions. | 2930 // Normal instructions. |
2890 for (ForwardInstructionIterator instr_it(block); | 2931 for (ForwardInstructionIterator instr_it(block); |
2891 !instr_it.Done(); | 2932 !instr_it.Done(); |
2892 instr_it.Advance()) { | 2933 instr_it.Advance()) { |
2893 Definition* def = instr_it.Current()->AsDefinition(); | 2934 Definition* def = instr_it.Current()->AsDefinition(); |
2894 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { | 2935 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2971 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", | 3012 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", |
2972 function.ToFullyQualifiedCString()); | 3013 function.ToFullyQualifiedCString()); |
2973 FlowGraphPrinter printer(flow_graph_, true); | 3014 FlowGraphPrinter printer(flow_graph_, true); |
2974 printer.PrintBlocks(); | 3015 printer.PrintBlocks(); |
2975 THR_Print("----------------------------------------------\n"); | 3016 THR_Print("----------------------------------------------\n"); |
2976 } | 3017 } |
2977 } | 3018 } |
2978 | 3019 |
2979 | 3020 |
2980 } // namespace dart | 3021 } // namespace dart |
OLD | NEW |