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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 return; | 304 return; |
305 } else if (uses_->location_slot() == NULL) { | 305 } else if (uses_->location_slot() == NULL) { |
306 uses_->set_location_slot(location_slot); | 306 uses_->set_location_slot(location_slot); |
307 return; | 307 return; |
308 } | 308 } |
309 } | 309 } |
310 uses_ = new UsePosition(pos, uses_, location_slot); | 310 uses_ = new UsePosition(pos, uses_, location_slot); |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 void LiveRange::AddSafepoint(intptr_t pos, LocationSummary* locs) { | |
315 SafepointPosition* new_pos = new SafepointPosition(pos, locs, NULL); | |
Kevin Millikin (Google)
2012/08/14 11:18:16
Weird that new_pos has a different type than pos.
Vyacheslav Egorov (Google)
2012/08/14 12:31:13
Done.
| |
316 | |
317 if (safepoints_ == NULL) { | |
318 ASSERT(safepoints_tail_ == NULL); | |
319 safepoints_ = safepoints_tail_ = new_pos; | |
320 } else { | |
321 ASSERT(safepoints_tail_ != NULL); | |
322 ASSERT(safepoints_tail_->pos() < pos); | |
Kevin Millikin (Google)
2012/08/14 11:18:16
Comment that we assume the list is sorted by posit
Vyacheslav Egorov (Google)
2012/08/14 12:31:13
Done.
| |
323 safepoints_tail_->set_next(new_pos); | |
324 safepoints_tail_ = new_pos; | |
325 } | |
326 } | |
327 | |
328 | |
314 void LiveRange::AddHintedUse(intptr_t pos, | 329 void LiveRange::AddHintedUse(intptr_t pos, |
315 Location* location_slot, | 330 Location* location_slot, |
316 Location* hint) { | 331 Location* hint) { |
317 ASSERT(hint != NULL); | 332 ASSERT(hint != NULL); |
318 AddUse(pos, location_slot); | 333 AddUse(pos, location_slot); |
319 uses_->set_hint(hint); | 334 uses_->set_hint(hint); |
320 } | 335 } |
321 | 336 |
322 | 337 |
323 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) { | 338 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
512 slot_index -= fixed_parameters_count; | 527 slot_index -= fixed_parameters_count; |
513 } | 528 } |
514 | 529 |
515 range->set_assigned_location(Location::StackSlot(slot_index)); | 530 range->set_assigned_location(Location::StackSlot(slot_index)); |
516 range->set_spill_slot(Location::StackSlot(slot_index)); | 531 range->set_spill_slot(Location::StackSlot(slot_index)); |
517 if (copied) { | 532 if (copied) { |
518 ASSERT(spill_slots_.length() == slot_index); | 533 ASSERT(spill_slots_.length() == slot_index); |
519 spill_slots_.Add(range->End()); | 534 spill_slots_.Add(range->End()); |
520 } | 535 } |
521 | 536 |
537 AssignSafepoints(range); | |
538 | |
522 range->finger()->Initialize(range); | 539 range->finger()->Initialize(range); |
523 UsePosition* use = range->finger()->FirstRegisterBeneficialUse( | 540 UsePosition* use = range->finger()->FirstRegisterBeneficialUse( |
524 graph_entry->start_pos()); | 541 graph_entry->start_pos()); |
525 if (use != NULL) { | 542 if (use != NULL) { |
526 LiveRange* tail = SplitBetween(range, | 543 LiveRange* tail = SplitBetween(range, |
527 graph_entry->start_pos(), | 544 graph_entry->start_pos(), |
528 use->pos()); | 545 use->pos()); |
529 AddToUnallocated(tail); | 546 AddToUnallocated(tail); |
530 } | 547 } |
531 ConvertAllUses(range); | 548 ConvertAllUses(range); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); | 668 GotoInstr* goto_instr = pred->last_instruction()->AsGoto(); |
652 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); | 669 ASSERT((goto_instr != NULL) && (goto_instr->HasParallelMove())); |
653 MoveOperands* move = | 670 MoveOperands* move = |
654 goto_instr->parallel_move()->MoveOperandsAt(move_idx); | 671 goto_instr->parallel_move()->MoveOperandsAt(move_idx); |
655 move->set_dest(Location::PrefersRegister()); | 672 move->set_dest(Location::PrefersRegister()); |
656 range->AddUse(pos, move->dest_slot()); | 673 range->AddUse(pos, move->dest_slot()); |
657 } | 674 } |
658 | 675 |
659 // All phi resolution moves are connected. Phi's live range is | 676 // All phi resolution moves are connected. Phi's live range is |
660 // complete. | 677 // complete. |
678 AssignSafepoints(range); | |
661 AddToUnallocated(range); | 679 AddToUnallocated(range); |
662 | 680 |
663 move_idx++; | 681 move_idx++; |
664 } | 682 } |
665 } | 683 } |
666 } | 684 } |
667 | 685 |
668 | 686 |
669 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, | 687 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
670 Instruction* current) { | 688 Instruction* current) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
805 } | 823 } |
806 | 824 |
807 // Block all allocatable registers for calls and record the stack bitmap. | 825 // Block all allocatable registers for calls and record the stack bitmap. |
808 if (locs->is_call()) { | 826 if (locs->is_call()) { |
809 // Expected shape of live range: | 827 // Expected shape of live range: |
810 // | 828 // |
811 // i i' | 829 // i i' |
812 // [--) | 830 // [--) |
813 // | 831 // |
814 // The stack bitmap describes the position i. | 832 // The stack bitmap describes the position i. |
815 Safepoint safepoint = { pos, locs->stack_bitmap() }; | |
816 safepoints_.Add(safepoint); | |
817 | |
818 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { | 833 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { |
819 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), | 834 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), |
820 pos, | 835 pos, |
821 pos + 1); | 836 pos + 1); |
822 } | 837 } |
823 | 838 |
824 #if defined(DEBUG) | 839 #if defined(DEBUG) |
825 // Verify that temps, inputs and output were specified as fixed | 840 // Verify that temps, inputs and output were specified as fixed |
826 // locations. Every register is blocked now so attempt to | 841 // locations. Every register is blocked now so attempt to |
827 // allocate will not succeed. | 842 // allocate will not succeed. |
828 for (intptr_t j = 0; j < locs->temp_count(); j++) { | 843 for (intptr_t j = 0; j < locs->temp_count(); j++) { |
829 ASSERT(!locs->temp(j).IsUnallocated()); | 844 ASSERT(!locs->temp(j).IsUnallocated()); |
830 } | 845 } |
831 | 846 |
832 for (intptr_t j = 0; j < locs->input_count(); j++) { | 847 for (intptr_t j = 0; j < locs->input_count(); j++) { |
833 ASSERT(!locs->in(j).IsUnallocated()); | 848 ASSERT(!locs->in(j).IsUnallocated()); |
834 } | 849 } |
835 | 850 |
836 ASSERT(!locs->out().IsUnallocated()); | 851 ASSERT(!locs->out().IsUnallocated()); |
837 #endif | 852 #endif |
838 } | 853 } |
839 | 854 |
855 if (locs->contains_call() != LocationSummary::kNoCall) { | |
856 safepoints_.Add(current); | |
857 } | |
858 | |
840 Definition* def = current->AsDefinition(); | 859 Definition* def = current->AsDefinition(); |
841 if (def == NULL) { | 860 if (def == NULL) { |
842 ASSERT(locs->out().IsInvalid()); | 861 ASSERT(locs->out().IsInvalid()); |
843 return; | 862 return; |
844 } | 863 } |
845 | 864 |
846 if (locs->out().IsInvalid()) { | 865 if (locs->out().IsInvalid()) { |
847 ASSERT(def->ssa_temp_index() < 0); | 866 ASSERT(def->ssa_temp_index() < 0); |
848 return; | 867 return; |
849 } | 868 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
930 // | 949 // |
931 ASSERT(out->IsUnallocated() && | 950 ASSERT(out->IsUnallocated() && |
932 (out->policy() == Location::kRequiresRegister)); | 951 (out->policy() == Location::kRequiresRegister)); |
933 | 952 |
934 // Shorten live range to the point of definition and add use to be filled by | 953 // Shorten live range to the point of definition and add use to be filled by |
935 // allocator. | 954 // allocator. |
936 range->DefineAt(pos); | 955 range->DefineAt(pos); |
937 range->AddUse(pos, out); | 956 range->AddUse(pos, out); |
938 } | 957 } |
939 | 958 |
959 AssignSafepoints(range); | |
940 AddToUnallocated(range); | 960 AddToUnallocated(range); |
941 } | 961 } |
942 | 962 |
943 | 963 |
944 static ParallelMoveInstr* CreateParallelMoveBefore(Instruction* instr, | 964 static ParallelMoveInstr* CreateParallelMoveBefore(Instruction* instr, |
945 intptr_t pos) { | 965 intptr_t pos) { |
946 ASSERT(pos > 0); | 966 ASSERT(pos > 0); |
947 Instruction* prev = instr->previous(); | 967 Instruction* prev = instr->previous(); |
948 ParallelMoveInstr* move = prev->AsParallelMove(); | 968 ParallelMoveInstr* move = prev->AsParallelMove(); |
949 if ((move == NULL) || (move->lifetime_position() != pos)) { | 969 if ((move == NULL) || (move->lifetime_position() != pos)) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1197 return kMaxPosition; | 1217 return kMaxPosition; |
1198 } | 1218 } |
1199 | 1219 |
1200 | 1220 |
1201 LiveRange* LiveRange::MakeTemp(intptr_t pos, Location* location_slot) { | 1221 LiveRange* LiveRange::MakeTemp(intptr_t pos, Location* location_slot) { |
1202 UNREACHABLE(); | 1222 UNREACHABLE(); |
1203 return NULL; | 1223 return NULL; |
1204 } | 1224 } |
1205 | 1225 |
1206 | 1226 |
1227 template<typename PositionType> | |
1228 PositionType* SplitListOfPositions(PositionType** head, | |
1229 intptr_t split_pos, | |
1230 bool split_at_start) { | |
1231 PositionType* last_before_split = NULL; | |
1232 PositionType* pos = *head; | |
1233 if (split_at_start) { | |
1234 while ((pos != NULL) && (pos->pos() < split_pos)) { | |
1235 last_before_split = pos; | |
1236 pos = pos->next(); | |
1237 } | |
1238 } else { | |
1239 while ((pos != NULL) && (pos->pos() <= split_pos)) { | |
1240 last_before_split = pos; | |
1241 pos = pos->next(); | |
1242 } | |
1243 } | |
1244 | |
1245 if (last_before_split == NULL) { | |
1246 *head = NULL; | |
1247 } else { | |
1248 last_before_split->set_next(NULL); | |
1249 } | |
1250 | |
1251 return pos; | |
1252 } | |
1253 | |
1254 | |
1207 LiveRange* LiveRange::SplitAt(intptr_t split_pos) { | 1255 LiveRange* LiveRange::SplitAt(intptr_t split_pos) { |
1208 if (Start() == split_pos) return this; | 1256 if (Start() == split_pos) return this; |
1209 | 1257 |
1210 UseInterval* interval = finger_.first_pending_use_interval(); | 1258 UseInterval* interval = finger_.first_pending_use_interval(); |
1211 if (interval == NULL) { | 1259 if (interval == NULL) { |
1212 finger_.Initialize(this); | 1260 finger_.Initialize(this); |
1213 interval = finger_.first_pending_use_interval(); | 1261 interval = finger_.first_pending_use_interval(); |
1214 } | 1262 } |
1215 | 1263 |
1216 ASSERT(split_pos < End()); | 1264 ASSERT(split_pos < End()); |
(...skipping 16 matching lines...) Expand all Loading... | |
1233 interval->next()); | 1281 interval->next()); |
1234 interval->end_ = split_pos; | 1282 interval->end_ = split_pos; |
1235 interval->next_ = first_after_split; | 1283 interval->next_ = first_after_split; |
1236 last_before_split = interval; | 1284 last_before_split = interval; |
1237 } | 1285 } |
1238 | 1286 |
1239 ASSERT(last_before_split->next() == first_after_split); | 1287 ASSERT(last_before_split->next() == first_after_split); |
1240 ASSERT(last_before_split->end() <= split_pos); | 1288 ASSERT(last_before_split->end() <= split_pos); |
1241 ASSERT(split_pos <= first_after_split->start()); | 1289 ASSERT(split_pos <= first_after_split->start()); |
1242 | 1290 |
1243 UsePosition* last_use_before_split = NULL; | 1291 UsePosition* first_use_after_split = |
1244 UsePosition* use = uses_; | 1292 SplitListOfPositions(&uses_, split_pos, split_at_start); |
1245 if (split_at_start) { | |
1246 while ((use != NULL) && (use->pos() < split_pos)) { | |
1247 last_use_before_split = use; | |
1248 use = use->next(); | |
1249 } | |
1250 } else { | |
1251 while ((use != NULL) && (use->pos() <= split_pos)) { | |
1252 last_use_before_split = use; | |
1253 use = use->next(); | |
1254 } | |
1255 } | |
1256 UsePosition* first_use_after_split = use; | |
1257 | 1293 |
1258 if (last_use_before_split == NULL) { | 1294 SafepointPosition* first_safepoint_after_split = |
1259 uses_ = NULL; | 1295 SplitListOfPositions(&safepoints_, split_pos, split_at_start); |
1260 } else { | |
1261 last_use_before_split->set_next(NULL); | |
1262 } | |
1263 | 1296 |
1264 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ? | 1297 UseInterval* last_use_interval = (last_before_split == last_use_interval_) ? |
1265 first_after_split : last_use_interval_; | 1298 first_after_split : last_use_interval_; |
1266 next_sibling_ = new LiveRange(vreg(), | 1299 next_sibling_ = new LiveRange(vreg(), |
1267 first_use_after_split, | 1300 first_use_after_split, |
1268 first_after_split, | 1301 first_after_split, |
1269 last_use_interval, | 1302 last_use_interval, |
1303 first_safepoint_after_split, | |
1270 next_sibling_); | 1304 next_sibling_); |
1271 | 1305 |
1272 TRACE_ALLOC(OS::Print(" split sibling [%d, %d)\n", | 1306 TRACE_ALLOC(OS::Print(" split sibling [%d, %d)\n", |
1273 next_sibling_->Start(), next_sibling_->End())); | 1307 next_sibling_->Start(), next_sibling_->End())); |
1274 | 1308 |
1275 last_use_interval_ = last_before_split; | 1309 last_use_interval_ = last_before_split; |
1276 last_use_interval_->next_ = NULL; | 1310 last_use_interval_->next_ = NULL; |
1277 | 1311 |
1278 if (first_use_after_split != NULL) { | 1312 if (first_use_after_split != NULL) { |
1279 finger_.UpdateAfterSplit(first_use_after_split->pos()); | 1313 finger_.UpdateAfterSplit(first_use_after_split->pos()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1364 } | 1398 } |
1365 | 1399 |
1366 spill_slots_[idx] = last_sibling->End(); | 1400 spill_slots_[idx] = last_sibling->End(); |
1367 | 1401 |
1368 range->set_spill_slot(Location::StackSlot(idx)); | 1402 range->set_spill_slot(Location::StackSlot(idx)); |
1369 | 1403 |
1370 spilled_.Add(range); | 1404 spilled_.Add(range); |
1371 } | 1405 } |
1372 | 1406 |
1373 | 1407 |
1374 bool LiveRange::Contains(intptr_t pos) const { | |
1375 const LiveRange* current = this; | |
1376 while (current != NULL) { | |
1377 UseInterval* interval = current->first_use_interval_; | |
1378 while (interval != NULL) { | |
1379 if (interval->Contains(pos)) return true; | |
1380 interval = interval->next(); | |
1381 } | |
1382 current = current->next_sibling_; | |
1383 } | |
1384 return false; | |
1385 } | |
1386 | |
1387 | |
1388 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { | 1408 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { |
1389 intptr_t stack_index = range->spill_slot().stack_index(); | 1409 intptr_t stack_index = range->spill_slot().stack_index(); |
1390 ASSERT(stack_index >= 0); | 1410 ASSERT(stack_index >= 0); |
1391 for (intptr_t i = 0; i < safepoints_.length(); ++i) { | 1411 |
1392 if (range->Contains(safepoints_[i].position)) { | 1412 while (range != NULL) { |
1393 TRACE_ALLOC(OS::Print(" marking S[%d] in stack bitmap at %d\n", | 1413 for (SafepointPosition* safepoint = range->first_safepoint(); |
1394 stack_index, | 1414 safepoint != NULL; |
1395 safepoints_[i].position)); | 1415 safepoint = safepoint->next()) { |
1396 safepoints_[i].stack_bitmap->Set(stack_index, true); | 1416 safepoint->locs()->stack_bitmap()->Set(stack_index, true); |
1397 } | 1417 } |
1418 range = range->next_sibling(); | |
1398 } | 1419 } |
1399 } | 1420 } |
1400 | 1421 |
1401 | 1422 |
1402 void FlowGraphAllocator::Spill(LiveRange* range) { | 1423 void FlowGraphAllocator::Spill(LiveRange* range) { |
1403 LiveRange* parent = GetLiveRange(range->vreg()); | 1424 LiveRange* parent = GetLiveRange(range->vreg()); |
1404 if (parent->spill_slot().IsInvalid()) { | 1425 if (parent->spill_slot().IsInvalid()) { |
1405 AllocateSpillSlotFor(parent); | 1426 AllocateSpillSlotFor(parent); |
1406 MarkAsObjectAtSafepoints(parent); | 1427 MarkAsObjectAtSafepoints(parent); |
1407 } | 1428 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1696 if (range->vreg() == kNoVirtualRegister) return; | 1717 if (range->vreg() == kNoVirtualRegister) return; |
1697 TRACE_ALLOC(OS::Print("range [%d, %d) for v%d has been allocated to ", | 1718 TRACE_ALLOC(OS::Print("range [%d, %d) for v%d has been allocated to ", |
1698 range->Start(), range->End(), range->vreg())); | 1719 range->Start(), range->End(), range->vreg())); |
1699 TRACE_ALLOC(range->assigned_location().Print()); | 1720 TRACE_ALLOC(range->assigned_location().Print()); |
1700 TRACE_ALLOC(OS::Print(":\n")); | 1721 TRACE_ALLOC(OS::Print(":\n")); |
1701 ASSERT(!range->assigned_location().IsInvalid()); | 1722 ASSERT(!range->assigned_location().IsInvalid()); |
1702 const Location loc = range->assigned_location(); | 1723 const Location loc = range->assigned_location(); |
1703 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { | 1724 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { |
1704 ConvertUseTo(use, loc); | 1725 ConvertUseTo(use, loc); |
1705 } | 1726 } |
1727 | |
1728 if (range->assigned_location().IsRegister()) { | |
1729 Register reg = range->assigned_location().reg(); | |
1730 for (SafepointPosition* safepoint = range->first_safepoint(); | |
1731 safepoint != NULL; | |
1732 safepoint = safepoint->next()) { | |
1733 safepoint->locs()->live_registers()->Add(reg); | |
1734 } | |
1735 } | |
1706 } | 1736 } |
1707 | 1737 |
1708 | 1738 |
1709 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { | 1739 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { |
1710 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { | 1740 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { |
1711 if (cpu_regs_[reg].is_empty()) continue; | 1741 if (cpu_regs_[reg].is_empty()) continue; |
1712 | 1742 |
1713 intptr_t first_evicted = -1; | 1743 intptr_t first_evicted = -1; |
1714 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) { | 1744 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) { |
1715 LiveRange* range = cpu_regs_[reg][i]; | 1745 LiveRange* range = cpu_regs_[reg][i]; |
1716 if (range->finger()->Advance(start)) { | 1746 if (range->finger()->Advance(start)) { |
1717 ConvertAllUses(range); | 1747 ConvertAllUses(range); |
1718 cpu_regs_[reg][i] = NULL; | 1748 cpu_regs_[reg][i] = NULL; |
1719 first_evicted = i; | 1749 first_evicted = i; |
1720 } | 1750 } |
1721 } | 1751 } |
1722 | 1752 |
1723 if (first_evicted != -1) { | 1753 if (first_evicted != -1) { |
1724 RemoveEvicted(static_cast<Register>(reg), first_evicted); | 1754 RemoveEvicted(static_cast<Register>(reg), first_evicted); |
1725 } | 1755 } |
1726 } | 1756 } |
1727 } | 1757 } |
1728 | 1758 |
1729 | 1759 |
1730 static inline bool ShouldBeAllocatedBefore(LiveRange* a, LiveRange* b) { | 1760 static inline bool ShouldBeAllocatedBefore(LiveRange* a, LiveRange* b) { |
1731 return a->Start() <= b->Start(); | 1761 return a->Start() <= b->Start(); |
1732 } | 1762 } |
1733 | 1763 |
1734 | 1764 |
1765 bool LiveRange::Contains(intptr_t pos) const { | |
1766 if (!CanCover(pos)) return false; | |
1767 | |
1768 for (UseInterval* interval = first_use_interval_; | |
1769 interval != NULL; | |
1770 interval = interval->next()) { | |
1771 if (interval->Contains(pos)) { | |
1772 return true; | |
1773 } | |
1774 } | |
1775 | |
1776 return false; | |
1777 } | |
1778 | |
1779 | |
1780 void FlowGraphAllocator::AssignSafepoints(LiveRange* range) { | |
1781 for (intptr_t i = safepoints_.length() - 1; i >= 0; i--) { | |
1782 Instruction* instr = safepoints_[i]; | |
1783 | |
1784 const intptr_t pos = instr->lifetime_position(); | |
1785 if (range->End() <= pos) break; | |
1786 | |
1787 if (range->Contains(pos)) range->AddSafepoint(pos, instr->locs()); | |
1788 } | |
1789 } | |
1790 | |
1791 | |
1735 void FlowGraphAllocator::AddToUnallocated(LiveRange* range) { | 1792 void FlowGraphAllocator::AddToUnallocated(LiveRange* range) { |
1736 range->finger()->Initialize(range); | 1793 range->finger()->Initialize(range); |
1737 | 1794 |
1738 if (unallocated_.is_empty()) { | 1795 if (unallocated_.is_empty()) { |
1739 unallocated_.Add(range); | 1796 unallocated_.Add(range); |
1740 return; | 1797 return; |
1741 } | 1798 } |
1742 | 1799 |
1743 for (intptr_t i = unallocated_.length() - 1; i >= 0; i--) { | 1800 for (intptr_t i = unallocated_.length() - 1; i >= 0; i--) { |
1744 if (ShouldBeAllocatedBefore(range, unallocated_[i])) { | 1801 if (ShouldBeAllocatedBefore(range, unallocated_[i])) { |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1976 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2033 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
1977 function.ToFullyQualifiedCString()); | 2034 function.ToFullyQualifiedCString()); |
1978 FlowGraphPrinter printer(Function::Handle(), block_order_, true); | 2035 FlowGraphPrinter printer(Function::Handle(), block_order_, true); |
1979 printer.PrintBlocks(); | 2036 printer.PrintBlocks(); |
1980 OS::Print("----------------------------------------------\n"); | 2037 OS::Print("----------------------------------------------\n"); |
1981 } | 2038 } |
1982 } | 2039 } |
1983 | 2040 |
1984 | 2041 |
1985 } // namespace dart | 2042 } // namespace dart |
OLD | NEW |