Simplify JumpTarget::ComputeEntryFrame. Eliminate a separate pass

over the frame elements to find registers used (before allocating
undetermined elements) and another pass to set the frame's register
indices (after allocating all elements).
Review URL: http://codereview.chromium.org/114018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1906 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5fab2d08
......@@ -66,6 +66,14 @@ void RegisterAllocator::UnuseReserved(RegisterFile* register_file) {
}
bool RegisterAllocator::IsReserved(int reg_code) {
return (reg_code == sp.code())
|| (reg_code == fp.code())
|| (reg_code == cp.code())
|| (reg_code == pc.code());
}
void RegisterAllocator::Initialize() {
Reset();
// The following registers are live on function entry, saved in the
......
......@@ -97,6 +97,12 @@ void RegisterAllocator::UnuseReserved(RegisterFile* register_file) {
}
bool RegisterAllocator::IsReserved(int reg_code) {
// Test below relies on the order of register codes.
return reg_code >= esp.code() && reg_code <= esi.code();
}
void RegisterAllocator::Initialize() {
Reset();
// The following register is live on function entry, saved in the
......
......@@ -189,28 +189,37 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
}
}
// Compute the registers already reserved by values in the frame.
// Count the reserved registers to avoid using them.
RegisterFile frame_registers = RegisterAllocator::Reserved();
for (int i = 0; i < length; i++) {
FrameElement* element = elements[i];
if (element != NULL && element->is_register()) {
frame_registers.Use(element->reg());
// Build the new frame. A freshly allocated frame has memory elements
// for the parameters and some platform-dependent elements (e.g.,
// return address). Replace those first.
entry_frame_ = new VirtualFrame(cgen_);
int index = 0;
for (; index < entry_frame_->elements_.length(); index++) {
// If the element is determined, set it now and count registers.
// Undetermined elements are initially recorded as if in memory.
if (elements[index] != NULL) {
entry_frame_->elements_[index] = *elements[index];
if (elements[index]->is_register()) {
entry_frame_->register_locations_[elements[index]->reg().code()] =
index;
}
}
}
// Build the new frame. The frame already has memory elements for
// the parameters (including the receiver) and the return address.
// We will fill it up with memory elements.
entry_frame_ = new VirtualFrame(cgen_);
while (entry_frame_->elements_.length() < length) {
entry_frame_->elements_.Add(FrameElement::MemoryElement());
// Then fill in the rest of the frame with new elements.
for (; index < length; index++) {
if (elements[index] == NULL) {
entry_frame_->elements_.Add(FrameElement::MemoryElement());
} else {
entry_frame_->elements_.Add(*elements[index]);
if (elements[index]->is_register()) {
entry_frame_->register_locations_[elements[index]->reg().code()] =
index;
}
}
}
// Copy the already-determined frame elements to the entry frame,
// and allocate any still-undetermined frame elements to registers
// or memory, from the top down.
// Allocate any still-undetermined frame elements to registers or
// memory, from the top down.
for (int i = length - 1; i >= 0; i--) {
if (elements[i] == NULL) {
// If the value is synced on all frames, put it in memory. This
......@@ -234,7 +243,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
for (int j = 0; j < reaching_frames_.length(); j++) {
FrameElement element = reaching_frames_[j]->elements_[i];
if (element.is_register() &&
!frame_registers.is_used(element.reg())) {
!entry_frame_->is_used(element.reg())) {
candidate_registers.Use(element.reg());
if (candidate_registers.count(element.reg()) > max_count) {
max_count = candidate_registers.count(element.reg());
......@@ -245,7 +254,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// If there was no preferred choice consider any free register.
if (best_reg_code == no_reg.code_) {
for (int j = 0; j < kNumRegisters; j++) {
if (!frame_registers.is_used(j)) {
if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) {
best_reg_code = j;
break;
}
......@@ -256,27 +265,21 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// (the element is already recorded as in memory)
if (best_reg_code != no_reg.code_) {
Register reg = { best_reg_code };
frame_registers.Use(reg);
entry_frame_->elements_[i] =
FrameElement::RegisterElement(reg,
FrameElement::NOT_SYNCED);
entry_frame_->register_locations_[best_reg_code] = i;
}
} else {
// The element is already determined.
entry_frame_->elements_[i] = *elements[i];
}
}
// Set the copied flags in the frame to be exact. This assumes that
// the backing store of copies is always lower in the frame.
// Set the register locations to their index in the frame.
for (int i = 0; i < length; i++) {
FrameElement* current = &entry_frame_->elements_[i];
current->clear_copied();
if (current->is_copy()) {
entry_frame_->elements_[current->index()].set_copied();
} else if (current->is_register()) {
entry_frame_->register_locations_[current->reg().code()] = i;
}
if (direction_ == BIDIRECTIONAL && i >= high_water_mark) {
......
......@@ -275,6 +275,11 @@ class RegisterAllocator BASE_EMBEDDED {
// Unuse all the reserved registers in a register file.
static void UnuseReserved(RegisterFile* register_file);
// True if the register is reserved by the code generator, false if it
// can be freely used by the allocator.
static bool IsReserved(int reg_code);
static bool IsReserved(Register reg) { return IsReserved(reg); }
// Predicates and accessors for the registers' reference counts.
bool is_used(int reg_code) const { return registers_.is_used(reg_code); }
bool is_used(Register reg) const { return registers_.is_used(reg.code()); }
......
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