| 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 |