Chromium Code Reviews| 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 |