Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 return; | 273 return; |
| 274 } else if (uses_->location_slot() == NULL) { | 274 } else if (uses_->location_slot() == NULL) { |
| 275 uses_->set_location_slot(location_slot); | 275 uses_->set_location_slot(location_slot); |
| 276 return; | 276 return; |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 uses_ = new UsePosition(pos, uses_, location_slot); | 279 uses_ = new UsePosition(pos, uses_, location_slot); |
| 280 } | 280 } |
| 281 | 281 |
| 282 | 282 |
| 283 void LiveRange::AddHintedUse(intptr_t pos, | |
| 284 Location* location_slot, | |
| 285 Location* hint) { | |
|
srdjan
2012/08/07 19:38:20
AddUseWithHint instead of AddHintedUse?
| |
| 286 ASSERT(hint != NULL); | |
| 287 AddUse(pos, location_slot); | |
| 288 uses_->set_hint(hint); | |
| 289 } | |
| 290 | |
| 291 | |
| 283 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) { | 292 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) { |
| 284 ASSERT(start < end); | 293 ASSERT(start < end); |
| 285 | 294 |
| 286 // Live ranges are being build by visiting instructions in post-order. | 295 // Live ranges are being build by visiting instructions in post-order. |
| 287 // This implies that use intervals will be perpended in a monotonically | 296 // This implies that use intervals will be perpended in a monotonically |
| 288 // decreasing order. | 297 // decreasing order. |
| 289 if (first_use_interval() != NULL) { | 298 if (first_use_interval() != NULL) { |
| 290 // If the first use interval and the use interval we are adding | 299 // If the first use interval and the use interval we are adding |
| 291 // touch then we can just extend the first interval to cover their | 300 // touch then we can just extend the first interval to cover their |
| 292 // union. | 301 // union. |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 // Expected shape of live ranges: | 562 // Expected shape of live ranges: |
| 554 // | 563 // |
| 555 // g g' | 564 // g g' |
| 556 // value --* | 565 // value --* |
| 557 // | 566 // |
| 558 | 567 |
| 559 LiveRange* range = GetLiveRange( | 568 LiveRange* range = GetLiveRange( |
| 560 val->AsUse()->definition()->ssa_temp_index()); | 569 val->AsUse()->definition()->ssa_temp_index()); |
| 561 | 570 |
| 562 range->AddUseInterval(block->start_pos(), pos); | 571 range->AddUseInterval(block->start_pos(), pos); |
| 563 range->AddUse(pos, move->src_slot()); | 572 range->AddHintedUse(pos, move->src_slot(), move->dest_slot()); |
| 564 | 573 |
| 565 move->set_src(Location::PrefersRegister()); | 574 move->set_src(Location::PrefersRegister()); |
| 566 } else { | 575 } else { |
| 567 ASSERT(val->IsConstant()); | 576 ASSERT(val->IsConstant()); |
| 568 move->set_src(Location::Constant(val->AsConstant()->value())); | 577 move->set_src(Location::Constant(val->AsConstant()->value())); |
| 569 } | 578 } |
| 570 move_idx++; | 579 move_idx++; |
| 571 } | 580 } |
| 572 | 581 |
| 573 // Begin backward iteration with the instruction before the parallel | 582 // Begin backward iteration with the instruction before the parallel |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 698 // live ranges: | 707 // live ranges: |
| 699 // | 708 // |
| 700 // j' i i' | 709 // j' i i' |
| 701 // value --* | 710 // value --* |
| 702 // register [-----) | 711 // register [-----) |
| 703 // | 712 // |
| 704 MoveOperands* move = | 713 MoveOperands* move = |
| 705 AddMoveAt(pos - 1, *in_ref, Location::Any()); | 714 AddMoveAt(pos - 1, *in_ref, Location::Any()); |
| 706 BlockLocation(*in_ref, pos - 1, pos + 1); | 715 BlockLocation(*in_ref, pos - 1, pos + 1); |
| 707 range->AddUseInterval(block->start_pos(), pos - 1); | 716 range->AddUseInterval(block->start_pos(), pos - 1); |
| 708 range->AddUse(pos - 1, move->src_slot()); | 717 range->AddHintedUse(pos - 1, move->src_slot(), in_ref); |
| 709 } else { | 718 } else { |
| 710 // Normal unallocated input. Expected shape of | 719 // Normal unallocated input. Expected shape of |
| 711 // live ranges: | 720 // live ranges: |
| 712 // | 721 // |
| 713 // i i' | 722 // i i' |
| 714 // value -----* | 723 // value -----* |
| 715 // | 724 // |
| 716 ASSERT(in_ref->IsUnallocated()); | 725 ASSERT(in_ref->IsUnallocated()); |
| 717 range->AddUseInterval(block->start_pos(), pos + 1); | 726 range->AddUseInterval(block->start_pos(), pos + 1); |
| 718 range->AddUse(pos + 1, in_ref); | 727 range->AddUse(pos + 1, in_ref); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 range->set_first_use(range->first_use()->next()); | 825 range->set_first_use(range->first_use()->next()); |
| 817 } | 826 } |
| 818 | 827 |
| 819 // Shorten live range to the point of definition, this might make the range | 828 // Shorten live range to the point of definition, this might make the range |
| 820 // empty (if the only use immediately follows). If range is not empty add | 829 // empty (if the only use immediately follows). If range is not empty add |
| 821 // move from a fixed register to an unallocated location. | 830 // move from a fixed register to an unallocated location. |
| 822 range->DefineAt(pos + 1); | 831 range->DefineAt(pos + 1); |
| 823 if (range->Start() == range->End()) return; | 832 if (range->Start() == range->End()) return; |
| 824 | 833 |
| 825 MoveOperands* move = AddMoveAt(pos + 1, Location::Any(), *out); | 834 MoveOperands* move = AddMoveAt(pos + 1, Location::Any(), *out); |
| 826 range->AddUse(pos + 1, move->dest_slot()); | 835 range->AddHintedUse(pos + 1, move->dest_slot(), out); |
| 827 } else if (output_same_as_first_input) { | 836 } else if (output_same_as_first_input) { |
| 828 // Output register will contain a value of the first input at instruction's | 837 // Output register will contain a value of the first input at instruction's |
| 829 // start. Expected shape of live ranges: | 838 // start. Expected shape of live ranges: |
| 830 // | 839 // |
| 831 // i i' | 840 // i i' |
| 832 // input #0 --* | 841 // input #0 --* |
| 833 // output [---- | 842 // output [---- |
| 834 // | 843 // |
| 835 ASSERT(locs->in_slot(0)->Equals(Location::RequiresRegister())); | 844 ASSERT(locs->in_slot(0)->Equals(Location::RequiresRegister())); |
| 836 | 845 |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 | 1344 |
| 1336 | 1345 |
| 1337 | 1346 |
| 1338 bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) { | 1347 bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) { |
| 1339 Register candidate = kNoRegister; | 1348 Register candidate = kNoRegister; |
| 1340 intptr_t free_until = 0; | 1349 intptr_t free_until = 0; |
| 1341 | 1350 |
| 1342 // If hint is available try hint first. | 1351 // If hint is available try hint first. |
| 1343 // TODO(vegorov): ensure that phis are hinted on the back edge. | 1352 // TODO(vegorov): ensure that phis are hinted on the back edge. |
| 1344 Location hint = unallocated->finger()->FirstHint(); | 1353 Location hint = unallocated->finger()->FirstHint(); |
| 1345 if (!hint.IsInvalid()) { | 1354 if (hint.IsRegister()) { |
| 1346 ASSERT(hint.IsRegister()); | |
| 1347 | |
| 1348 if (!blocked_cpu_regs_[hint.reg()]) { | 1355 if (!blocked_cpu_regs_[hint.reg()]) { |
| 1349 free_until = FirstIntersectionWithAllocated(hint.reg(), unallocated); | 1356 free_until = FirstIntersectionWithAllocated(hint.reg(), unallocated); |
| 1350 candidate = hint.reg(); | 1357 candidate = hint.reg(); |
| 1351 } | 1358 } |
| 1352 | 1359 |
| 1353 TRACE_ALLOC(OS::Print("found hint ")); | 1360 TRACE_ALLOC(OS::Print("found hint ")); |
| 1354 TRACE_ALLOC(hint.Print()); | 1361 TRACE_ALLOC(hint.Print()); |
| 1355 TRACE_ALLOC(OS::Print(" for %d: free until %d\n", | 1362 TRACE_ALLOC(OS::Print(" for %d: free until %d\n", |
| 1356 unallocated->vreg(), free_until)); | 1363 unallocated->vreg(), free_until)); |
| 1357 } | 1364 } else if (free_until != kMaxPosition) { |
| 1358 | |
| 1359 if (free_until != kMaxPosition) { | |
| 1360 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; ++reg) { | 1365 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; ++reg) { |
| 1361 if (!blocked_cpu_regs_[reg] && cpu_regs_[reg].length() == 0) { | 1366 if (!blocked_cpu_regs_[reg] && cpu_regs_[reg].length() == 0) { |
| 1362 candidate = static_cast<Register>(reg); | 1367 candidate = static_cast<Register>(reg); |
| 1363 free_until = kMaxPosition; | 1368 free_until = kMaxPosition; |
| 1364 break; | 1369 break; |
| 1365 } | 1370 } |
| 1366 } | 1371 } |
| 1367 } | 1372 } |
| 1368 | 1373 |
| 1369 ASSERT(0 <= kMaxPosition); | 1374 ASSERT(0 <= kMaxPosition); |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1883 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 1888 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
| 1884 function.ToFullyQualifiedCString()); | 1889 function.ToFullyQualifiedCString()); |
| 1885 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 1890 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
| 1886 printer.PrintBlocks(); | 1891 printer.PrintBlocks(); |
| 1887 OS::Print("----------------------------------------------\n"); | 1892 OS::Print("----------------------------------------------\n"); |
| 1888 } | 1893 } |
| 1889 } | 1894 } |
| 1890 | 1895 |
| 1891 | 1896 |
| 1892 } // namespace dart | 1897 } // namespace dart |
| OLD | NEW |