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)) { |
240 live_in_[pred->postorder_number()]->Add(use); | 243 live_in_[pred->postorder_number()]->Add(use); |
241 } | 244 } |
| 245 if (phi->HasPairRepresentation()) { |
| 246 const intptr_t second_use = ToSecondPairVreg(use); |
| 247 if (!kill_[pred->postorder_number()]->Contains(second_use)) { |
| 248 live_in_[pred->postorder_number()]->Add(second_use); |
| 249 } |
| 250 } |
242 } | 251 } |
243 } | 252 } |
244 } else if (block->IsCatchBlockEntry()) { | 253 } else if (block->IsCatchBlockEntry()) { |
245 // Process initial definitions. | 254 // Process initial definitions. |
246 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); | 255 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); |
247 for (intptr_t i = 0; | 256 for (intptr_t i = 0; |
248 i < catch_entry->initial_definitions()->length(); | 257 i < catch_entry->initial_definitions()->length(); |
249 i++) { | 258 i++) { |
250 Definition* def = (*catch_entry->initial_definitions())[i]; | 259 Definition* def = (*catch_entry->initial_definitions())[i]; |
251 const intptr_t vreg = def->ssa_temp_index(); | 260 const intptr_t vreg = def->ssa_temp_index(); |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 ParallelMoveInstr* parallel_move = goto_instr->parallel_move(); | 776 ParallelMoveInstr* parallel_move = goto_instr->parallel_move(); |
768 | 777 |
769 // All uses are recorded at the position of parallel move preceding goto. | 778 // All uses are recorded at the position of parallel move preceding goto. |
770 const intptr_t pos = goto_instr->lifetime_position(); | 779 const intptr_t pos = goto_instr->lifetime_position(); |
771 | 780 |
772 JoinEntryInstr* join = goto_instr->successor(); | 781 JoinEntryInstr* join = goto_instr->successor(); |
773 ASSERT(join != NULL); | 782 ASSERT(join != NULL); |
774 | 783 |
775 // Search for the index of the current block in the predecessors of | 784 // Search for the index of the current block in the predecessors of |
776 // the join. | 785 // the join. |
777 const intptr_t pred_idx = join->IndexOfPredecessor(block); | 786 const intptr_t pred_index = join->IndexOfPredecessor(block); |
778 | 787 |
779 // Record the corresponding phi input use for each phi. | 788 // Record the corresponding phi input use for each phi. |
780 intptr_t move_idx = 0; | 789 intptr_t move_index = 0; |
781 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 790 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
782 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
783 PhiInstr* phi = it.Current(); | 791 PhiInstr* phi = it.Current(); |
784 Value* val = phi->InputAt(pred_idx); | 792 Value* val = phi->InputAt(pred_index); |
785 MoveOperands* move = parallel_move->MoveOperandsAt(move_idx); | 793 MoveOperands* move = parallel_move->MoveOperandsAt(move_index++); |
786 | 794 |
787 ConstantInstr* constant = val->definition()->AsConstant(); | 795 ConstantInstr* constant = val->definition()->AsConstant(); |
788 if (constant != NULL) { | 796 if (constant != NULL) { |
789 move->set_src(Location::Constant(constant)); | 797 move->set_src(Location::Constant(constant)); |
790 move_idx++; | |
791 continue; | 798 continue; |
792 } | 799 } |
793 | 800 |
794 // Expected shape of live ranges: | 801 // Expected shape of live ranges: |
795 // | 802 // |
796 // g g' | 803 // g g' |
797 // value --* | 804 // value --* |
798 // | 805 // |
799 | 806 intptr_t vreg = val->definition()->ssa_temp_index(); |
800 const intptr_t vreg = val->definition()->ssa_temp_index(); | |
801 LiveRange* range = GetLiveRange(vreg); | 807 LiveRange* range = GetLiveRange(vreg); |
802 if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg); | 808 if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg); |
803 | 809 |
804 range->AddUseInterval(block->start_pos(), pos); | 810 range->AddUseInterval(block->start_pos(), pos); |
805 range->AddHintedUse( | 811 range->AddHintedUse( |
806 pos, | 812 pos, |
807 move->src_slot(), | 813 move->src_slot(), |
808 GetLiveRange(phi->ssa_temp_index())->assigned_location_slot()); | 814 GetLiveRange(phi->ssa_temp_index())->assigned_location_slot()); |
| 815 move->set_src(Location::PrefersRegister()); |
809 | 816 |
810 move->set_src(Location::PrefersRegister()); | 817 if (val->definition()->HasPairRepresentation()) { |
811 move_idx++; | 818 move = parallel_move->MoveOperandsAt(move_index++); |
| 819 vreg = ToSecondPairVreg(vreg); |
| 820 range = GetLiveRange(vreg); |
| 821 if (interfere_at_backedge != NULL) { |
| 822 interfere_at_backedge->Add(vreg); |
| 823 } |
| 824 range->AddUseInterval(block->start_pos(), pos); |
| 825 range->AddHintedUse( |
| 826 pos, |
| 827 move->src_slot(), |
| 828 GetLiveRange(ToSecondPairVreg( |
| 829 phi->ssa_temp_index()))->assigned_location_slot()); |
| 830 move->set_src(Location::PrefersRegister()); |
| 831 } |
812 } | 832 } |
813 | 833 |
814 // Begin backward iteration with the instruction before the parallel | 834 // Begin backward iteration with the instruction before the parallel |
815 // move. | 835 // move. |
816 return goto_instr->previous(); | 836 return goto_instr->previous(); |
817 } | 837 } |
818 | 838 |
819 | 839 |
820 void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) { | 840 void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) { |
821 // For join blocks we need to add destinations of phi resolution moves | 841 // 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. | 842 // to phi's live range so that register allocator will fill them with moves. |
823 | 843 |
824 // All uses are recorded at the start position in the block. | 844 // All uses are recorded at the start position in the block. |
825 const intptr_t pos = join->start_pos(); | 845 const intptr_t pos = join->start_pos(); |
826 const bool is_loop_header = BlockInfoAt(join->start_pos())->is_loop_header(); | 846 const bool is_loop_header = BlockInfoAt(join->start_pos())->is_loop_header(); |
827 intptr_t move_idx = 0; | 847 intptr_t move_idx = 0; |
828 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 848 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
829 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
830 PhiInstr* phi = it.Current(); | 849 PhiInstr* phi = it.Current(); |
831 ASSERT(phi != NULL); | 850 ASSERT(phi != NULL); |
832 const intptr_t vreg = phi->ssa_temp_index(); | 851 const intptr_t vreg = phi->ssa_temp_index(); |
833 ASSERT(vreg >= 0); | 852 ASSERT(vreg >= 0); |
| 853 const bool is_pair_phi = phi->HasPairRepresentation(); |
834 | 854 |
835 // Expected shape of live range: | 855 // Expected shape of live range: |
836 // | 856 // |
837 // B | 857 // B |
838 // phi [-------- | 858 // phi [-------- |
839 // | 859 // |
840 LiveRange* range = GetLiveRange(vreg); | 860 LiveRange* range = GetLiveRange(vreg); |
841 range->DefineAt(pos); // Shorten live range. | 861 range->DefineAt(pos); // Shorten live range. |
| 862 if (is_loop_header) range->mark_loop_phi(); |
842 | 863 |
843 if (is_loop_header) range->mark_loop_phi(); | 864 if (is_pair_phi) { |
| 865 LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg)); |
| 866 second_range->DefineAt(pos); // Shorten live range. |
| 867 if (is_loop_header) second_range->mark_loop_phi(); |
| 868 } |
844 | 869 |
845 for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) { | 870 for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) { |
846 BlockEntryInstr* pred = join->PredecessorAt(pred_idx); | 871 BlockEntryInstr* pred = join->PredecessorAt(pred_idx); |
847 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); | 872 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); |
848 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); | 873 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); |
849 MoveOperands* move = | 874 MoveOperands* move = |
850 goto_instr->parallel_move()->MoveOperandsAt(move_idx); | 875 goto_instr->parallel_move()->MoveOperandsAt(move_idx); |
851 move->set_dest(Location::PrefersRegister()); | 876 move->set_dest(Location::PrefersRegister()); |
852 range->AddUse(pos, move->dest_slot()); | 877 range->AddUse(pos, move->dest_slot()); |
| 878 if (is_pair_phi) { |
| 879 LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg)); |
| 880 MoveOperands* second_move = |
| 881 goto_instr->parallel_move()->MoveOperandsAt(move_idx + 1); |
| 882 second_move->set_dest(Location::PrefersRegister()); |
| 883 second_range->AddUse(pos, second_move->dest_slot()); |
| 884 } |
853 } | 885 } |
854 | 886 |
855 // All phi resolution moves are connected. Phi's live range is | 887 // All phi resolution moves are connected. Phi's live range is |
856 // complete. | 888 // complete. |
857 AssignSafepoints(phi, range); | 889 AssignSafepoints(phi, range); |
| 890 CompleteRange(range, RegisterKindForResult(phi)); |
| 891 if (is_pair_phi) { |
| 892 LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg)); |
| 893 AssignSafepoints(phi, second_range); |
| 894 CompleteRange(second_range, RegisterKindForResult(phi)); |
| 895 } |
858 | 896 |
859 CompleteRange(range, RegisterKindForResult(phi)); | 897 move_idx += is_pair_phi ? 2 : 1; |
860 | |
861 move_idx++; | |
862 } | 898 } |
863 } | 899 } |
864 | 900 |
865 | 901 |
866 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, | 902 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
867 Instruction* current) { | 903 Instruction* current) { |
868 ASSERT(current->env() != NULL); | 904 ASSERT(current->env() != NULL); |
869 Environment* env = current->env(); | 905 Environment* env = current->env(); |
870 while (env != NULL) { | 906 while (env != NULL) { |
871 // Any value mentioned in the deoptimization environment should survive | 907 // Any value mentioned in the deoptimization environment should survive |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 } | 1528 } |
1493 | 1529 |
1494 // Create parallel moves in join predecessors. This must be done after | 1530 // Create parallel moves in join predecessors. This must be done after |
1495 // all instructions are numbered. | 1531 // all instructions are numbered. |
1496 for (intptr_t i = block_count - 1; i >= 0; i--) { | 1532 for (intptr_t i = block_count - 1; i >= 0; i--) { |
1497 BlockEntryInstr* block = postorder_[i]; | 1533 BlockEntryInstr* block = postorder_[i]; |
1498 | 1534 |
1499 // For join entry predecessors create phi resolution moves if | 1535 // For join entry predecessors create phi resolution moves if |
1500 // necessary. They will be populated by the register allocator. | 1536 // necessary. They will be populated by the register allocator. |
1501 JoinEntryInstr* join = block->AsJoinEntry(); | 1537 JoinEntryInstr* join = block->AsJoinEntry(); |
1502 if ((join != NULL) && | 1538 if (join != NULL) { |
1503 (join->phis() != NULL) && | 1539 intptr_t move_count = 0; |
1504 !join->phis()->is_empty()) { | 1540 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
1505 const intptr_t phi_count = join->phis()->length(); | 1541 move_count += it.Current()->HasPairRepresentation() ? 2 : 1; |
| 1542 } |
1506 for (intptr_t i = 0; i < block->PredecessorCount(); i++) { | 1543 for (intptr_t i = 0; i < block->PredecessorCount(); i++) { |
1507 // Insert the move between the last two instructions of the | 1544 // Insert the move between the last two instructions of the |
1508 // predecessor block (all such blocks have at least two instructions: | 1545 // predecessor block (all such blocks have at least two instructions: |
1509 // the block entry and goto instructions.) | 1546 // the block entry and goto instructions.) |
1510 Instruction* last = block->PredecessorAt(i)->last_instruction(); | 1547 Instruction* last = block->PredecessorAt(i)->last_instruction(); |
1511 ASSERT(last->IsGoto()); | 1548 ASSERT(last->IsGoto()); |
1512 | 1549 |
1513 ParallelMoveInstr* move = last->AsGoto()->GetParallelMove(); | 1550 ParallelMoveInstr* move = last->AsGoto()->GetParallelMove(); |
1514 | 1551 |
1515 // Populate the ParallelMove with empty moves. | 1552 // Populate the ParallelMove with empty moves. |
1516 for (intptr_t j = 0; j < phi_count; j++) { | 1553 for (intptr_t j = 0; j < move_count; j++) { |
1517 move->AddMove(Location::NoLocation(), Location::NoLocation()); | 1554 move->AddMove(Location::NoLocation(), Location::NoLocation()); |
1518 } | 1555 } |
1519 } | 1556 } |
1520 } | 1557 } |
1521 } | 1558 } |
1522 } | 1559 } |
1523 | 1560 |
1524 | 1561 |
1525 // Discover structural (reducible) loops nesting structure. | 1562 // Discover structural (reducible) loops nesting structure. |
1526 void FlowGraphAllocator::DiscoverLoops() { | 1563 void FlowGraphAllocator::DiscoverLoops() { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2016 const intptr_t pos = FirstIntersection( | 2053 const intptr_t pos = FirstIntersection( |
2017 unallocated->finger()->first_pending_use_interval(), | 2054 unallocated->finger()->first_pending_use_interval(), |
2018 allocated_head); | 2055 allocated_head); |
2019 if (pos < intersection) intersection = pos; | 2056 if (pos < intersection) intersection = pos; |
2020 } | 2057 } |
2021 return intersection; | 2058 return intersection; |
2022 } | 2059 } |
2023 | 2060 |
2024 | 2061 |
2025 void ReachingDefs::AddPhi(PhiInstr* phi) { | 2062 void ReachingDefs::AddPhi(PhiInstr* phi) { |
2026 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2027 if (phi->reaching_defs() == NULL) { | 2063 if (phi->reaching_defs() == NULL) { |
2028 Zone* zone = flow_graph_.zone(); | 2064 Zone* zone = flow_graph_.zone(); |
2029 phi->set_reaching_defs(new(zone) BitVector( | 2065 phi->set_reaching_defs(new(zone) BitVector( |
2030 zone, flow_graph_.max_virtual_register_number())); | 2066 zone, flow_graph_.max_virtual_register_number())); |
2031 | 2067 |
2032 // Compute initial set reaching defs set. | 2068 // Compute initial set reaching defs set. |
2033 bool depends_on_phi = false; | 2069 bool depends_on_phi = false; |
2034 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 2070 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
2035 Definition* input = phi->InputAt(i)->definition(); | 2071 Definition* input = phi->InputAt(i)->definition(); |
2036 if (input->IsPhi()) { | 2072 if (input->IsPhi()) { |
2037 depends_on_phi = true; | 2073 depends_on_phi = true; |
2038 } | 2074 } |
2039 phi->reaching_defs()->Add(input->ssa_temp_index()); | 2075 phi->reaching_defs()->Add(input->ssa_temp_index()); |
| 2076 if (phi->HasPairRepresentation()) { |
| 2077 phi->reaching_defs()->Add(ToSecondPairVreg(input->ssa_temp_index())); |
| 2078 } |
2040 } | 2079 } |
2041 | 2080 |
2042 // If this phi depends on another phi then we need fix point iteration. | 2081 // If this phi depends on another phi then we need fix point iteration. |
2043 if (depends_on_phi) phis_.Add(phi); | 2082 if (depends_on_phi) phis_.Add(phi); |
2044 } | 2083 } |
2045 } | 2084 } |
2046 | 2085 |
2047 | 2086 |
2048 void ReachingDefs::Compute() { | 2087 void ReachingDefs::Compute() { |
2049 // Transitively collect all phis that are used by the given phi. | 2088 // Transitively collect all phis that are used by the given phi. |
2050 for (intptr_t i = 0; i < phis_.length(); i++) { | 2089 for (intptr_t i = 0; i < phis_.length(); i++) { |
2051 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2052 PhiInstr* phi = phis_[i]; | 2090 PhiInstr* phi = phis_[i]; |
2053 | 2091 |
2054 // Add all phis that affect this phi to the list. | 2092 // Add all phis that affect this phi to the list. |
2055 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 2093 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
2056 PhiInstr* input_phi = phi->InputAt(i)->definition()->AsPhi(); | 2094 PhiInstr* input_phi = phi->InputAt(i)->definition()->AsPhi(); |
2057 if (input_phi != NULL) { | 2095 if (input_phi != NULL) { |
2058 AddPhi(input_phi); | 2096 AddPhi(input_phi); |
2059 } | 2097 } |
2060 } | 2098 } |
2061 } | 2099 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 (free_until >= loop_header->last_block()->end_pos()) && | 2184 (free_until >= loop_header->last_block()->end_pos()) && |
2147 loop_header->backedge_interference()->Contains(unallocated->vreg())) { | 2185 loop_header->backedge_interference()->Contains(unallocated->vreg())) { |
2148 GrowableArray<bool> used_on_backedge(number_of_registers_); | 2186 GrowableArray<bool> used_on_backedge(number_of_registers_); |
2149 for (intptr_t i = 0; i < number_of_registers_; i++) { | 2187 for (intptr_t i = 0; i < number_of_registers_; i++) { |
2150 used_on_backedge.Add(false); | 2188 used_on_backedge.Add(false); |
2151 } | 2189 } |
2152 | 2190 |
2153 for (PhiIterator it(loop_header->entry()->AsJoinEntry()); | 2191 for (PhiIterator it(loop_header->entry()->AsJoinEntry()); |
2154 !it.Done(); | 2192 !it.Done(); |
2155 it.Advance()) { | 2193 it.Advance()) { |
2156 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2157 PhiInstr* phi = it.Current(); | 2194 PhiInstr* phi = it.Current(); |
2158 ASSERT(phi->is_alive()); | 2195 ASSERT(phi->is_alive()); |
2159 const intptr_t phi_vreg = phi->ssa_temp_index(); | 2196 const intptr_t phi_vreg = phi->ssa_temp_index(); |
2160 LiveRange* range = GetLiveRange(phi_vreg); | 2197 LiveRange* range = GetLiveRange(phi_vreg); |
2161 if (range->assigned_location().kind() == register_kind_) { | 2198 if (range->assigned_location().kind() == register_kind_) { |
2162 const intptr_t reg = range->assigned_location().register_code(); | 2199 const intptr_t reg = range->assigned_location().register_code(); |
2163 | |
2164 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { | 2200 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { |
2165 used_on_backedge[reg] = true; | 2201 used_on_backedge[reg] = true; |
2166 } | 2202 } |
2167 } | 2203 } |
| 2204 if (phi->HasPairRepresentation()) { |
| 2205 const intptr_t second_phi_vreg = ToSecondPairVreg(phi_vreg); |
| 2206 LiveRange* second_range = GetLiveRange(second_phi_vreg); |
| 2207 if (second_range->assigned_location().kind() == register_kind_) { |
| 2208 const intptr_t reg = |
| 2209 second_range->assigned_location().register_code(); |
| 2210 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { |
| 2211 used_on_backedge[reg] = true; |
| 2212 } |
| 2213 } |
| 2214 } |
2168 } | 2215 } |
2169 | 2216 |
2170 if (used_on_backedge[candidate]) { | 2217 if (used_on_backedge[candidate]) { |
2171 TRACE_ALLOC(THR_Print( | 2218 TRACE_ALLOC(THR_Print( |
2172 "considering %s for v%" Pd ": has interference on the back edge" | 2219 "considering %s for v%" Pd ": has interference on the back edge" |
2173 " {loop [%" Pd ", %" Pd ")}\n", | 2220 " {loop [%" Pd ", %" Pd ")}\n", |
2174 MakeRegisterLocation(candidate).Name(), | 2221 MakeRegisterLocation(candidate).Name(), |
2175 unallocated->vreg(), | 2222 unallocated->vreg(), |
2176 loop_header->entry()->start_pos(), | 2223 loop_header->entry()->start_pos(), |
2177 loop_header->last_block()->end_pos())); | 2224 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]; | 2917 Definition* def = (*catch_entry->initial_definitions())[i]; |
2871 ASSERT(!def->HasPairRepresentation()); | 2918 ASSERT(!def->HasPairRepresentation()); |
2872 value_representations_[def->ssa_temp_index()] = | 2919 value_representations_[def->ssa_temp_index()] = |
2873 RepresentationForRange(def->representation()); | 2920 RepresentationForRange(def->representation()); |
2874 } | 2921 } |
2875 } | 2922 } |
2876 // Phis. | 2923 // Phis. |
2877 if (block->IsJoinEntry()) { | 2924 if (block->IsJoinEntry()) { |
2878 JoinEntryInstr* join = block->AsJoinEntry(); | 2925 JoinEntryInstr* join = block->AsJoinEntry(); |
2879 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 2926 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
2880 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | |
2881 PhiInstr* phi = it.Current(); | 2927 PhiInstr* phi = it.Current(); |
2882 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { | 2928 ASSERT(phi != NULL && phi->ssa_temp_index() >= 0); |
2883 ASSERT(!phi->HasPairRepresentation()); | 2929 value_representations_[phi->ssa_temp_index()] = |
2884 value_representations_[phi->ssa_temp_index()] = | 2930 RepresentationForRange(phi->representation()); |
| 2931 if (phi->HasPairRepresentation()) { |
| 2932 value_representations_[ToSecondPairVreg(phi->ssa_temp_index())] = |
2885 RepresentationForRange(phi->representation()); | 2933 RepresentationForRange(phi->representation()); |
2886 } | 2934 } |
2887 } | 2935 } |
2888 } | 2936 } |
2889 // Normal instructions. | 2937 // Normal instructions. |
2890 for (ForwardInstructionIterator instr_it(block); | 2938 for (ForwardInstructionIterator instr_it(block); |
2891 !instr_it.Done(); | 2939 !instr_it.Done(); |
2892 instr_it.Advance()) { | 2940 instr_it.Advance()) { |
2893 Definition* def = instr_it.Current()->AsDefinition(); | 2941 Definition* def = instr_it.Current()->AsDefinition(); |
2894 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { | 2942 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", | 3019 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", |
2972 function.ToFullyQualifiedCString()); | 3020 function.ToFullyQualifiedCString()); |
2973 FlowGraphPrinter printer(flow_graph_, true); | 3021 FlowGraphPrinter printer(flow_graph_, true); |
2974 printer.PrintBlocks(); | 3022 printer.PrintBlocks(); |
2975 THR_Print("----------------------------------------------\n"); | 3023 THR_Print("----------------------------------------------\n"); |
2976 } | 3024 } |
2977 } | 3025 } |
2978 | 3026 |
2979 | 3027 |
2980 } // namespace dart | 3028 } // namespace dart |
OLD | NEW |