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

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

Issue 907093002: Port flow_graph*, disassembler to ISL_Print (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/disassembler.cc ('k') | runtime/vm/flow_graph_compiler.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"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/log.h"
12 #include "vm/parser.h" 13 #include "vm/parser.h"
13 14
14 namespace dart { 15 namespace dart {
15 16
16 DEFINE_FLAG(bool, print_ssa_liveness, false, 17 DEFINE_FLAG(bool, print_ssa_liveness, false,
17 "Print liveness for ssa variables."); 18 "Print liveness for ssa variables.");
18 DEFINE_FLAG(bool, trace_ssa_allocator, false, 19 DEFINE_FLAG(bool, trace_ssa_allocator, false,
19 "Trace register allocation over SSA."); 20 "Trace register allocation over SSA.");
20 DEFINE_FLAG(bool, print_ssa_liveranges, false, 21 DEFINE_FLAG(bool, print_ssa_liveranges, false,
21 "Print live ranges after allocation."); 22 "Print live ranges after allocation.");
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 UNREACHABLE(); 442 UNREACHABLE();
442 } 443 }
443 } 444 }
444 445
445 446
446 void LiveRange::Print() { 447 void LiveRange::Print() {
447 if (first_use_interval() == NULL) { 448 if (first_use_interval() == NULL) {
448 return; 449 return;
449 } 450 }
450 451
451 OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", vreg(), 452 ISL_Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", vreg(),
452 Start(), 453 Start(),
453 End()); 454 End());
454 assigned_location().Print(); 455 assigned_location().Print();
455 if (spill_slot_.HasStackIndex()) { 456 if (spill_slot_.HasStackIndex()) {
456 intptr_t stack_slot = spill_slot_.stack_index(); 457 intptr_t stack_slot = spill_slot_.stack_index();
457 OS::Print(" allocated spill slot: %" Pd "", stack_slot); 458 ISL_Print(" allocated spill slot: %" Pd "", stack_slot);
458 } 459 }
459 OS::Print("\n"); 460 ISL_Print("\n");
460 461
461 SafepointPosition* safepoint = first_safepoint(); 462 SafepointPosition* safepoint = first_safepoint();
462 while (safepoint != NULL) { 463 while (safepoint != NULL) {
463 OS::Print(" Safepoint [%" Pd "]: ", safepoint->pos()); 464 ISL_Print(" Safepoint [%" Pd "]: ", safepoint->pos());
464 safepoint->locs()->stack_bitmap()->Print(); 465 safepoint->locs()->stack_bitmap()->Print();
465 OS::Print("\n"); 466 ISL_Print("\n");
466 safepoint = safepoint->next(); 467 safepoint = safepoint->next();
467 } 468 }
468 469
469 UsePosition* use_pos = uses_; 470 UsePosition* use_pos = uses_;
470 for (UseInterval* interval = first_use_interval_; 471 for (UseInterval* interval = first_use_interval_;
471 interval != NULL; 472 interval != NULL;
472 interval = interval->next()) { 473 interval = interval->next()) {
473 OS::Print(" use interval [%" Pd ", %" Pd ")\n", 474 ISL_Print(" use interval [%" Pd ", %" Pd ")\n",
474 interval->start(), 475 interval->start(),
475 interval->end()); 476 interval->end());
476 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) { 477 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) {
477 OS::Print(" use at %" Pd "", use_pos->pos()); 478 ISL_Print(" use at %" Pd "", use_pos->pos());
478 if (use_pos->location_slot() != NULL) { 479 if (use_pos->location_slot() != NULL) {
479 OS::Print(" as "); 480 ISL_Print(" as ");
480 use_pos->location_slot()->Print(); 481 use_pos->location_slot()->Print();
481 } 482 }
482 OS::Print("\n"); 483 ISL_Print("\n");
483 use_pos = use_pos->next(); 484 use_pos = use_pos->next();
484 } 485 }
485 } 486 }
486 487
487 if (next_sibling() != NULL) { 488 if (next_sibling() != NULL) {
488 next_sibling()->Print(); 489 next_sibling()->Print();
489 } 490 }
490 } 491 }
491 492
492 493
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ? 1776 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ?
1776 first_after_split : last_use_interval_; 1777 first_after_split : last_use_interval_;
1777 next_sibling_ = new LiveRange(vreg(), 1778 next_sibling_ = new LiveRange(vreg(),
1778 representation(), 1779 representation(),
1779 first_use_after_split, 1780 first_use_after_split,
1780 first_after_split, 1781 first_after_split,
1781 last_use_interval, 1782 last_use_interval,
1782 first_safepoint_after_split, 1783 first_safepoint_after_split,
1783 next_sibling_); 1784 next_sibling_);
1784 1785
1785 TRACE_ALLOC(OS::Print(" split sibling [%" Pd ", %" Pd ")\n", 1786 TRACE_ALLOC(ISL_Print(" split sibling [%" Pd ", %" Pd ")\n",
1786 next_sibling_->Start(), next_sibling_->End())); 1787 next_sibling_->Start(), next_sibling_->End()));
1787 1788
1788 last_use_interval_ = last_before_split; 1789 last_use_interval_ = last_before_split;
1789 last_use_interval_->next_ = NULL; 1790 last_use_interval_->next_ = NULL;
1790 1791
1791 if (first_use_after_split != NULL) { 1792 if (first_use_after_split != NULL) {
1792 finger_.UpdateAfterSplit(first_use_after_split->pos()); 1793 finger_.UpdateAfterSplit(first_use_after_split->pos());
1793 } 1794 }
1794 1795
1795 return next_sibling_; 1796 return next_sibling_;
1796 } 1797 }
1797 1798
1798 1799
1799 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range, 1800 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range,
1800 intptr_t from, 1801 intptr_t from,
1801 intptr_t to) { 1802 intptr_t to) {
1802 TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %" Pd 1803 TRACE_ALLOC(ISL_Print("split v%" Pd " [%" Pd ", %" Pd
1803 ") between [%" Pd ", %" Pd ")\n", 1804 ") between [%" Pd ", %" Pd ")\n",
1804 range->vreg(), range->Start(), range->End(), from, to)); 1805 range->vreg(), range->Start(), range->End(), from, to));
1805 1806
1806 intptr_t split_pos = kIllegalPosition; 1807 intptr_t split_pos = kIllegalPosition;
1807 1808
1808 BlockInfo* split_block = BlockInfoAt(to); 1809 BlockInfo* split_block = BlockInfoAt(to);
1809 if (from < split_block->entry()->lifetime_position()) { 1810 if (from < split_block->entry()->lifetime_position()) {
1810 // Interval [from, to) spans multiple blocks. 1811 // Interval [from, to) spans multiple blocks.
1811 1812
1812 // If last block is inside a loop prefer splitting at outermost loop's 1813 // If last block is inside a loop prefer splitting at outermost loop's
(...skipping 19 matching lines...) Expand all
1832 ASSERT(from < split_pos); 1833 ASSERT(from < split_pos);
1833 1834
1834 return range->SplitAt(split_pos); 1835 return range->SplitAt(split_pos);
1835 } 1836 }
1836 1837
1837 1838
1838 void FlowGraphAllocator::SpillBetween(LiveRange* range, 1839 void FlowGraphAllocator::SpillBetween(LiveRange* range,
1839 intptr_t from, 1840 intptr_t from,
1840 intptr_t to) { 1841 intptr_t to) {
1841 ASSERT(from < to); 1842 ASSERT(from < to);
1842 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") " 1843 TRACE_ALLOC(ISL_Print("spill v%" Pd " [%" Pd ", %" Pd ") "
1843 "between [%" Pd ", %" Pd ")\n", 1844 "between [%" Pd ", %" Pd ")\n",
1844 range->vreg(), range->Start(), range->End(), from, to)); 1845 range->vreg(), range->Start(), range->End(), from, to));
1845 LiveRange* tail = range->SplitAt(from); 1846 LiveRange* tail = range->SplitAt(from);
1846 1847
1847 if (tail->Start() < to) { 1848 if (tail->Start() < to) {
1848 // There is an intersection of tail and [from, to). 1849 // There is an intersection of tail and [from, to).
1849 LiveRange* tail_tail = SplitBetween(tail, tail->Start(), to); 1850 LiveRange* tail_tail = SplitBetween(tail, tail->Start(), to);
1850 Spill(tail); 1851 Spill(tail);
1851 AddToUnallocated(tail_tail); 1852 AddToUnallocated(tail_tail);
1852 } else { 1853 } else {
1853 // No intersection between tail and [from, to). 1854 // No intersection between tail and [from, to).
1854 AddToUnallocated(tail); 1855 AddToUnallocated(tail);
1855 } 1856 }
1856 } 1857 }
1857 1858
1858 1859
1859 void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) { 1860 void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) {
1860 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") after %" Pd "\n", 1861 TRACE_ALLOC(ISL_Print("spill v%" Pd " [%" Pd ", %" Pd ") after %" Pd "\n",
1861 range->vreg(), range->Start(), range->End(), from)); 1862 range->vreg(), range->Start(), range->End(), from));
1862 1863
1863 // When spilling the value inside the loop check if this spill can 1864 // When spilling the value inside the loop check if this spill can
1864 // be moved outside. 1865 // be moved outside.
1865 BlockInfo* block_info = BlockInfoAt(from); 1866 BlockInfo* block_info = BlockInfoAt(from);
1866 if (block_info->is_loop_header() || (block_info->loop() != NULL)) { 1867 if (block_info->is_loop_header() || (block_info->loop() != NULL)) {
1867 BlockInfo* loop_header = 1868 BlockInfo* loop_header =
1868 block_info->is_loop_header() ? block_info : block_info->loop(); 1869 block_info->is_loop_header() ? block_info : block_info->loop();
1869 1870
1870 if ((range->Start() <= loop_header->entry()->start_pos()) && 1871 if ((range->Start() <= loop_header->entry()->start_pos()) &&
1871 RangeHasOnlyUnconstrainedUsesInLoop(range, loop_header->loop_id())) { 1872 RangeHasOnlyUnconstrainedUsesInLoop(range, loop_header->loop_id())) {
1872 ASSERT(loop_header->entry()->start_pos() <= from); 1873 ASSERT(loop_header->entry()->start_pos() <= from);
1873 from = loop_header->entry()->start_pos(); 1874 from = loop_header->entry()->start_pos();
1874 TRACE_ALLOC(OS::Print(" moved spill position to loop header %" Pd "\n", 1875 TRACE_ALLOC(ISL_Print(" moved spill position to loop header %" Pd "\n",
1875 from)); 1876 from));
1876 } 1877 }
1877 } 1878 }
1878 1879
1879 LiveRange* tail = range->SplitAt(from); 1880 LiveRange* tail = range->SplitAt(from);
1880 Spill(tail); 1881 Spill(tail);
1881 } 1882 }
1882 1883
1883 1884
1884 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { 1885 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 // If hint is available try hint first. 2097 // If hint is available try hint first.
2097 // TODO(vegorov): ensure that phis are hinted on the back edge. 2098 // TODO(vegorov): ensure that phis are hinted on the back edge.
2098 Location hint = unallocated->finger()->FirstHint(); 2099 Location hint = unallocated->finger()->FirstHint();
2099 if (hint.IsMachineRegister()) { 2100 if (hint.IsMachineRegister()) {
2100 if (!blocked_registers_[hint.register_code()]) { 2101 if (!blocked_registers_[hint.register_code()]) {
2101 free_until = FirstIntersectionWithAllocated(hint.register_code(), 2102 free_until = FirstIntersectionWithAllocated(hint.register_code(),
2102 unallocated); 2103 unallocated);
2103 candidate = hint.register_code(); 2104 candidate = hint.register_code();
2104 } 2105 }
2105 2106
2106 TRACE_ALLOC(OS::Print("found hint %s for v%" Pd ": free until %" Pd "\n", 2107 TRACE_ALLOC(ISL_Print("found hint %s for v%" Pd ": free until %" Pd "\n",
2107 hint.Name(), 2108 hint.Name(),
2108 unallocated->vreg(), 2109 unallocated->vreg(),
2109 free_until)); 2110 free_until));
2110 } else { 2111 } else {
2111 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { 2112 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) {
2112 if (!blocked_registers_[reg] && (registers_[reg]->length() == 0)) { 2113 if (!blocked_registers_[reg] && (registers_[reg]->length() == 0)) {
2113 candidate = reg; 2114 candidate = reg;
2114 free_until = kMaxPosition; 2115 free_until = kMaxPosition;
2115 break; 2116 break;
2116 } 2117 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 if (range->assigned_location().kind() == register_kind_) { 2160 if (range->assigned_location().kind() == register_kind_) {
2160 const intptr_t reg = range->assigned_location().register_code(); 2161 const intptr_t reg = range->assigned_location().register_code();
2161 2162
2162 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { 2163 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) {
2163 used_on_backedge[reg] = true; 2164 used_on_backedge[reg] = true;
2164 } 2165 }
2165 } 2166 }
2166 } 2167 }
2167 2168
2168 if (used_on_backedge[candidate]) { 2169 if (used_on_backedge[candidate]) {
2169 TRACE_ALLOC(OS::Print( 2170 TRACE_ALLOC(ISL_Print(
2170 "considering %s for v%" Pd ": has interference on the back edge" 2171 "considering %s for v%" Pd ": has interference on the back edge"
2171 " {loop [%" Pd ", %" Pd ")}\n", 2172 " {loop [%" Pd ", %" Pd ")}\n",
2172 MakeRegisterLocation(candidate).Name(), 2173 MakeRegisterLocation(candidate).Name(),
2173 unallocated->vreg(), 2174 unallocated->vreg(),
2174 loop_header->entry()->start_pos(), 2175 loop_header->entry()->start_pos(),
2175 loop_header->last_block()->end_pos())); 2176 loop_header->last_block()->end_pos()));
2176 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { 2177 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) {
2177 if (blocked_registers_[reg] || 2178 if (blocked_registers_[reg] ||
2178 (reg == candidate) || 2179 (reg == candidate) ||
2179 used_on_backedge[reg]) { 2180 used_on_backedge[reg]) {
2180 continue; 2181 continue;
2181 } 2182 }
2182 2183
2183 const intptr_t intersection = 2184 const intptr_t intersection =
2184 FirstIntersectionWithAllocated(reg, unallocated); 2185 FirstIntersectionWithAllocated(reg, unallocated);
2185 if (intersection >= free_until) { 2186 if (intersection >= free_until) {
2186 candidate = reg; 2187 candidate = reg;
2187 free_until = intersection; 2188 free_until = intersection;
2188 TRACE_ALLOC(OS::Print( 2189 TRACE_ALLOC(ISL_Print(
2189 "found %s for v%" Pd " with no interference on the back edge\n", 2190 "found %s for v%" Pd " with no interference on the back edge\n",
2190 MakeRegisterLocation(candidate).Name(), 2191 MakeRegisterLocation(candidate).Name(),
2191 candidate)); 2192 candidate));
2192 break; 2193 break;
2193 } 2194 }
2194 } 2195 }
2195 } 2196 }
2196 } 2197 }
2197 2198
2198 TRACE_ALLOC(OS::Print("assigning free register ")); 2199 TRACE_ALLOC(ISL_Print("assigning free register "));
2199 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); 2200 TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
2200 TRACE_ALLOC(OS::Print(" to v%" Pd "\n", unallocated->vreg())); 2201 TRACE_ALLOC(ISL_Print(" to v%" Pd "\n", unallocated->vreg()));
2201 2202
2202 if (free_until != kMaxPosition) { 2203 if (free_until != kMaxPosition) {
2203 // There was an intersection. Split unallocated. 2204 // There was an intersection. Split unallocated.
2204 TRACE_ALLOC(OS::Print(" splitting at %" Pd "\n", free_until)); 2205 TRACE_ALLOC(ISL_Print(" splitting at %" Pd "\n", free_until));
2205 LiveRange* tail = unallocated->SplitAt(free_until); 2206 LiveRange* tail = unallocated->SplitAt(free_until);
2206 AddToUnallocated(tail); 2207 AddToUnallocated(tail);
2207 } 2208 }
2208 2209
2209 registers_[candidate]->Add(unallocated); 2210 registers_[candidate]->Add(unallocated);
2210 unallocated->set_assigned_location(MakeRegisterLocation(candidate)); 2211 unallocated->set_assigned_location(MakeRegisterLocation(candidate));
2211 2212
2212 return true; 2213 return true;
2213 } 2214 }
2214 2215
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 : unallocated->Start(); 2294 : unallocated->Start();
2294 if (free_until < register_use_pos) { 2295 if (free_until < register_use_pos) {
2295 // Can't acquire free register. Spill until we really need one. 2296 // Can't acquire free register. Spill until we really need one.
2296 ASSERT(unallocated->Start() < ToInstructionStart(register_use_pos)); 2297 ASSERT(unallocated->Start() < ToInstructionStart(register_use_pos));
2297 SpillBetween(unallocated, unallocated->Start(), register_use->pos()); 2298 SpillBetween(unallocated, unallocated->Start(), register_use->pos());
2298 return; 2299 return;
2299 } 2300 }
2300 2301
2301 ASSERT(candidate != kNoRegister); 2302 ASSERT(candidate != kNoRegister);
2302 2303
2303 TRACE_ALLOC(OS::Print("assigning blocked register ")); 2304 TRACE_ALLOC(ISL_Print("assigning blocked register "));
2304 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); 2305 TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
2305 TRACE_ALLOC(OS::Print(" to live range v%" Pd " until %" Pd "\n", 2306 TRACE_ALLOC(ISL_Print(" to live range v%" Pd " until %" Pd "\n",
2306 unallocated->vreg(), blocked_at)); 2307 unallocated->vreg(), blocked_at));
2307 2308
2308 if (blocked_at < unallocated->End()) { 2309 if (blocked_at < unallocated->End()) {
2309 // Register is blocked before the end of the live range. Split the range 2310 // Register is blocked before the end of the live range. Split the range
2310 // at latest at blocked_at position. 2311 // at latest at blocked_at position.
2311 LiveRange* tail = SplitBetween(unallocated, 2312 LiveRange* tail = SplitBetween(unallocated,
2312 unallocated->Start(), 2313 unallocated->Start(),
2313 blocked_at + 1); 2314 blocked_at + 1);
2314 AddToUnallocated(tail); 2315 AddToUnallocated(tail);
2315 } 2316 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 2461
2461 return parallel_move->AddMove(to, from); 2462 return parallel_move->AddMove(to, from);
2462 } 2463 }
2463 2464
2464 2465
2465 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { 2466 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) {
2466 ASSERT(!loc.IsPairLocation()); 2467 ASSERT(!loc.IsPairLocation());
2467 ASSERT(use->location_slot() != NULL); 2468 ASSERT(use->location_slot() != NULL);
2468 Location* slot = use->location_slot(); 2469 Location* slot = use->location_slot();
2469 ASSERT(slot->IsUnallocated()); 2470 ASSERT(slot->IsUnallocated());
2470 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos())); 2471 TRACE_ALLOC(ISL_Print(" use at %" Pd " converted to ", use->pos()));
2471 TRACE_ALLOC(loc.Print()); 2472 TRACE_ALLOC(loc.Print());
2472 TRACE_ALLOC(OS::Print("\n")); 2473 TRACE_ALLOC(ISL_Print("\n"));
2473 *slot = loc; 2474 *slot = loc;
2474 } 2475 }
2475 2476
2476 2477
2477 void FlowGraphAllocator::ConvertAllUses(LiveRange* range) { 2478 void FlowGraphAllocator::ConvertAllUses(LiveRange* range) {
2478 if (range->vreg() == kNoVirtualRegister) return; 2479 if (range->vreg() == kNoVirtualRegister) return;
2479 2480
2480 const Location loc = range->assigned_location(); 2481 const Location loc = range->assigned_location();
2481 ASSERT(!loc.IsInvalid()); 2482 ASSERT(!loc.IsInvalid());
2482 2483
2483 TRACE_ALLOC(OS::Print("range [%" Pd ", %" Pd ") " 2484 TRACE_ALLOC(ISL_Print("range [%" Pd ", %" Pd ") "
2484 "for v%" Pd " has been allocated to ", 2485 "for v%" Pd " has been allocated to ",
2485 range->Start(), range->End(), range->vreg())); 2486 range->Start(), range->End(), range->vreg()));
2486 TRACE_ALLOC(loc.Print()); 2487 TRACE_ALLOC(loc.Print());
2487 TRACE_ALLOC(OS::Print(":\n")); 2488 TRACE_ALLOC(ISL_Print(":\n"));
2488 2489
2489 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { 2490 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) {
2490 ConvertUseTo(use, loc); 2491 ConvertUseTo(use, loc);
2491 } 2492 }
2492 2493
2493 // Add live registers at all safepoints for instructions with slow-path 2494 // Add live registers at all safepoints for instructions with slow-path
2494 // code. 2495 // code.
2495 if (loc.IsMachineRegister()) { 2496 if (loc.IsMachineRegister()) {
2496 for (SafepointPosition* safepoint = range->first_safepoint(); 2497 for (SafepointPosition* safepoint = range->first_safepoint();
2497 safepoint != NULL; 2498 safepoint != NULL;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 2654
2654 2655
2655 void FlowGraphAllocator::AllocateUnallocatedRanges() { 2656 void FlowGraphAllocator::AllocateUnallocatedRanges() {
2656 #if defined(DEBUG) 2657 #if defined(DEBUG)
2657 ASSERT(UnallocatedIsSorted()); 2658 ASSERT(UnallocatedIsSorted());
2658 #endif 2659 #endif
2659 2660
2660 while (!unallocated_.is_empty()) { 2661 while (!unallocated_.is_empty()) {
2661 LiveRange* range = unallocated_.RemoveLast(); 2662 LiveRange* range = unallocated_.RemoveLast();
2662 const intptr_t start = range->Start(); 2663 const intptr_t start = range->Start();
2663 TRACE_ALLOC(OS::Print("Processing live range for v%" Pd " " 2664 TRACE_ALLOC(ISL_Print("Processing live range for v%" Pd " "
2664 "starting at %" Pd "\n", 2665 "starting at %" Pd "\n",
2665 range->vreg(), 2666 range->vreg(),
2666 start)); 2667 start));
2667 2668
2668 // TODO(vegorov): eagerly spill liveranges without register uses. 2669 // TODO(vegorov): eagerly spill liveranges without register uses.
2669 AdvanceActiveIntervals(start); 2670 AdvanceActiveIntervals(start);
2670 2671
2671 if (!AllocateFreeRegister(range)) { 2672 if (!AllocateFreeRegister(range)) {
2672 if (intrinsic_mode_) { 2673 if (intrinsic_mode_) {
2673 // No spilling when compiling intrinsics. 2674 // No spilling when compiling intrinsics.
2674 // TODO(fschneider): Handle spilling in intrinsics. For now, the 2675 // TODO(fschneider): Handle spilling in intrinsics. For now, the
2675 // IR has to be built so that there are enough free registers. 2676 // IR has to be built so that there are enough free registers.
2676 UNREACHABLE(); 2677 UNREACHABLE();
2677 } 2678 }
2678 AllocateAnyRegister(range); 2679 AllocateAnyRegister(range);
2679 } 2680 }
2680 } 2681 }
2681 2682
2682 // All allocation decisions were done. 2683 // All allocation decisions were done.
2683 ASSERT(unallocated_.is_empty()); 2684 ASSERT(unallocated_.is_empty());
2684 2685
2685 // Finish allocation. 2686 // Finish allocation.
2686 AdvanceActiveIntervals(kMaxPosition); 2687 AdvanceActiveIntervals(kMaxPosition);
2687 TRACE_ALLOC(OS::Print("Allocation completed\n")); 2688 TRACE_ALLOC(ISL_Print("Allocation completed\n"));
2688 } 2689 }
2689 2690
2690 2691
2691 bool FlowGraphAllocator::TargetLocationIsSpillSlot(LiveRange* range, 2692 bool FlowGraphAllocator::TargetLocationIsSpillSlot(LiveRange* range,
2692 Location target) { 2693 Location target) {
2693 if (target.IsStackSlot() || 2694 if (target.IsStackSlot() ||
2694 target.IsDoubleStackSlot() || 2695 target.IsDoubleStackSlot() ||
2695 target.IsConstant()) { 2696 target.IsConstant()) {
2696 ASSERT(GetLiveRange(range->vreg())->spill_slot().Equals(target)); 2697 ASSERT(GetLiveRange(range->vreg())->spill_slot().Equals(target));
2697 return true; 2698 return true;
2698 } 2699 }
2699 return false; 2700 return false;
2700 } 2701 }
2701 2702
2702 2703
2703 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent, 2704 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent,
2704 BlockEntryInstr* source_block, 2705 BlockEntryInstr* source_block,
2705 BlockEntryInstr* target_block) { 2706 BlockEntryInstr* target_block) {
2706 TRACE_ALLOC(OS::Print("Connect v%" Pd " on the edge B%" Pd " -> B%" Pd "\n", 2707 TRACE_ALLOC(ISL_Print("Connect v%" Pd " on the edge B%" Pd " -> B%" Pd "\n",
2707 parent->vreg(), 2708 parent->vreg(),
2708 source_block->block_id(), 2709 source_block->block_id(),
2709 target_block->block_id())); 2710 target_block->block_id()));
2710 if (parent->next_sibling() == NULL) { 2711 if (parent->next_sibling() == NULL) {
2711 // Nothing to connect. The whole range was allocated to the same location. 2712 // Nothing to connect. The whole range was allocated to the same location.
2712 TRACE_ALLOC(OS::Print("range v%" Pd " has no siblings\n", parent->vreg())); 2713 TRACE_ALLOC(ISL_Print("range v%" Pd " has no siblings\n", parent->vreg()));
2713 return; 2714 return;
2714 } 2715 }
2715 2716
2716 const intptr_t source_pos = source_block->end_pos() - 1; 2717 const intptr_t source_pos = source_block->end_pos() - 1;
2717 ASSERT(IsInstructionEndPosition(source_pos)); 2718 ASSERT(IsInstructionEndPosition(source_pos));
2718 2719
2719 const intptr_t target_pos = target_block->start_pos(); 2720 const intptr_t target_pos = target_block->start_pos();
2720 2721
2721 Location target; 2722 Location target;
2722 Location source; 2723 Location source;
(...skipping 16 matching lines...) Expand all
2739 ASSERT(target.IsInvalid()); 2740 ASSERT(target.IsInvalid());
2740 target = range->assigned_location(); 2741 target = range->assigned_location();
2741 #if defined(DEBUG) 2742 #if defined(DEBUG)
2742 target_cover = range; 2743 target_cover = range;
2743 #endif 2744 #endif
2744 } 2745 }
2745 2746
2746 range = range->next_sibling(); 2747 range = range->next_sibling();
2747 } 2748 }
2748 2749
2749 TRACE_ALLOC(OS::Print("connecting v%" Pd " between [%" Pd ", %" Pd ") {%s} " 2750 TRACE_ALLOC(ISL_Print("connecting v%" Pd " between [%" Pd ", %" Pd ") {%s} "
2750 "to [%" Pd ", %" Pd ") {%s}\n", 2751 "to [%" Pd ", %" Pd ") {%s}\n",
2751 parent->vreg(), 2752 parent->vreg(),
2752 source_cover->Start(), 2753 source_cover->Start(),
2753 source_cover->End(), 2754 source_cover->End(),
2754 source.Name(), 2755 source.Name(),
2755 target_cover->Start(), 2756 target_cover->Start(),
2756 target_cover->End(), 2757 target_cover->End(),
2757 target.Name())); 2758 target.Name()));
2758 2759
2759 // Siblings were allocated to the same register. 2760 // Siblings were allocated to the same register.
(...skipping 16 matching lines...) Expand all
2776 2777
2777 void FlowGraphAllocator::ResolveControlFlow() { 2778 void FlowGraphAllocator::ResolveControlFlow() {
2778 // Resolve linear control flow between touching split siblings 2779 // Resolve linear control flow between touching split siblings
2779 // inside basic blocks. 2780 // inside basic blocks.
2780 for (intptr_t vreg = 0; vreg < live_ranges_.length(); vreg++) { 2781 for (intptr_t vreg = 0; vreg < live_ranges_.length(); vreg++) {
2781 LiveRange* range = live_ranges_[vreg]; 2782 LiveRange* range = live_ranges_[vreg];
2782 if (range == NULL) continue; 2783 if (range == NULL) continue;
2783 2784
2784 while (range->next_sibling() != NULL) { 2785 while (range->next_sibling() != NULL) {
2785 LiveRange* sibling = range->next_sibling(); 2786 LiveRange* sibling = range->next_sibling();
2786 TRACE_ALLOC(OS::Print("connecting [%" Pd ", %" Pd ") [", 2787 TRACE_ALLOC(ISL_Print("connecting [%" Pd ", %" Pd ") [",
2787 range->Start(), range->End())); 2788 range->Start(), range->End()));
2788 TRACE_ALLOC(range->assigned_location().Print()); 2789 TRACE_ALLOC(range->assigned_location().Print());
2789 TRACE_ALLOC(OS::Print("] to [%" Pd ", %" Pd ") [", 2790 TRACE_ALLOC(ISL_Print("] to [%" Pd ", %" Pd ") [",
2790 sibling->Start(), sibling->End())); 2791 sibling->Start(), sibling->End()));
2791 TRACE_ALLOC(sibling->assigned_location().Print()); 2792 TRACE_ALLOC(sibling->assigned_location().Print());
2792 TRACE_ALLOC(OS::Print("]\n")); 2793 TRACE_ALLOC(ISL_Print("]\n"));
2793 if ((range->End() == sibling->Start()) && 2794 if ((range->End() == sibling->Start()) &&
2794 !TargetLocationIsSpillSlot(range, sibling->assigned_location()) && 2795 !TargetLocationIsSpillSlot(range, sibling->assigned_location()) &&
2795 !range->assigned_location().Equals(sibling->assigned_location()) && 2796 !range->assigned_location().Equals(sibling->assigned_location()) &&
2796 !IsBlockEntry(range->End())) { 2797 !IsBlockEntry(range->End())) {
2797 AddMoveAt(sibling->Start(), 2798 AddMoveAt(sibling->Start(),
2798 sibling->assigned_location(), 2799 sibling->assigned_location(),
2799 range->assigned_location()); 2800 range->assigned_location());
2800 } 2801 }
2801 range = sibling; 2802 range = sibling;
2802 } 2803 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2913 DiscoverLoops(); 2914 DiscoverLoops();
2914 2915
2915 BuildLiveRanges(); 2916 BuildLiveRanges();
2916 2917
2917 if (FLAG_print_ssa_liveness) { 2918 if (FLAG_print_ssa_liveness) {
2918 liveness_.Dump(); 2919 liveness_.Dump();
2919 } 2920 }
2920 2921
2921 if (FLAG_print_ssa_liveranges) { 2922 if (FLAG_print_ssa_liveranges) {
2922 const Function& function = flow_graph_.function(); 2923 const Function& function = flow_graph_.function();
2923 OS::Print("-- [before ssa allocator] ranges [%s] ---------\n", 2924 ISL_Print("-- [before ssa allocator] ranges [%s] ---------\n",
2924 function.ToFullyQualifiedCString()); 2925 function.ToFullyQualifiedCString());
2925 PrintLiveRanges(); 2926 PrintLiveRanges();
2926 OS::Print("----------------------------------------------\n"); 2927 ISL_Print("----------------------------------------------\n");
2927 2928
2928 OS::Print("-- [before ssa allocator] ir [%s] -------------\n", 2929 ISL_Print("-- [before ssa allocator] ir [%s] -------------\n",
2929 function.ToFullyQualifiedCString()); 2930 function.ToFullyQualifiedCString());
2930 FlowGraphPrinter printer(flow_graph_, true); 2931 FlowGraphPrinter printer(flow_graph_, true);
2931 printer.PrintBlocks(); 2932 printer.PrintBlocks();
2932 OS::Print("----------------------------------------------\n"); 2933 ISL_Print("----------------------------------------------\n");
2933 } 2934 }
2934 2935
2935 PrepareForAllocation(Location::kRegister, 2936 PrepareForAllocation(Location::kRegister,
2936 kNumberOfCpuRegisters, 2937 kNumberOfCpuRegisters,
2937 unallocated_cpu_, 2938 unallocated_cpu_,
2938 cpu_regs_, 2939 cpu_regs_,
2939 blocked_cpu_registers_); 2940 blocked_cpu_registers_);
2940 AllocateUnallocatedRanges(); 2941 AllocateUnallocatedRanges();
2941 2942
2942 cpu_spill_slot_count_ = spill_slots_.length(); 2943 cpu_spill_slot_count_ = spill_slots_.length();
(...skipping 11 matching lines...) Expand all
2954 ResolveControlFlow(); 2955 ResolveControlFlow();
2955 2956
2956 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry(); 2957 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
2957 ASSERT(entry != NULL); 2958 ASSERT(entry != NULL);
2958 intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor; 2959 intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor;
2959 entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count); 2960 entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count);
2960 2961
2961 if (FLAG_print_ssa_liveranges) { 2962 if (FLAG_print_ssa_liveranges) {
2962 const Function& function = flow_graph_.function(); 2963 const Function& function = flow_graph_.function();
2963 2964
2964 OS::Print("-- [after ssa allocator] ranges [%s] ---------\n", 2965 ISL_Print("-- [after ssa allocator] ranges [%s] ---------\n",
2965 function.ToFullyQualifiedCString()); 2966 function.ToFullyQualifiedCString());
2966 PrintLiveRanges(); 2967 PrintLiveRanges();
2967 OS::Print("----------------------------------------------\n"); 2968 ISL_Print("----------------------------------------------\n");
2968 2969
2969 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2970 ISL_Print("-- [after ssa allocator] ir [%s] -------------\n",
2970 function.ToFullyQualifiedCString()); 2971 function.ToFullyQualifiedCString());
2971 FlowGraphPrinter printer(flow_graph_, true); 2972 FlowGraphPrinter printer(flow_graph_, true);
2972 printer.PrintBlocks(); 2973 printer.PrintBlocks();
2973 OS::Print("----------------------------------------------\n"); 2974 ISL_Print("----------------------------------------------\n");
2974 } 2975 }
2975 } 2976 }
2976 2977
2977 2978
2978 } // namespace dart 2979 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/disassembler.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698