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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 UNREACHABLE(); | 362 UNREACHABLE(); |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 | 366 |
367 void LiveRange::Print() { | 367 void LiveRange::Print() { |
368 if (first_use_interval() == NULL) { | 368 if (first_use_interval() == NULL) { |
369 return; | 369 return; |
370 } | 370 } |
371 | 371 |
372 OS::Print(" live range v%"Pd" [%"Pd", %"Pd") in ", vreg(), Start(), End()); | 372 OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", vreg(), Start(), End ()); |
siva
2013/08/20 19:54:51
indent as
OS::Print(" live range v%" Pd " [%" Pd
Jacob
2013/08/20 20:32:15
Done.
| |
373 assigned_location().Print(); | 373 assigned_location().Print(); |
374 OS::Print("\n"); | 374 OS::Print("\n"); |
375 | 375 |
376 UsePosition* use_pos = uses_; | 376 UsePosition* use_pos = uses_; |
377 for (UseInterval* interval = first_use_interval_; | 377 for (UseInterval* interval = first_use_interval_; |
378 interval != NULL; | 378 interval != NULL; |
379 interval = interval->next()) { | 379 interval = interval->next()) { |
380 OS::Print(" use interval [%"Pd", %"Pd")\n", | 380 OS::Print(" use interval [%" Pd ", %" Pd ")\n", |
381 interval->start(), | 381 interval->start(), |
382 interval->end()); | 382 interval->end()); |
383 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) { | 383 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) { |
384 OS::Print(" use at %"Pd"", use_pos->pos()); | 384 OS::Print(" use at %" Pd "", use_pos->pos()); |
385 if (use_pos->location_slot() != NULL) { | 385 if (use_pos->location_slot() != NULL) { |
386 OS::Print(" as "); | 386 OS::Print(" as "); |
387 use_pos->location_slot()->Print(); | 387 use_pos->location_slot()->Print(); |
388 } | 388 } |
389 OS::Print("\n"); | 389 OS::Print("\n"); |
390 use_pos = use_pos->next(); | 390 use_pos = use_pos->next(); |
391 } | 391 } |
392 } | 392 } |
393 | 393 |
394 if (next_sibling() != NULL) { | 394 if (next_sibling() != NULL) { |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1475 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ? | 1475 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ? |
1476 first_after_split : last_use_interval_; | 1476 first_after_split : last_use_interval_; |
1477 next_sibling_ = new LiveRange(vreg(), | 1477 next_sibling_ = new LiveRange(vreg(), |
1478 representation(), | 1478 representation(), |
1479 first_use_after_split, | 1479 first_use_after_split, |
1480 first_after_split, | 1480 first_after_split, |
1481 last_use_interval, | 1481 last_use_interval, |
1482 first_safepoint_after_split, | 1482 first_safepoint_after_split, |
1483 next_sibling_); | 1483 next_sibling_); |
1484 | 1484 |
1485 TRACE_ALLOC(OS::Print(" split sibling [%"Pd", %"Pd")\n", | 1485 TRACE_ALLOC(OS::Print(" split sibling [%" Pd ", %" Pd ")\n", |
1486 next_sibling_->Start(), next_sibling_->End())); | 1486 next_sibling_->Start(), next_sibling_->End())); |
1487 | 1487 |
1488 last_use_interval_ = last_before_split; | 1488 last_use_interval_ = last_before_split; |
1489 last_use_interval_->next_ = NULL; | 1489 last_use_interval_->next_ = NULL; |
1490 | 1490 |
1491 if (first_use_after_split != NULL) { | 1491 if (first_use_after_split != NULL) { |
1492 finger_.UpdateAfterSplit(first_use_after_split->pos()); | 1492 finger_.UpdateAfterSplit(first_use_after_split->pos()); |
1493 } | 1493 } |
1494 | 1494 |
1495 return next_sibling_; | 1495 return next_sibling_; |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range, | 1499 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range, |
1500 intptr_t from, | 1500 intptr_t from, |
1501 intptr_t to) { | 1501 intptr_t to) { |
1502 TRACE_ALLOC(OS::Print("split v%"Pd" [%"Pd", %"Pd") between [%"Pd", %"Pd")\n", | 1502 TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %" Pd ") between [%" Pd ", %" Pd ")\n", |
siva
2013/08/20 19:54:51
TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %"
Jacob
2013/08/20 20:32:15
Done.
| |
1503 range->vreg(), range->Start(), range->End(), from, to)); | 1503 range->vreg(), range->Start(), range->End(), from, to)); |
1504 | 1504 |
1505 intptr_t split_pos = kIllegalPosition; | 1505 intptr_t split_pos = kIllegalPosition; |
1506 | 1506 |
1507 BlockInfo* split_block = BlockInfoAt(to); | 1507 BlockInfo* split_block = BlockInfoAt(to); |
1508 if (from < split_block->entry()->lifetime_position()) { | 1508 if (from < split_block->entry()->lifetime_position()) { |
1509 // Interval [from, to) spans multiple blocks. | 1509 // Interval [from, to) spans multiple blocks. |
1510 | 1510 |
1511 // If last block is inside a loop prefer splitting at outermost loop's | 1511 // If last block is inside a loop prefer splitting at outermost loop's |
1512 // header. | 1512 // header. |
(...skipping 17 matching lines...) Expand all Loading... | |
1530 ASSERT((split_pos != kIllegalPosition) && (from < split_pos)); | 1530 ASSERT((split_pos != kIllegalPosition) && (from < split_pos)); |
1531 | 1531 |
1532 return range->SplitAt(split_pos); | 1532 return range->SplitAt(split_pos); |
1533 } | 1533 } |
1534 | 1534 |
1535 | 1535 |
1536 void FlowGraphAllocator::SpillBetween(LiveRange* range, | 1536 void FlowGraphAllocator::SpillBetween(LiveRange* range, |
1537 intptr_t from, | 1537 intptr_t from, |
1538 intptr_t to) { | 1538 intptr_t to) { |
1539 ASSERT(from < to); | 1539 ASSERT(from < to); |
1540 TRACE_ALLOC(OS::Print("spill v%"Pd" [%"Pd", %"Pd") " | 1540 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") " |
1541 "between [%"Pd", %"Pd")\n", | 1541 "between [%" Pd ", %" Pd ")\n", |
1542 range->vreg(), range->Start(), range->End(), from, to)); | 1542 range->vreg(), range->Start(), range->End(), from, to)); |
1543 LiveRange* tail = range->SplitAt(from); | 1543 LiveRange* tail = range->SplitAt(from); |
1544 | 1544 |
1545 if (tail->Start() < to) { | 1545 if (tail->Start() < to) { |
1546 // There is an intersection of tail and [from, to). | 1546 // There is an intersection of tail and [from, to). |
1547 LiveRange* tail_tail = SplitBetween(tail, tail->Start(), to); | 1547 LiveRange* tail_tail = SplitBetween(tail, tail->Start(), to); |
1548 Spill(tail); | 1548 Spill(tail); |
1549 AddToUnallocated(tail_tail); | 1549 AddToUnallocated(tail_tail); |
1550 } else { | 1550 } else { |
1551 // No intersection between tail and [from, to). | 1551 // No intersection between tail and [from, to). |
1552 AddToUnallocated(tail); | 1552 AddToUnallocated(tail); |
1553 } | 1553 } |
1554 } | 1554 } |
1555 | 1555 |
1556 | 1556 |
1557 void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) { | 1557 void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) { |
1558 TRACE_ALLOC(OS::Print("spill v%"Pd" [%"Pd", %"Pd") after %"Pd"\n", | 1558 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") after %" Pd "\n", |
1559 range->vreg(), range->Start(), range->End(), from)); | 1559 range->vreg(), range->Start(), range->End(), from)); |
1560 | 1560 |
1561 // When spilling the value inside the loop check if this spill can | 1561 // When spilling the value inside the loop check if this spill can |
1562 // be moved outside. | 1562 // be moved outside. |
1563 BlockInfo* block_info = BlockInfoAt(from); | 1563 BlockInfo* block_info = BlockInfoAt(from); |
1564 if (block_info->is_loop_header() || (block_info->loop() != NULL)) { | 1564 if (block_info->is_loop_header() || (block_info->loop() != NULL)) { |
1565 BlockInfo* loop_header = | 1565 BlockInfo* loop_header = |
1566 block_info->is_loop_header() ? block_info : block_info->loop(); | 1566 block_info->is_loop_header() ? block_info : block_info->loop(); |
1567 | 1567 |
1568 if ((range->Start() <= loop_header->entry()->start_pos()) && | 1568 if ((range->Start() <= loop_header->entry()->start_pos()) && |
1569 RangeHasOnlyUnconstrainedUsesInLoop(range, loop_header->loop_id())) { | 1569 RangeHasOnlyUnconstrainedUsesInLoop(range, loop_header->loop_id())) { |
1570 ASSERT(loop_header->entry()->start_pos() <= from); | 1570 ASSERT(loop_header->entry()->start_pos() <= from); |
1571 from = loop_header->entry()->start_pos(); | 1571 from = loop_header->entry()->start_pos(); |
1572 TRACE_ALLOC(OS::Print(" moved spill position to loop header %"Pd"\n", | 1572 TRACE_ALLOC(OS::Print(" moved spill position to loop header %" Pd "\n", |
1573 from)); | 1573 from)); |
1574 } | 1574 } |
1575 } | 1575 } |
1576 | 1576 |
1577 LiveRange* tail = range->SplitAt(from); | 1577 LiveRange* tail = range->SplitAt(from); |
1578 Spill(tail); | 1578 Spill(tail); |
1579 } | 1579 } |
1580 | 1580 |
1581 | 1581 |
1582 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { | 1582 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1784 // If hint is available try hint first. | 1784 // If hint is available try hint first. |
1785 // TODO(vegorov): ensure that phis are hinted on the back edge. | 1785 // TODO(vegorov): ensure that phis are hinted on the back edge. |
1786 Location hint = unallocated->finger()->FirstHint(); | 1786 Location hint = unallocated->finger()->FirstHint(); |
1787 if (hint.IsMachineRegister()) { | 1787 if (hint.IsMachineRegister()) { |
1788 if (!blocked_registers_[hint.register_code()]) { | 1788 if (!blocked_registers_[hint.register_code()]) { |
1789 free_until = FirstIntersectionWithAllocated(hint.register_code(), | 1789 free_until = FirstIntersectionWithAllocated(hint.register_code(), |
1790 unallocated); | 1790 unallocated); |
1791 candidate = hint.register_code(); | 1791 candidate = hint.register_code(); |
1792 } | 1792 } |
1793 | 1793 |
1794 TRACE_ALLOC(OS::Print("found hint %s for v%"Pd": free until %"Pd"\n", | 1794 TRACE_ALLOC(OS::Print("found hint %s for v%" Pd ": free until %" Pd "\n", |
1795 hint.Name(), | 1795 hint.Name(), |
1796 unallocated->vreg(), | 1796 unallocated->vreg(), |
1797 free_until)); | 1797 free_until)); |
1798 } else { | 1798 } else { |
1799 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { | 1799 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { |
1800 if (!blocked_registers_[reg] && (registers_[reg].length() == 0)) { | 1800 if (!blocked_registers_[reg] && (registers_[reg].length() == 0)) { |
1801 candidate = reg; | 1801 candidate = reg; |
1802 free_until = kMaxPosition; | 1802 free_until = kMaxPosition; |
1803 break; | 1803 break; |
1804 } | 1804 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1846 const intptr_t reg = range->assigned_location().register_code(); | 1846 const intptr_t reg = range->assigned_location().register_code(); |
1847 | 1847 |
1848 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { | 1848 if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) { |
1849 used_on_backedge[reg] = true; | 1849 used_on_backedge[reg] = true; |
1850 } | 1850 } |
1851 } | 1851 } |
1852 } | 1852 } |
1853 | 1853 |
1854 if (used_on_backedge[candidate]) { | 1854 if (used_on_backedge[candidate]) { |
1855 TRACE_ALLOC(OS::Print( | 1855 TRACE_ALLOC(OS::Print( |
1856 "considering %s for v%"Pd": has interference on the back edge" | 1856 "considering %s for v%" Pd ": has interference on the back edge" |
1857 " {loop [%"Pd", %"Pd")}\n", | 1857 " {loop [%" Pd ", %" Pd ")}\n", |
1858 MakeRegisterLocation(candidate).Name(), | 1858 MakeRegisterLocation(candidate).Name(), |
1859 unallocated->vreg(), | 1859 unallocated->vreg(), |
1860 loop_header->entry()->start_pos(), | 1860 loop_header->entry()->start_pos(), |
1861 loop_header->last_block()->end_pos())); | 1861 loop_header->last_block()->end_pos())); |
1862 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { | 1862 for (intptr_t reg = 0; reg < NumberOfRegisters(); ++reg) { |
1863 if (blocked_registers_[reg] || | 1863 if (blocked_registers_[reg] || |
1864 (reg == candidate) || | 1864 (reg == candidate) || |
1865 used_on_backedge[reg]) { | 1865 used_on_backedge[reg]) { |
1866 continue; | 1866 continue; |
1867 } | 1867 } |
1868 | 1868 |
1869 const intptr_t intersection = | 1869 const intptr_t intersection = |
1870 FirstIntersectionWithAllocated(reg, unallocated); | 1870 FirstIntersectionWithAllocated(reg, unallocated); |
1871 if (intersection >= free_until) { | 1871 if (intersection >= free_until) { |
1872 candidate = reg; | 1872 candidate = reg; |
1873 free_until = intersection; | 1873 free_until = intersection; |
1874 TRACE_ALLOC(OS::Print( | 1874 TRACE_ALLOC(OS::Print( |
1875 "found %s for v%"Pd" with no interference on the back edge\n", | 1875 "found %s for v%" Pd " with no interference on the back edge\n", |
1876 MakeRegisterLocation(candidate).Name(), | 1876 MakeRegisterLocation(candidate).Name(), |
1877 candidate)); | 1877 candidate)); |
1878 break; | 1878 break; |
1879 } | 1879 } |
1880 } | 1880 } |
1881 } | 1881 } |
1882 } | 1882 } |
1883 | 1883 |
1884 TRACE_ALLOC(OS::Print("assigning free register ")); | 1884 TRACE_ALLOC(OS::Print("assigning free register ")); |
1885 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); | 1885 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); |
1886 TRACE_ALLOC(OS::Print(" to v%"Pd"\n", unallocated->vreg())); | 1886 TRACE_ALLOC(OS::Print(" to v%" Pd "\n", unallocated->vreg())); |
1887 | 1887 |
1888 if (free_until != kMaxPosition) { | 1888 if (free_until != kMaxPosition) { |
1889 // There was an intersection. Split unallocated. | 1889 // There was an intersection. Split unallocated. |
1890 TRACE_ALLOC(OS::Print(" splitting at %"Pd"\n", free_until)); | 1890 TRACE_ALLOC(OS::Print(" splitting at %" Pd "\n", free_until)); |
1891 LiveRange* tail = unallocated->SplitAt(free_until); | 1891 LiveRange* tail = unallocated->SplitAt(free_until); |
1892 AddToUnallocated(tail); | 1892 AddToUnallocated(tail); |
1893 } | 1893 } |
1894 | 1894 |
1895 registers_[candidate].Add(unallocated); | 1895 registers_[candidate].Add(unallocated); |
1896 unallocated->set_assigned_location(MakeRegisterLocation(candidate)); | 1896 unallocated->set_assigned_location(MakeRegisterLocation(candidate)); |
1897 | 1897 |
1898 return true; | 1898 return true; |
1899 } | 1899 } |
1900 | 1900 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1978 : unallocated->Start(); | 1978 : unallocated->Start(); |
1979 if (free_until < register_use_pos) { | 1979 if (free_until < register_use_pos) { |
1980 // Can't acquire free register. Spill until we really need one. | 1980 // Can't acquire free register. Spill until we really need one. |
1981 ASSERT(unallocated->Start() < ToInstructionStart(register_use_pos)); | 1981 ASSERT(unallocated->Start() < ToInstructionStart(register_use_pos)); |
1982 SpillBetween(unallocated, unallocated->Start(), register_use->pos()); | 1982 SpillBetween(unallocated, unallocated->Start(), register_use->pos()); |
1983 return; | 1983 return; |
1984 } | 1984 } |
1985 | 1985 |
1986 TRACE_ALLOC(OS::Print("assigning blocked register ")); | 1986 TRACE_ALLOC(OS::Print("assigning blocked register ")); |
1987 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); | 1987 TRACE_ALLOC(MakeRegisterLocation(candidate).Print()); |
1988 TRACE_ALLOC(OS::Print(" to live range v%"Pd" until %"Pd"\n", | 1988 TRACE_ALLOC(OS::Print(" to live range v%" Pd " until %" Pd "\n", |
1989 unallocated->vreg(), blocked_at)); | 1989 unallocated->vreg(), blocked_at)); |
1990 | 1990 |
1991 if (blocked_at < unallocated->End()) { | 1991 if (blocked_at < unallocated->End()) { |
1992 // Register is blocked before the end of the live range. Split the range | 1992 // Register is blocked before the end of the live range. Split the range |
1993 // at latest at blocked_at position. | 1993 // at latest at blocked_at position. |
1994 LiveRange* tail = SplitBetween(unallocated, | 1994 LiveRange* tail = SplitBetween(unallocated, |
1995 unallocated->Start(), | 1995 unallocated->Start(), |
1996 blocked_at + 1); | 1996 blocked_at + 1); |
1997 AddToUnallocated(tail); | 1997 AddToUnallocated(tail); |
1998 } | 1998 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2135 } | 2135 } |
2136 | 2136 |
2137 return parallel_move->AddMove(to, from); | 2137 return parallel_move->AddMove(to, from); |
2138 } | 2138 } |
2139 | 2139 |
2140 | 2140 |
2141 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { | 2141 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { |
2142 ASSERT(use->location_slot() != NULL); | 2142 ASSERT(use->location_slot() != NULL); |
2143 Location* slot = use->location_slot(); | 2143 Location* slot = use->location_slot(); |
2144 ASSERT(slot->IsUnallocated()); | 2144 ASSERT(slot->IsUnallocated()); |
2145 TRACE_ALLOC(OS::Print(" use at %"Pd" converted to ", use->pos())); | 2145 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos())); |
2146 TRACE_ALLOC(loc.Print()); | 2146 TRACE_ALLOC(loc.Print()); |
2147 TRACE_ALLOC(OS::Print("\n")); | 2147 TRACE_ALLOC(OS::Print("\n")); |
2148 *slot = loc; | 2148 *slot = loc; |
2149 } | 2149 } |
2150 | 2150 |
2151 | 2151 |
2152 void FlowGraphAllocator::ConvertAllUses(LiveRange* range) { | 2152 void FlowGraphAllocator::ConvertAllUses(LiveRange* range) { |
2153 if (range->vreg() == kNoVirtualRegister) return; | 2153 if (range->vreg() == kNoVirtualRegister) return; |
2154 | 2154 |
2155 const Location loc = range->assigned_location(); | 2155 const Location loc = range->assigned_location(); |
2156 ASSERT(!loc.IsInvalid()); | 2156 ASSERT(!loc.IsInvalid()); |
2157 | 2157 |
2158 TRACE_ALLOC(OS::Print("range [%"Pd", %"Pd") " | 2158 TRACE_ALLOC(OS::Print("range [%" Pd ", %" Pd ") " |
2159 "for v%"Pd" has been allocated to ", | 2159 "for v%" Pd " has been allocated to ", |
2160 range->Start(), range->End(), range->vreg())); | 2160 range->Start(), range->End(), range->vreg())); |
2161 TRACE_ALLOC(loc.Print()); | 2161 TRACE_ALLOC(loc.Print()); |
2162 TRACE_ALLOC(OS::Print(":\n")); | 2162 TRACE_ALLOC(OS::Print(":\n")); |
2163 | 2163 |
2164 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { | 2164 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { |
2165 ConvertUseTo(use, loc); | 2165 ConvertUseTo(use, loc); |
2166 } | 2166 } |
2167 | 2167 |
2168 // Add live registers at all safepoints for instructions with slow-path | 2168 // Add live registers at all safepoints for instructions with slow-path |
2169 // code. | 2169 // code. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2314 | 2314 |
2315 | 2315 |
2316 void FlowGraphAllocator::AllocateUnallocatedRanges() { | 2316 void FlowGraphAllocator::AllocateUnallocatedRanges() { |
2317 #if defined(DEBUG) | 2317 #if defined(DEBUG) |
2318 ASSERT(UnallocatedIsSorted()); | 2318 ASSERT(UnallocatedIsSorted()); |
2319 #endif | 2319 #endif |
2320 | 2320 |
2321 while (!unallocated_.is_empty()) { | 2321 while (!unallocated_.is_empty()) { |
2322 LiveRange* range = unallocated_.RemoveLast(); | 2322 LiveRange* range = unallocated_.RemoveLast(); |
2323 const intptr_t start = range->Start(); | 2323 const intptr_t start = range->Start(); |
2324 TRACE_ALLOC(OS::Print("Processing live range for v%"Pd" " | 2324 TRACE_ALLOC(OS::Print("Processing live range for v%" Pd " " |
2325 "starting at %"Pd"\n", | 2325 "starting at %" Pd "\n", |
2326 range->vreg(), | 2326 range->vreg(), |
2327 start)); | 2327 start)); |
2328 | 2328 |
2329 // TODO(vegorov): eagerly spill liveranges without register uses. | 2329 // TODO(vegorov): eagerly spill liveranges without register uses. |
2330 AdvanceActiveIntervals(start); | 2330 AdvanceActiveIntervals(start); |
2331 | 2331 |
2332 if (!AllocateFreeRegister(range)) { | 2332 if (!AllocateFreeRegister(range)) { |
2333 AllocateAnyRegister(range); | 2333 AllocateAnyRegister(range); |
2334 } | 2334 } |
2335 } | 2335 } |
(...skipping 15 matching lines...) Expand all Loading... | |
2351 ASSERT(GetLiveRange(range->vreg())->spill_slot().Equals(target)); | 2351 ASSERT(GetLiveRange(range->vreg())->spill_slot().Equals(target)); |
2352 return true; | 2352 return true; |
2353 } | 2353 } |
2354 return false; | 2354 return false; |
2355 } | 2355 } |
2356 | 2356 |
2357 | 2357 |
2358 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent, | 2358 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent, |
2359 BlockEntryInstr* source_block, | 2359 BlockEntryInstr* source_block, |
2360 BlockEntryInstr* target_block) { | 2360 BlockEntryInstr* target_block) { |
2361 TRACE_ALLOC(OS::Print("Connect v%"Pd" on the edge B%"Pd" -> B%"Pd"\n", | 2361 TRACE_ALLOC(OS::Print("Connect v%" Pd " on the edge B%" Pd " -> B%" Pd "\n", |
2362 parent->vreg(), | 2362 parent->vreg(), |
2363 source_block->block_id(), | 2363 source_block->block_id(), |
2364 target_block->block_id())); | 2364 target_block->block_id())); |
2365 if (parent->next_sibling() == NULL) { | 2365 if (parent->next_sibling() == NULL) { |
2366 // Nothing to connect. The whole range was allocated to the same location. | 2366 // Nothing to connect. The whole range was allocated to the same location. |
2367 TRACE_ALLOC(OS::Print("range v%"Pd" has no siblings\n", parent->vreg())); | 2367 TRACE_ALLOC(OS::Print("range v%" Pd " has no siblings\n", parent->vreg())); |
2368 return; | 2368 return; |
2369 } | 2369 } |
2370 | 2370 |
2371 const intptr_t source_pos = source_block->end_pos() - 1; | 2371 const intptr_t source_pos = source_block->end_pos() - 1; |
2372 ASSERT(IsInstructionEndPosition(source_pos)); | 2372 ASSERT(IsInstructionEndPosition(source_pos)); |
2373 | 2373 |
2374 const intptr_t target_pos = target_block->start_pos(); | 2374 const intptr_t target_pos = target_block->start_pos(); |
2375 | 2375 |
2376 Location target; | 2376 Location target; |
2377 Location source; | 2377 Location source; |
(...skipping 16 matching lines...) Expand all Loading... | |
2394 ASSERT(target.IsInvalid()); | 2394 ASSERT(target.IsInvalid()); |
2395 target = range->assigned_location(); | 2395 target = range->assigned_location(); |
2396 #if defined(DEBUG) | 2396 #if defined(DEBUG) |
2397 target_cover = range; | 2397 target_cover = range; |
2398 #endif | 2398 #endif |
2399 } | 2399 } |
2400 | 2400 |
2401 range = range->next_sibling(); | 2401 range = range->next_sibling(); |
2402 } | 2402 } |
2403 | 2403 |
2404 TRACE_ALLOC(OS::Print("connecting v%"Pd" between [%"Pd", %"Pd") {%s} " | 2404 TRACE_ALLOC(OS::Print("connecting v%" Pd " between [%" Pd ", %" Pd ") {%s} " |
2405 "to [%"Pd", %"Pd") {%s}\n", | 2405 "to [%" Pd ", %" Pd ") {%s}\n", |
2406 parent->vreg(), | 2406 parent->vreg(), |
2407 source_cover->Start(), | 2407 source_cover->Start(), |
2408 source_cover->End(), | 2408 source_cover->End(), |
2409 source.Name(), | 2409 source.Name(), |
2410 target_cover->Start(), | 2410 target_cover->Start(), |
2411 target_cover->End(), | 2411 target_cover->End(), |
2412 target.Name())); | 2412 target.Name())); |
2413 | 2413 |
2414 // Siblings were allocated to the same register. | 2414 // Siblings were allocated to the same register. |
2415 if (source.Equals(target)) return; | 2415 if (source.Equals(target)) return; |
(...skipping 15 matching lines...) Expand all Loading... | |
2431 | 2431 |
2432 void FlowGraphAllocator::ResolveControlFlow() { | 2432 void FlowGraphAllocator::ResolveControlFlow() { |
2433 // Resolve linear control flow between touching split siblings | 2433 // Resolve linear control flow between touching split siblings |
2434 // inside basic blocks. | 2434 // inside basic blocks. |
2435 for (intptr_t vreg = 0; vreg < live_ranges_.length(); vreg++) { | 2435 for (intptr_t vreg = 0; vreg < live_ranges_.length(); vreg++) { |
2436 LiveRange* range = live_ranges_[vreg]; | 2436 LiveRange* range = live_ranges_[vreg]; |
2437 if (range == NULL) continue; | 2437 if (range == NULL) continue; |
2438 | 2438 |
2439 while (range->next_sibling() != NULL) { | 2439 while (range->next_sibling() != NULL) { |
2440 LiveRange* sibling = range->next_sibling(); | 2440 LiveRange* sibling = range->next_sibling(); |
2441 TRACE_ALLOC(OS::Print("connecting [%"Pd", %"Pd") [", | 2441 TRACE_ALLOC(OS::Print("connecting [%" Pd ", %" Pd ") [", |
2442 range->Start(), range->End())); | 2442 range->Start(), range->End())); |
2443 TRACE_ALLOC(range->assigned_location().Print()); | 2443 TRACE_ALLOC(range->assigned_location().Print()); |
2444 TRACE_ALLOC(OS::Print("] to [%"Pd", %"Pd") [", | 2444 TRACE_ALLOC(OS::Print("] to [%" Pd ", %" Pd ") [", |
2445 sibling->Start(), sibling->End())); | 2445 sibling->Start(), sibling->End())); |
2446 TRACE_ALLOC(sibling->assigned_location().Print()); | 2446 TRACE_ALLOC(sibling->assigned_location().Print()); |
2447 TRACE_ALLOC(OS::Print("]\n")); | 2447 TRACE_ALLOC(OS::Print("]\n")); |
2448 if ((range->End() == sibling->Start()) && | 2448 if ((range->End() == sibling->Start()) && |
2449 !TargetLocationIsSpillSlot(range, sibling->assigned_location()) && | 2449 !TargetLocationIsSpillSlot(range, sibling->assigned_location()) && |
2450 !range->assigned_location().Equals(sibling->assigned_location()) && | 2450 !range->assigned_location().Equals(sibling->assigned_location()) && |
2451 !IsBlockEntry(range->End())) { | 2451 !IsBlockEntry(range->End())) { |
2452 AddMoveAt(sibling->Start(), | 2452 AddMoveAt(sibling->Start(), |
2453 sibling->assigned_location(), | 2453 sibling->assigned_location(), |
2454 range->assigned_location()); | 2454 range->assigned_location()); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2599 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2599 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
2600 function.ToFullyQualifiedCString()); | 2600 function.ToFullyQualifiedCString()); |
2601 FlowGraphPrinter printer(flow_graph_, true); | 2601 FlowGraphPrinter printer(flow_graph_, true); |
2602 printer.PrintBlocks(); | 2602 printer.PrintBlocks(); |
2603 OS::Print("----------------------------------------------\n"); | 2603 OS::Print("----------------------------------------------\n"); |
2604 } | 2604 } |
2605 } | 2605 } |
2606 | 2606 |
2607 | 2607 |
2608 } // namespace dart | 2608 } // namespace dart |
OLD | NEW |