Bug 1385165 - Calculate spill weight of a range's uses when add to or remove from it. r=bhackett

Iterating a LiveRange's uses in BacktrackingAllocator::computeSpillWeight() to
access UsePosition.uses_ isn't cache friendly, because it is a linked list and
each node is allocated separately. Changing the data strcture to a vector is
worse because of the overhead from frequent insertion/removing. However,
UsePostion.uses_ can't be changed after initialization, so we can pre-calculate
the spill weight when it is added to or remove from a LiveRange.

MozReview-Commit-ID: BJEvI7KBVAJ

--HG--
extra : rebase_source : 04a14fae5a455d0e70f995e80887eb09b184dc2c
This commit is contained in:
Ting-Yu Chou 2017-08-14 15:24:58 +08:00
parent 7ba14e5806
commit 36d5f35367
2 changed files with 70 additions and 25 deletions

View File

@ -71,11 +71,39 @@ InsertSortedList(InlineForwardList<T> &list, T* value)
// LiveRange
/////////////////////////////////////////////////////////////////////
inline void
LiveRange::noteAddedUse(UsePosition* use)
{
LUse::Policy policy = use->usePolicy();
usesSpillWeight_ += BacktrackingAllocator::SpillWeightFromUsePolicy(policy);
if (policy == LUse::FIXED)
++numFixedUses_;
}
inline void
LiveRange::noteRemovedUse(UsePosition* use)
{
LUse::Policy policy = use->usePolicy();
usesSpillWeight_ -= BacktrackingAllocator::SpillWeightFromUsePolicy(policy);
if (policy == LUse::FIXED)
--numFixedUses_;
MOZ_ASSERT_IF(!hasUses(), !usesSpillWeight_ && !numFixedUses_);
}
void
LiveRange::addUse(UsePosition* use)
{
MOZ_ASSERT(covers(use->pos));
InsertSortedList(uses_, use);
noteAddedUse(use);
}
UsePosition*
LiveRange::popUse()
{
UsePosition* ret = uses_.popFront();
noteRemovedUse(ret);
return ret;
}
void
@ -89,6 +117,7 @@ LiveRange::distributeUses(LiveRange* other)
UsePosition* use = *iter;
if (other->covers(use->pos)) {
uses_.removeAndIncrement(iter);
noteRemovedUse(use);
other->addUse(use);
} else {
iter++;
@ -2546,27 +2575,9 @@ BacktrackingAllocator::computeSpillWeight(LiveBundle* bundle)
}
}
for (UsePositionIterator iter = range->usesBegin(); iter; iter++) {
switch (iter->usePolicy()) {
case LUse::ANY:
usesTotal += 1000;
break;
case LUse::FIXED:
fixed = true;
MOZ_FALLTHROUGH;
case LUse::REGISTER:
usesTotal += 2000;
break;
case LUse::KEEPALIVE:
break;
default:
// Note: RECOVERED_INPUT will not appear in UsePositionIterator.
MOZ_CRASH("Bad use");
}
}
usesTotal += range->usesSpillWeight();
if (range->numFixedUses() > 0)
fixed = true;
}
// Bundles with fixed uses are given a higher spill weight, since they must

View File

@ -259,15 +259,30 @@ class LiveRange : public TempObject
// All uses of the virtual register in this range, ordered by location.
InlineForwardList<UsePosition> uses_;
// Total spill weight that calculate from all the uses' policy. Because the
// use's policy can't be changed after initialization, we can update the
// weight whenever a use is added to or remove from this range. This way, we
// don't need to iterate all the uses every time computeSpillWeight() is
// called.
size_t usesSpillWeight_;
// Number of uses that have policy LUse::FIXED.
uint32_t numFixedUses_;
// Whether this range contains the virtual register's definition.
bool hasDefinition_;
LiveRange(uint32_t vreg, Range range)
: vreg_(vreg), bundle_(nullptr), range_(range), hasDefinition_(false)
: vreg_(vreg), bundle_(nullptr), range_(range), usesSpillWeight_(0),
numFixedUses_(0), hasDefinition_(false)
{
MOZ_ASSERT(!range.empty());
}
void noteAddedUse(UsePosition* use);
void noteRemovedUse(UsePosition* use);
public:
static LiveRange* FallibleNew(TempAllocator& alloc, uint32_t vreg,
CodePosition from, CodePosition to)
@ -316,9 +331,7 @@ class LiveRange : public TempObject
bool hasUses() const {
return !!usesBegin();
}
UsePosition* popUse() {
return uses_.popFront();
}
UsePosition* popUse();
bool hasDefinition() const {
return hasDefinition_;
@ -345,6 +358,13 @@ class LiveRange : public TempObject
hasDefinition_ = true;
}
size_t usesSpillWeight() {
return usesSpillWeight_;
}
uint32_t numFixedUses() {
return numFixedUses_;
}
#ifdef JS_JITSPEW
// Return a string describing this range.
UniqueChars toString() const;
@ -684,6 +704,20 @@ class BacktrackingAllocator : protected RegisterAllocator
MOZ_MUST_USE bool go();
static size_t SpillWeightFromUsePolicy(LUse::Policy policy) {
switch (policy) {
case LUse::ANY:
return 1000;
case LUse::REGISTER:
case LUse::FIXED:
return 2000;
default:
return 0;
}
}
private:
typedef Vector<LiveRange*, 4, SystemAllocPolicy> LiveRangeVector;