mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
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:
parent
7ba14e5806
commit
36d5f35367
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user