Commit 36853c83 authored by whesse@chromium.org's avatar whesse@chromium.org

Remove register counts from VirtualFrame, use register indices instead.

Review URL: http://codereview.chromium.org/42565

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1605 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 68d9782c
...@@ -5163,11 +5163,11 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -5163,11 +5163,11 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
#ifdef DEBUG #ifdef DEBUG
bool CodeGenerator::HasValidEntryRegisters() { bool CodeGenerator::HasValidEntryRegisters() {
return (allocator()->count(eax) == frame()->register_count(eax)) return (allocator()->count(eax) == (frame()->is_used(eax) ? 1 : 0))
&& (allocator()->count(ebx) == frame()->register_count(ebx)) && (allocator()->count(ebx) == (frame()->is_used(ebx) ? 1 : 0))
&& (allocator()->count(ecx) == frame()->register_count(ecx)) && (allocator()->count(ecx) == (frame()->is_used(ecx) ? 1 : 0))
&& (allocator()->count(edx) == frame()->register_count(edx)) && (allocator()->count(edx) == (frame()->is_used(edx) ? 1 : 0))
&& (allocator()->count(edi) == frame()->register_count(edi)); && (allocator()->count(edi) == (frame()->is_used(edi) ? 1 : 0));
} }
#endif #endif
......
...@@ -272,14 +272,13 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -272,14 +272,13 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// Set the copied flags in the frame to be exact. This assumes that // Set the copied flags in the frame to be exact. This assumes that
// the backing store of copies is always lower in the frame. // the backing store of copies is always lower in the frame.
// Set the register counts and indices. // Set the register locations to their index in the frame.
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
FrameElement current = entry_frame_->elements_[i]; FrameElement current = entry_frame_->elements_[i];
entry_frame_->elements_[i].clear_copied(); entry_frame_->elements_[i].clear_copied();
if (current.is_copy()) { if (current.is_copy()) {
entry_frame_->elements_[current.index()].set_copied(); entry_frame_->elements_[current.index()].set_copied();
} else if (current.is_register()) { } else if (current.is_register()) {
entry_frame_->frame_registers_.Use(current.reg());
entry_frame_->register_locations_[current.reg().code()] = i; entry_frame_->register_locations_[current.reg().code()] = i;
} }
} }
......
...@@ -107,7 +107,7 @@ Result RegisterAllocator::Allocate(Register target) { ...@@ -107,7 +107,7 @@ Result RegisterAllocator::Allocate(Register target) {
// If the target is only referenced in the frame, it can be spilled and // If the target is only referenced in the frame, it can be spilled and
// then allocated. // then allocated.
ASSERT(cgen_->has_valid_frame()); ASSERT(cgen_->has_valid_frame());
if (count(target) == cgen_->frame()->register_count(target)) { if (cgen_->frame()->is_used(target) && count(target) == 1) {
cgen_->frame()->Spill(target); cgen_->frame()->Spill(target);
ASSERT(!is_used(target)); ASSERT(!is_used(target));
return Result(target, cgen_); return Result(target, cgen_);
......
...@@ -76,8 +76,16 @@ class VirtualFrame : public Malloced { ...@@ -76,8 +76,16 @@ class VirtualFrame : public Malloced {
return elements_.length() - expression_base_index(); return elements_.length() - expression_base_index();
} }
int register_count(Register reg) { int register_index(Register reg) {
return frame_registers_.count(reg); return register_locations_[reg.code()];
}
bool is_used(int reg_code) {
return register_locations_[reg_code] != kIllegalIndex;
}
bool is_used(Register reg) {
return is_used(reg.code()) != kIllegalIndex;
} }
// Add extra in-memory elements to the top of the frame to match an actual // Add extra in-memory elements to the top of the frame to match an actual
...@@ -342,10 +350,6 @@ class VirtualFrame : public Malloced { ...@@ -342,10 +350,6 @@ class VirtualFrame : public Malloced {
// kIllegalIndex if a register is not on the frame. // kIllegalIndex if a register is not on the frame.
int register_locations_[kNumRegisters]; int register_locations_[kNumRegisters];
// The frame has an embedded register file that it uses to track registers
// used in the frame.
RegisterFile frame_registers_;
// The index of the first parameter. The receiver lies below the first // The index of the first parameter. The receiver lies below the first
// parameter. // parameter.
int param0_index() const { return 1; } int param0_index() const { return 1; }
......
...@@ -308,7 +308,7 @@ void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { ...@@ -308,7 +308,7 @@ void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
elements_[i] = target; elements_[i] = target;
} else { } else {
// We need to move source to target. // We need to move source to target.
if (frame_registers_.is_used(target.reg())) { if (is_used(target.reg())) {
// The move is blocked because the target contains valid data. // The move is blocked because the target contains valid data.
// If we are stuck with only cycles remaining, then we spill source. // If we are stuck with only cycles remaining, then we spill source.
// Otherwise, we just need more iterations. // Otherwise, we just need more iterations.
......
...@@ -76,8 +76,16 @@ class VirtualFrame : public Malloced { ...@@ -76,8 +76,16 @@ class VirtualFrame : public Malloced {
return elements_.length() - expression_base_index(); return elements_.length() - expression_base_index();
} }
int register_count(Register reg) { int register_index(Register reg) {
return frame_registers_.count(reg); return register_locations_[reg.code()];
}
bool is_used(int reg_code) {
return register_locations_[reg_code] != kIllegalIndex;
}
bool is_used(Register reg) {
return is_used(reg.code());
} }
// Add extra in-memory elements to the top of the frame to match an actual // Add extra in-memory elements to the top of the frame to match an actual
...@@ -333,10 +341,6 @@ class VirtualFrame : public Malloced { ...@@ -333,10 +341,6 @@ class VirtualFrame : public Malloced {
// (the ebp register). // (the ebp register).
int frame_pointer_; int frame_pointer_;
// The frame has an embedded register file that it uses to track registers
// used in the frame.
RegisterFile frame_registers_;
// The index of the register frame element using each register, or // The index of the register frame element using each register, or
// kIllegalIndex if a register is not on the frame. // kIllegalIndex if a register is not on the frame.
int register_locations_[kNumRegisters]; int register_locations_[kNumRegisters];
......
...@@ -57,8 +57,7 @@ VirtualFrame::VirtualFrame(VirtualFrame* original) ...@@ -57,8 +57,7 @@ VirtualFrame::VirtualFrame(VirtualFrame* original)
parameter_count_(original->parameter_count_), parameter_count_(original->parameter_count_),
local_count_(original->local_count_), local_count_(original->local_count_),
stack_pointer_(original->stack_pointer_), stack_pointer_(original->stack_pointer_),
frame_pointer_(original->frame_pointer_), frame_pointer_(original->frame_pointer_) {
frame_registers_(original->frame_registers_) {
// Copy all the elements from the original. // Copy all the elements from the original.
for (int i = 0; i < original->elements_.length(); i++) { for (int i = 0; i < original->elements_.length(); i++) {
elements_.Add(original->elements_[i]); elements_.Add(original->elements_[i]);
...@@ -152,7 +151,6 @@ void VirtualFrame::ForgetElements(int count) { ...@@ -152,7 +151,6 @@ void VirtualFrame::ForgetElements(int count) {
if (cgen_->frame() == this) { if (cgen_->frame() == this) {
Unuse(last.reg()); Unuse(last.reg());
} else { } else {
frame_registers_.Unuse(last.reg());
register_locations_[last.reg().code()] = kIllegalIndex; register_locations_[last.reg().code()] = kIllegalIndex;
} }
} }
...@@ -161,29 +159,22 @@ void VirtualFrame::ForgetElements(int count) { ...@@ -161,29 +159,22 @@ void VirtualFrame::ForgetElements(int count) {
void VirtualFrame::Use(Register reg, int index) { void VirtualFrame::Use(Register reg, int index) {
ASSERT(frame_registers_.count(reg) == 0);
ASSERT(register_locations_[reg.code()] == kIllegalIndex); ASSERT(register_locations_[reg.code()] == kIllegalIndex);
register_locations_[reg.code()] = index; register_locations_[reg.code()] = index;
frame_registers_.Use(reg);
cgen_->allocator()->Use(reg); cgen_->allocator()->Use(reg);
} }
void VirtualFrame::Unuse(Register reg) { void VirtualFrame::Unuse(Register reg) {
ASSERT(frame_registers_.count(reg) == 1);
ASSERT(register_locations_[reg.code()] != kIllegalIndex); ASSERT(register_locations_[reg.code()] != kIllegalIndex);
register_locations_[reg.code()] = kIllegalIndex; register_locations_[reg.code()] = kIllegalIndex;
frame_registers_.Unuse(reg);
cgen_->allocator()->Unuse(reg); cgen_->allocator()->Unuse(reg);
} }
void VirtualFrame::Spill(Register target) { void VirtualFrame::Spill(Register target) {
if (!frame_registers_.is_used(target)) return; if (is_used(target)) {
for (int i = 0; i < elements_.length(); i++) { SpillElementAt(register_index(target));
if (elements_[i].is_register() && elements_[i].reg().is(target)) {
SpillElementAt(i);
}
} }
} }
...@@ -194,23 +185,15 @@ Register VirtualFrame::SpillAnyRegister() { ...@@ -194,23 +185,15 @@ Register VirtualFrame::SpillAnyRegister() {
// internally-referenced register whose internal reference count matches // internally-referenced register whose internal reference count matches
// its external reference count (so that spilling it from the frame frees // its external reference count (so that spilling it from the frame frees
// it for use). // it for use).
int min_count = kMaxInt;
int best_register_code = no_reg.code_;
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
int count = frame_registers_.count(i); if (is_used(i) && cgen_->allocator()->count(i) == 1) {
if (count < min_count && count == cgen_->allocator()->count(i)) { Register result = { i };
min_count = count; Spill(result);
best_register_code = i; ASSERT(!cgen_->allocator()->is_used(result));
return result;
} }
} }
return no_reg;
Register result = { best_register_code };
if (result.is_valid()) {
Spill(result);
ASSERT(!cgen_->allocator()->is_used(result));
}
return result;
} }
...@@ -279,7 +262,6 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) { ...@@ -279,7 +262,6 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
if (cgen_->frame() == this) { if (cgen_->frame() == this) {
Unuse(source.reg()); Unuse(source.reg());
} else { } else {
frame_registers_.Unuse(source.reg());
register_locations_[source.reg().code()] = kIllegalIndex; register_locations_[source.reg().code()] = kIllegalIndex;
} }
} }
...@@ -390,24 +372,13 @@ void VirtualFrame::SetElementAt(int index, Result* value) { ...@@ -390,24 +372,13 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
FrameElement new_element; FrameElement new_element;
if (value->is_register()) { if (value->is_register()) {
// There are two cases depending no whether the register already if (is_used(value->reg())) {
// occurs in the frame or not. // The register already appears on the frame. Either the existing
if (register_count(value->reg()) == 0) { // register element, or the new element at frame_index, must be made
Use(value->reg(), frame_index); // a copy.
elements_[frame_index] = int i = register_index(value->reg());
FrameElement::RegisterElement(value->reg(),
FrameElement::NOT_SYNCED);
} else {
int i = 0;
for (; i < elements_.length(); i++) {
if (elements_[i].is_register() && elements_[i].reg().is(value->reg())) {
break;
}
}
ASSERT(i < elements_.length());
if (i < frame_index) { if (i < frame_index) {
// The register backing store is lower in the frame than its copy. // The register FrameElement is lower in the frame than the new copy.
elements_[frame_index] = CopyElementAt(i); elements_[frame_index] = CopyElementAt(i);
} else { } else {
// There was an early bailout for the case of setting a // There was an early bailout for the case of setting a
...@@ -426,6 +397,12 @@ void VirtualFrame::SetElementAt(int index, Result* value) { ...@@ -426,6 +397,12 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
} }
} }
} }
} else {
// The register value->reg() was not already used on the frame.
Use(value->reg(), frame_index);
elements_[frame_index] =
FrameElement::RegisterElement(value->reg(),
FrameElement::NOT_SYNCED);
} }
} else { } else {
ASSERT(value->is_constant()); ASSERT(value->is_constant());
...@@ -497,21 +474,12 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code, ...@@ -497,21 +474,12 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code,
void VirtualFrame::Push(Register reg) { void VirtualFrame::Push(Register reg) {
FrameElement new_element; if (is_used(reg)) {
if (register_count(reg) == 0) { elements_.Add(CopyElementAt(register_index(reg)));
Use(reg, elements_.length());
new_element =
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED);
} else { } else {
for (int i = 0; i < elements_.length(); i++) { Use(reg, elements_.length());
FrameElement element = elements_[i]; elements_.Add(FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED));
if (element.is_register() && element.reg().is(reg)) {
new_element = CopyElementAt(i);
break;
}
}
} }
elements_.Add(new_element);
} }
...@@ -569,9 +537,6 @@ bool VirtualFrame::Equals(VirtualFrame* other) { ...@@ -569,9 +537,6 @@ bool VirtualFrame::Equals(VirtualFrame* other) {
if (frame_pointer_ != other->frame_pointer_) return false; if (frame_pointer_ != other->frame_pointer_) return false;
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (frame_registers_.count(i) != other->frame_registers_.count(i)) {
return false;
}
if (register_locations_[i] != other->register_locations_[i]) { if (register_locations_[i] != other->register_locations_[i]) {
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment