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