Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: runtime/vm/flow_graph_allocator.cc

Issue 1377113004: VM: Support phis with pair representations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698