fix two bugs concerning tracking available registers and reserving them when necessary

This commit is contained in:
Joel Dice 2009-02-08 16:20:28 -07:00
parent 0fbe89c147
commit 4ca45ffa41

View File

@ -28,6 +28,9 @@ const bool DebugBuddies = false;
const int AnyFrameIndex = -2; const int AnyFrameIndex = -2;
const int NoFrameIndex = -1; const int NoFrameIndex = -1;
const unsigned StealRegisterReserveCount = 1;
const unsigned ResolveRegisterReserveCount = 2;
class Context; class Context;
class Value; class Value;
class Stack; class Stack;
@ -943,7 +946,28 @@ buddies(Value* a, Value* b)
} }
void void
increment(Context* c, Resource* r) decrementAvailableRegisterCount(Context* c)
{
assert(c, c->availableRegisterCount);
-- c->availableRegisterCount;
if (DebugResources) {
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
}
}
void
incrementAvailableRegisterCount(Context* c)
{
++ c->availableRegisterCount;
if (DebugResources) {
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
}
}
void
increment(Context* c, RegisterResource* r)
{ {
if (not r->reserved) { if (not r->reserved) {
if (DebugResources) { if (DebugResources) {
@ -952,6 +976,10 @@ increment(Context* c, Resource* r)
} }
++ r->referenceCount; ++ r->referenceCount;
if (r->referenceCount == 1) {
decrementAvailableRegisterCount(c);
}
} }
} }
@ -967,6 +995,10 @@ decrement(Context* c, Resource* r)
assert(c, r->referenceCount > 0); assert(c, r->referenceCount > 0);
-- r->referenceCount; -- r->referenceCount;
if (r->referenceCount == 0) {
incrementAvailableRegisterCount(c);
}
} }
} }
@ -990,12 +1022,7 @@ RegisterResource::freeze(Context* c, Value* v)
freezeResource(c, this, v); freezeResource(c, this, v);
if (freezeCount == 1) { if (freezeCount == 1) {
assert(c, c->availableRegisterCount); decrementAvailableRegisterCount(c);
-- c->availableRegisterCount;
if (DebugResources) {
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
}
} }
} }
} }
@ -1029,11 +1056,7 @@ RegisterResource::thaw(Context* c, Value* v)
thawResource(c, this, v); thawResource(c, this, v);
if (freezeCount == 0) { if (freezeCount == 0) {
++ c->availableRegisterCount; incrementAvailableRegisterCount(c);
if (DebugResources) {
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
}
} }
} }
} }
@ -1062,7 +1085,7 @@ class Target {
Target Target
pickTarget(Context* c, Read* r, bool intersectRead, pickTarget(Context* c, Read* r, bool intersectRead,
unsigned reserveRegisterCount); unsigned registerReserveCount);
unsigned unsigned
resourceCost(Context* c UNUSED, Value* v, Resource* r) resourceCost(Context* c UNUSED, Value* v, Resource* r)
@ -1144,12 +1167,12 @@ pickFrameTarget(Context* c, Value* v)
Target Target
pickTarget(Context* c, Read* read, bool intersectRead, pickTarget(Context* c, Read* read, bool intersectRead,
unsigned reserveRegisterCount) unsigned registerReserveCount)
{ {
SiteMask mask; SiteMask mask;
read->intersect(&mask); read->intersect(&mask);
unsigned registerPenalty = (c->availableRegisterCount > reserveRegisterCount unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
? 0 : Target::Penalty); ? 0 : Target::Penalty);
Target best; Target best;
@ -1732,9 +1755,9 @@ sitesToString(Context* c, Value* v, char* buffer, unsigned size)
Site* Site*
pickTargetSite(Context* c, Read* read, bool intersectRead = false, pickTargetSite(Context* c, Read* read, bool intersectRead = false,
unsigned reserveRegisterCount = 0) unsigned registerReserveCount = 0)
{ {
Target target(pickTarget(c, read, intersectRead, reserveRegisterCount)); Target target(pickTarget(c, read, intersectRead, registerReserveCount));
expect(c, target.cost < Target::Impossible); expect(c, target.cost < Target::Impossible);
if (target.type == MemoryOperand) { if (target.type == MemoryOperand) {
return frameSite(c, target.index); return frameSite(c, target.index);
@ -1758,7 +1781,8 @@ steal(Context* c, Resource* r, Value* thief)
{ {
r->site->freeze(c, r->value); r->site->freeze(c, r->value);
move(c, r->value, r->site, pickTargetSite(c, live(r->value), false, 1)); move(c, r->value, r->site, pickTargetSite
(c, live(r->value), false, StealRegisterReserveCount));
r->site->thaw(c, r->value); r->site->thaw(c, r->value);
} }
@ -3656,7 +3680,7 @@ acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask)
{ {
if (acceptMatch(c, s, read, mask) and (not s->frozen(c))) { if (acceptMatch(c, s, read, mask) and (not s->frozen(c))) {
if (s->type(c) == RegisterOperand) { if (s->type(c) == RegisterOperand) {
return c->availableRegisterCount > 1; return c->availableRegisterCount > ResolveRegisterReserveCount;
} else { } else {
assert(c, s->match(c, SiteMask(1 << MemoryOperand, 0, AnyFrameIndex))); assert(c, s->match(c, SiteMask(1 << MemoryOperand, 0, AnyFrameIndex)));
@ -3909,7 +3933,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (s == 0) { if (s == 0) {
s = pickSourceSite(c, r, 0, 0, mask, false, true, acceptForResolve); s = pickSourceSite(c, r, 0, 0, mask, false, true, acceptForResolve);
if (s == 0) { if (s == 0) {
s = pickTargetSite(c, r, false, 2); s = pickTargetSite(c, r, false, ResolveRegisterReserveCount);
useTarget = true; useTarget = true;
} }
} }