OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/greedy-allocator.h" | 5 #include "src/compiler/greedy-allocator.h" |
6 #include "src/compiler/register-allocator.h" | 6 #include "src/compiler/register-allocator.h" |
7 | 7 |
8 namespace v8 { | 8 namespace v8 { |
9 namespace internal { | 9 namespace internal { |
10 namespace compiler { | 10 namespace compiler { |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 void GreedyAllocator::TryAllocateLiveRange(LiveRange* range) { | 331 void GreedyAllocator::TryAllocateLiveRange(LiveRange* range) { |
332 // TODO(mtrofin): once we introduce groups, we'll want to first try and | 332 // TODO(mtrofin): once we introduce groups, we'll want to first try and |
333 // allocate at the preferred register. | 333 // allocate at the preferred register. |
334 TRACE("Attempting to allocate live range %d:%d.\n", range->TopLevel()->vreg(), | 334 TRACE("Attempting to allocate live range %d:%d.\n", range->TopLevel()->vreg(), |
335 range->relative_id()); | 335 range->relative_id()); |
336 int free_reg = -1; | 336 int free_reg = -1; |
337 int evictable_reg = -1; | 337 int evictable_reg = -1; |
338 int hinted_reg = -1; | 338 int hinted_reg = -1; |
339 | 339 |
340 EnsureValidRangeWeight(range); | 340 EnsureValidRangeWeight(range); |
341 DCHECK(range->weight() != LiveRange::kInvalidWeight); | 341 float competing_weight = range->weight(); |
| 342 DCHECK(competing_weight != LiveRange::kInvalidWeight); |
342 | 343 |
343 // Can we allocate at the hinted register? | 344 // Can we allocate at the hinted register? |
344 if (range->FirstHintPosition(&hinted_reg) != nullptr) { | 345 if (range->FirstHintPosition(&hinted_reg) != nullptr) { |
345 DCHECK(hinted_reg >= 0); | 346 DCHECK(hinted_reg >= 0); |
346 float max_conflict_weight = GetMaximumConflictingWeight(hinted_reg, range); | 347 float max_conflict_weight = |
| 348 GetMaximumConflictingWeight(hinted_reg, range, competing_weight); |
347 if (max_conflict_weight == LiveRange::kInvalidWeight) { | 349 if (max_conflict_weight == LiveRange::kInvalidWeight) { |
348 free_reg = hinted_reg; | 350 free_reg = hinted_reg; |
349 } else if (max_conflict_weight < range->weight()) { | 351 } else if (max_conflict_weight < range->weight()) { |
350 evictable_reg = hinted_reg; | 352 evictable_reg = hinted_reg; |
351 } | 353 } |
352 } | 354 } |
353 | 355 |
354 if (free_reg < 0 && evictable_reg < 0) { | 356 if (free_reg < 0 && evictable_reg < 0) { |
355 // There was no hinted reg, or we cannot allocate there. | 357 // There was no hinted reg, or we cannot allocate there. |
356 float smallest_weight = LiveRange::kMaxWeight; | 358 float smallest_weight = LiveRange::kMaxWeight; |
357 | 359 |
358 // Seek either the first free register, or, from the set of registers | 360 // Seek either the first free register, or, from the set of registers |
359 // where the maximum conflict is lower than the candidate's weight, the one | 361 // where the maximum conflict is lower than the candidate's weight, the one |
360 // with the smallest such weight. | 362 // with the smallest such weight. |
361 for (int i = 0; i < num_registers(); i++) { | 363 for (int i = 0; i < num_registers(); i++) { |
362 // Skip unnecessarily re-visiting the hinted register, if any. | 364 // Skip unnecessarily re-visiting the hinted register, if any. |
363 if (i == hinted_reg) continue; | 365 if (i == hinted_reg) continue; |
364 float max_conflict_weight = GetMaximumConflictingWeight(i, range); | 366 float max_conflict_weight = |
| 367 GetMaximumConflictingWeight(i, range, competing_weight); |
365 if (max_conflict_weight == LiveRange::kInvalidWeight) { | 368 if (max_conflict_weight == LiveRange::kInvalidWeight) { |
366 free_reg = i; | 369 free_reg = i; |
367 break; | 370 break; |
368 } | 371 } |
369 if (max_conflict_weight < range->weight() && | 372 if (max_conflict_weight < range->weight() && |
370 max_conflict_weight < smallest_weight) { | 373 max_conflict_weight < smallest_weight) { |
371 smallest_weight = max_conflict_weight; | 374 smallest_weight = max_conflict_weight; |
372 evictable_reg = i; | 375 evictable_reg = i; |
373 } | 376 } |
374 } | 377 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 } | 478 } |
476 } | 479 } |
477 allocations_.clear(); | 480 allocations_.clear(); |
478 | 481 |
479 TRACE("End allocating function %s with the Greedy Allocator\n", | 482 TRACE("End allocating function %s with the Greedy Allocator\n", |
480 data()->debug_name()); | 483 data()->debug_name()); |
481 } | 484 } |
482 | 485 |
483 | 486 |
484 float GreedyAllocator::GetMaximumConflictingWeight( | 487 float GreedyAllocator::GetMaximumConflictingWeight( |
485 unsigned reg_id, const LiveRange* range) const { | 488 unsigned reg_id, const LiveRange* range, float competing_weight) const { |
486 float ret = LiveRange::kInvalidWeight; | 489 float ret = LiveRange::kInvalidWeight; |
487 | 490 |
488 auto conflicts = current_allocations(reg_id)->GetConflicts(range); | 491 auto conflicts = current_allocations(reg_id)->GetConflicts(range); |
489 for (LiveRange* conflict = conflicts.Current(); conflict != nullptr; | 492 for (LiveRange* conflict = conflicts.Current(); conflict != nullptr; |
490 conflict = conflicts.GetNext()) { | 493 conflict = conflicts.GetNext()) { |
491 DCHECK_NE(conflict->weight(), LiveRange::kInvalidWeight); | 494 DCHECK_NE(conflict->weight(), LiveRange::kInvalidWeight); |
| 495 if (competing_weight <= conflict->weight()) return LiveRange::kMaxWeight; |
492 ret = Max(ret, conflict->weight()); | 496 ret = Max(ret, conflict->weight()); |
493 if (ret == LiveRange::kMaxWeight) return ret; | 497 DCHECK(ret < LiveRange::kMaxWeight); |
494 } | 498 } |
495 | 499 |
496 return ret; | 500 return ret; |
497 } | 501 } |
498 | 502 |
499 | 503 |
500 float GreedyAllocator::GetMaximumConflictingWeight(unsigned reg_id, | 504 float GreedyAllocator::GetMaximumConflictingWeight(unsigned reg_id, |
501 const LiveRangeGroup* group, | 505 const LiveRangeGroup* group, |
502 float group_weight) const { | 506 float group_weight) const { |
503 float ret = LiveRange::kInvalidWeight; | 507 float ret = LiveRange::kInvalidWeight; |
504 | 508 |
505 for (LiveRange* member : group->ranges()) { | 509 for (LiveRange* member : group->ranges()) { |
506 float member_conflict_weight = GetMaximumConflictingWeight(reg_id, member); | 510 float member_conflict_weight = |
| 511 GetMaximumConflictingWeight(reg_id, member, group_weight); |
507 if (member_conflict_weight == LiveRange::kMaxWeight) { | 512 if (member_conflict_weight == LiveRange::kMaxWeight) { |
508 return LiveRange::kMaxWeight; | 513 return LiveRange::kMaxWeight; |
509 } | 514 } |
510 if (member_conflict_weight > group_weight) return LiveRange::kMaxWeight; | 515 if (member_conflict_weight > group_weight) return LiveRange::kMaxWeight; |
511 ret = Max(member_conflict_weight, ret); | 516 ret = Max(member_conflict_weight, ret); |
512 } | 517 } |
513 | 518 |
514 return ret; | 519 return ret; |
515 } | 520 } |
516 | 521 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 scheduler().Schedule(range); | 664 scheduler().Schedule(range); |
660 return; | 665 return; |
661 } | 666 } |
662 SpillRangeAsLastResort(range); | 667 SpillRangeAsLastResort(range); |
663 } | 668 } |
664 | 669 |
665 | 670 |
666 } // namespace compiler | 671 } // namespace compiler |
667 } // namespace internal | 672 } // namespace internal |
668 } // namespace v8 | 673 } // namespace v8 |
OLD | NEW |