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) { ...@@ -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() { void RegisterAllocator::Initialize() {
Reset(); Reset();
// The following registers are live on function entry, saved in the // The following registers are live on function entry, saved in the
......
...@@ -97,6 +97,12 @@ void RegisterAllocator::UnuseReserved(RegisterFile* register_file) { ...@@ -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() { void RegisterAllocator::Initialize() {
Reset(); Reset();
// The following register is live on function entry, saved in the // The following register is live on function entry, saved in the
......
...@@ -189,28 +189,37 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -189,28 +189,37 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
} }
} }
// Compute the registers already reserved by values in the frame. // Build the new frame. A freshly allocated frame has memory elements
// Count the reserved registers to avoid using them. // for the parameters and some platform-dependent elements (e.g.,
RegisterFile frame_registers = RegisterAllocator::Reserved(); // return address). Replace those first.
for (int i = 0; i < length; i++) { entry_frame_ = new VirtualFrame(cgen_);
FrameElement* element = elements[i]; int index = 0;
if (element != NULL && element->is_register()) { for (; index < entry_frame_->elements_.length(); index++) {
frame_registers.Use(element->reg()); // 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;
}
} }
} }
// Then fill in the rest of the frame with new elements.
// Build the new frame. The frame already has memory elements for for (; index < length; index++) {
// the parameters (including the receiver) and the return address. if (elements[index] == NULL) {
// We will fill it up with memory elements. entry_frame_->elements_.Add(FrameElement::MemoryElement());
entry_frame_ = new VirtualFrame(cgen_); } else {
while (entry_frame_->elements_.length() < length) { entry_frame_->elements_.Add(*elements[index]);
entry_frame_->elements_.Add(FrameElement::MemoryElement()); if (elements[index]->is_register()) {
entry_frame_->register_locations_[elements[index]->reg().code()] =
index;
}
}
} }
// Allocate any still-undetermined frame elements to registers or
// Copy the already-determined frame elements to the entry frame, // memory, from the top down.
// and allocate any still-undetermined frame elements to registers
// or memory, from the top down.
for (int i = length - 1; i >= 0; i--) { for (int i = length - 1; i >= 0; i--) {
if (elements[i] == NULL) { if (elements[i] == NULL) {
// If the value is synced on all frames, put it in memory. This // If the value is synced on all frames, put it in memory. This
...@@ -234,7 +243,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -234,7 +243,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
for (int j = 0; j < reaching_frames_.length(); j++) { for (int j = 0; j < reaching_frames_.length(); j++) {
FrameElement element = reaching_frames_[j]->elements_[i]; FrameElement element = reaching_frames_[j]->elements_[i];
if (element.is_register() && if (element.is_register() &&
!frame_registers.is_used(element.reg())) { !entry_frame_->is_used(element.reg())) {
candidate_registers.Use(element.reg()); candidate_registers.Use(element.reg());
if (candidate_registers.count(element.reg()) > max_count) { if (candidate_registers.count(element.reg()) > max_count) {
max_count = candidate_registers.count(element.reg()); max_count = candidate_registers.count(element.reg());
...@@ -245,7 +254,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -245,7 +254,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// If there was no preferred choice consider any free register. // If there was no preferred choice consider any free register.
if (best_reg_code == no_reg.code_) { if (best_reg_code == no_reg.code_) {
for (int j = 0; j < kNumRegisters; j++) { 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; best_reg_code = j;
break; break;
} }
...@@ -256,27 +265,21 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -256,27 +265,21 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// (the element is already recorded as in memory) // (the element is already recorded as in memory)
if (best_reg_code != no_reg.code_) { if (best_reg_code != no_reg.code_) {
Register reg = { best_reg_code }; Register reg = { best_reg_code };
frame_registers.Use(reg);
entry_frame_->elements_[i] = entry_frame_->elements_[i] =
FrameElement::RegisterElement(reg, FrameElement::RegisterElement(reg,
FrameElement::NOT_SYNCED); 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 // 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 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];
current->clear_copied(); current->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()) {
entry_frame_->register_locations_[current->reg().code()] = i;
} }
if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { if (direction_ == BIDIRECTIONAL && i >= high_water_mark) {
......
...@@ -275,6 +275,11 @@ class RegisterAllocator BASE_EMBEDDED { ...@@ -275,6 +275,11 @@ class RegisterAllocator BASE_EMBEDDED {
// Unuse all the reserved registers in a register file. // Unuse all the reserved registers in a register file.
static void UnuseReserved(RegisterFile* 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. // Predicates and accessors for the registers' reference counts.
bool is_used(int reg_code) const { return registers_.is_used(reg_code); } 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()); } 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