[turbofan] Greedy: faster compile time.

Avoiding unnecessarily traversing conflicts when doing weight
comparisons. This reduced compile time regressions from a few
multiples to under 10% - at least for zlib.

Review URL: https://codereview.chromium.org/1346263004

Cr-Commit-Position: refs/heads/master@{#30783}
This commit is contained in:
mtrofin 2015-09-16 20:53:43 -07:00 committed by Commit bot
parent 7a88581351
commit 1145090ad5
2 changed files with 13 additions and 8 deletions

View File

@ -338,12 +338,14 @@ void GreedyAllocator::TryAllocateLiveRange(LiveRange* range) {
int hinted_reg = -1; int hinted_reg = -1;
EnsureValidRangeWeight(range); EnsureValidRangeWeight(range);
DCHECK(range->weight() != LiveRange::kInvalidWeight); float competing_weight = range->weight();
DCHECK(competing_weight != LiveRange::kInvalidWeight);
// Can we allocate at the hinted register? // Can we allocate at the hinted register?
if (range->FirstHintPosition(&hinted_reg) != nullptr) { if (range->FirstHintPosition(&hinted_reg) != nullptr) {
DCHECK(hinted_reg >= 0); DCHECK(hinted_reg >= 0);
float max_conflict_weight = GetMaximumConflictingWeight(hinted_reg, range); float max_conflict_weight =
GetMaximumConflictingWeight(hinted_reg, range, competing_weight);
if (max_conflict_weight == LiveRange::kInvalidWeight) { if (max_conflict_weight == LiveRange::kInvalidWeight) {
free_reg = hinted_reg; free_reg = hinted_reg;
} else if (max_conflict_weight < range->weight()) { } else if (max_conflict_weight < range->weight()) {
@ -361,7 +363,8 @@ void GreedyAllocator::TryAllocateLiveRange(LiveRange* range) {
for (int i = 0; i < num_registers(); i++) { for (int i = 0; i < num_registers(); i++) {
// Skip unnecessarily re-visiting the hinted register, if any. // Skip unnecessarily re-visiting the hinted register, if any.
if (i == hinted_reg) continue; if (i == hinted_reg) continue;
float max_conflict_weight = GetMaximumConflictingWeight(i, range); float max_conflict_weight =
GetMaximumConflictingWeight(i, range, competing_weight);
if (max_conflict_weight == LiveRange::kInvalidWeight) { if (max_conflict_weight == LiveRange::kInvalidWeight) {
free_reg = i; free_reg = i;
break; break;
@ -482,15 +485,16 @@ void GreedyAllocator::AllocateRegisters() {
float GreedyAllocator::GetMaximumConflictingWeight( float GreedyAllocator::GetMaximumConflictingWeight(
unsigned reg_id, const LiveRange* range) const { unsigned reg_id, const LiveRange* range, float competing_weight) const {
float ret = LiveRange::kInvalidWeight; float ret = LiveRange::kInvalidWeight;
auto conflicts = current_allocations(reg_id)->GetConflicts(range); auto conflicts = current_allocations(reg_id)->GetConflicts(range);
for (LiveRange* conflict = conflicts.Current(); conflict != nullptr; for (LiveRange* conflict = conflicts.Current(); conflict != nullptr;
conflict = conflicts.GetNext()) { conflict = conflicts.GetNext()) {
DCHECK_NE(conflict->weight(), LiveRange::kInvalidWeight); DCHECK_NE(conflict->weight(), LiveRange::kInvalidWeight);
if (competing_weight <= conflict->weight()) return LiveRange::kMaxWeight;
ret = Max(ret, conflict->weight()); ret = Max(ret, conflict->weight());
if (ret == LiveRange::kMaxWeight) return ret; DCHECK(ret < LiveRange::kMaxWeight);
} }
return ret; return ret;
@ -503,7 +507,8 @@ float GreedyAllocator::GetMaximumConflictingWeight(unsigned reg_id,
float ret = LiveRange::kInvalidWeight; float ret = LiveRange::kInvalidWeight;
for (LiveRange* member : group->ranges()) { for (LiveRange* member : group->ranges()) {
float member_conflict_weight = GetMaximumConflictingWeight(reg_id, member); float member_conflict_weight =
GetMaximumConflictingWeight(reg_id, member, group_weight);
if (member_conflict_weight == LiveRange::kMaxWeight) { if (member_conflict_weight == LiveRange::kMaxWeight) {
return LiveRange::kMaxWeight; return LiveRange::kMaxWeight;
} }

View File

@ -148,8 +148,8 @@ class GreedyAllocator final : public RegisterAllocator {
// Returns kInvalidWeight if there are no conflicts, or the largest weight of // Returns kInvalidWeight if there are no conflicts, or the largest weight of
// a range conflicting with the given range, at the given register. // a range conflicting with the given range, at the given register.
float GetMaximumConflictingWeight(unsigned reg_id, float GetMaximumConflictingWeight(unsigned reg_id, const LiveRange* range,
const LiveRange* range) const; float competing_weight) const;
// Returns kInvalidWeight if there are no conflicts, or the largest weight of // Returns kInvalidWeight if there are no conflicts, or the largest weight of
// a range conflicting with the given range, at the given register. // a range conflicting with the given range, at the given register.