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