Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: src/arm/virtual-frame-arm.cc

Issue 1604002: Simple register allocation for ARM. Only top of expression... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/arm/virtual-frame-arm.cc
===================================================================
--- src/arm/virtual-frame-arm.cc (revision 4341)
+++ src/arm/virtual-frame-arm.cc (working copy)
@@ -37,37 +37,123 @@
#define __ ACCESS_MASM(masm())
-void VirtualFrame::SyncElementBelowStackPointer(int index) {
- UNREACHABLE();
+void VirtualFrame::PopToR1R0() {
+ VirtualFrame where_to_go = *this;
+ where_to_go.top_of_stack_state_ = R1_R0_TOS;
+ MergeTo(&where_to_go);
Søren Thygesen Gjesse 2010/04/07 10:46:51 Maybe add a comment here saying the r0/r1 TOS stat
Erik Corry 2010/04/07 12:49:17 Done.
+ element_count_ -= 2;
+ top_of_stack_state_ = NO_TOS_REGISTERS;
}
-void VirtualFrame::SyncElementByPushing(int index) {
- UNREACHABLE();
+void VirtualFrame::PopToR1() {
+ VirtualFrame where_to_go = *this;
+ where_to_go.top_of_stack_state_ = R1_TOS;
+ MergeTo(&where_to_go);
+ element_count_ -= 1;
+ top_of_stack_state_ = NO_TOS_REGISTERS;
}
-void VirtualFrame::MergeTo(VirtualFrame* expected) {
- // ARM frames are currently always in memory.
- ASSERT(Equals(expected));
+void VirtualFrame::PopToR0() {
+ VirtualFrame where_to_go = *this;
+ where_to_go.top_of_stack_state_ = R0_TOS;
+ MergeTo(&where_to_go);
+ element_count_ -= 1;
+ top_of_stack_state_ = NO_TOS_REGISTERS;
}
-void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) {
- UNREACHABLE();
+void VirtualFrame::MergeTo(VirtualFrame* expected) {
Kasper Lund 2010/04/07 08:09:50 Do you have good tests of this function? Full cove
Erik Corry 2010/04/07 12:49:17 No. The coverage tool for covering code generated
+ if (Equals(expected)) return;
+ switch (top_of_stack_state_ * 5 + expected->top_of_stack_state_) {
Søren Thygesen Gjesse 2010/04/07 10:46:51 Maybe add a macro for (one_state * 5 + another_sta
Erik Corry 2010/04/07 12:49:17 On ARM multiplying by 5 should be the same speed a
+ case NO_TOS_REGISTERS * 5 + NO_TOS_REGISTERS:
+ break;
+ case NO_TOS_REGISTERS * 5 + R0_TOS:
+ __ pop(r0);
+ break;
+ case NO_TOS_REGISTERS * 5 + R1_TOS:
+ __ pop(r1);
+ break;
+ case NO_TOS_REGISTERS * 5 + R1_R0_TOS:
+ __ pop(r0);
+ __ pop(r1);
+ break;
+ case NO_TOS_REGISTERS * 5 + R0_R1_TOS:
+ __ pop(r0);
+ __ pop(r1);
+ break;
+ case R0_TOS * 5 + NO_TOS_REGISTERS:
+ __ push(r0);
+ break;
+ case R0_TOS * 5 + R0_TOS:
+ break;
+ case R0_TOS * 5 + R1_TOS:
+ __ mov(r1, r0);
+ break;
+ case R0_TOS * 5 + R1_R0_TOS:
+ __ pop(r1);
+ break;
+ case R0_TOS * 5 + R0_R1_TOS:
+ __ mov(r1, r0);
+ __ pop(r0);
+ break;
+ case R1_TOS * 5 + NO_TOS_REGISTERS:
+ __ push(r1);
+ break;
+ case R1_TOS * 5 + R0_TOS:
+ __ mov(r0, r1);
+ break;
+ case R1_TOS * 5 + R1_TOS:
+ break;
+ case R1_TOS * 5 + R1_R0_TOS:
+ __ mov(r0, r1);
+ __ pop(r1);
+ break;
+ case R1_TOS * 5 + R0_R1_TOS:
+ __ pop(r0);
+ break;
+ case R1_R0_TOS * 5 + NO_TOS_REGISTERS:
+ __ push(r1);
+ __ push(r0);
+ break;
+ case R1_R0_TOS * 5 + R0_TOS:
+ __ push(r1);
+ break;
+ case R1_R0_TOS * 5 + R1_TOS:
+ __ push(r1);
+ __ mov(r1, r0);
+ break;
+ case R1_R0_TOS * 5 + R1_R0_TOS:
+ break;
+ case R1_R0_TOS * 5 + R0_R1_TOS:
Søren Thygesen Gjesse 2010/04/07 07:53:37 MacroAssembler::Swap?
Erik Corry 2010/04/07 12:49:17 Done.
+ __ eor(r0, r0, Operand(r1));
+ __ eor(r1, r1, Operand(r0));
+ __ eor(r0, r0, Operand(r1));
+ break;
+ case R0_R1_TOS * 5 + NO_TOS_REGISTERS:
+ __ push(r0);
+ __ push(r1);
+ break;
+ case R0_R1_TOS * 5 + R0_TOS:
+ __ push(r0);
+ __ mov(r0, r1);
+ break;
+ case R0_R1_TOS * 5 + R1_TOS:
+ __ push(r0);
+ break;
+ case R0_R1_TOS * 5 + R1_R0_TOS:
+ __ eor(r0, r0, Operand(r1));
Kasper Lund 2010/04/07 08:09:50 Swap again.
Erik Corry 2010/04/07 12:49:17 Done.
+ __ eor(r1, r1, Operand(r0));
+ __ eor(r0, r0, Operand(r1));
+ break;
+ case R0_R1_TOS * 5 + R0_R1_TOS:
+ break;
Søren Thygesen Gjesse 2010/04/07 10:46:51 default with UNREACHABLE()?
Erik Corry 2010/04/07 12:49:17 Done.
+ }
+ ASSERT(register_allocation_map_ == expected->register_allocation_map_);
}
-void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
- UNREACHABLE();
-}
-
-
-void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) {
- UNREACHABLE();
-}
-
-
void VirtualFrame::Enter() {
Comment cmnt(masm(), "[ Enter JS frame");
@@ -92,8 +178,6 @@
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
// Adjust FP to point to saved FP.
__ add(fp, sp, Operand(2 * kPointerSize));
- cgen()->allocator()->Unuse(r1);
- cgen()->allocator()->Unuse(lr);
}
@@ -152,37 +236,11 @@
-void VirtualFrame::SaveContextRegister() {
- UNIMPLEMENTED();
-}
-
-
-void VirtualFrame::RestoreContextRegister() {
- UNIMPLEMENTED();
-}
-
-
void VirtualFrame::PushReceiverSlotAddress() {
UNIMPLEMENTED();
}
-int VirtualFrame::InvalidateFrameSlotAt(int index) {
- UNIMPLEMENTED();
- return kIllegalIndex;
-}
-
-
-void VirtualFrame::TakeFrameSlotAt(int index) {
- UNIMPLEMENTED();
-}
-
-
-void VirtualFrame::StoreToFrameSlotAt(int index) {
- UNIMPLEMENTED();
-}
-
-
void VirtualFrame::PushTryHandler(HandlerType type) {
// Grow the expression stack by handler size less one (the return
// address in lr is already counted by a call instruction).
@@ -247,47 +305,155 @@
}
Søren Thygesen Gjesse 2010/04/07 10:46:51 Lining up the states in a comment here could be he
Erik Corry 2010/04/07 12:49:17 Done.
+const bool VirtualFrame::kR0InUse[TOS_STATES] =
+ { false, true, false, true, true };
+const bool VirtualFrame::kR1InUse[TOS_STATES] =
+ { false, false, true, true, true };
+const int VirtualFrame::kVirtualElements[TOS_STATES] = { 0, 1, 1, 2, 2 };
+const VirtualFrame::TopOfStack VirtualFrame::kPopState[TOS_STATES] =
+ { NO_TOS_REGISTERS, NO_TOS_REGISTERS, NO_TOS_REGISTERS, R0_TOS, R1_TOS };
+const VirtualFrame::TopOfStack VirtualFrame::kPushState[TOS_STATES] =
+ { R0_TOS, R0_R1_TOS, R1_R0_TOS, R1_R0_TOS, R0_R1_TOS };
+const Register VirtualFrame::kTopRegister[TOS_STATES] = { r0, r0, r1, r1, r0 };
+const Register VirtualFrame::kBottomRegister[TOS_STATES] =
+ { r0, r0, r1, r0, r1 };
+const Register VirtualFrame::kAllocatedRegisters[
+ VirtualFrame::kNumberOfAllocatedRegisters] = { r2, r3, r4, r5, r6 };
+
+
+bool VirtualFrame::SpilledScope::is_spilled_ = false;
+
+
void VirtualFrame::Drop(int count) {
ASSERT(count >= 0);
ASSERT(height() >= count);
- int num_virtual_elements = (element_count() - 1) - stack_pointer_;
-
- // Emit code to lower the stack pointer if necessary.
- if (num_virtual_elements < count) {
- int num_dropped = count - num_virtual_elements;
- stack_pointer_ -= num_dropped;
- __ add(sp, sp, Operand(num_dropped * kPointerSize));
+ // Discard elements from the virtual frame and free any registers.
+ int num_virtual_elements = kVirtualElements[top_of_stack_state_];
+ while (num_virtual_elements > 0) {
+ Pop();
+ num_virtual_elements--;
+ count--;
+ if (count == 0) return;
}
-
- // Discard elements from the virtual frame and free any registers.
+ if (count == 0) return;
+ __ add(sp, sp, Operand(count * kPointerSize));
element_count_ -= count;
}
-Result VirtualFrame::Pop() {
- UNIMPLEMENTED();
- return Result();
+void VirtualFrame::Pop() {
+ if (top_of_stack_state_ == NO_TOS_REGISTERS) {
+ __ add(sp, sp, Operand(kPointerSize));
+ } else {
+ top_of_stack_state_ = kPopState[top_of_stack_state_];
+ }
+ element_count_--;
}
void VirtualFrame::EmitPop(Register reg) {
- ASSERT(stack_pointer_ == element_count() - 1);
- stack_pointer_--;
+ ASSERT(!is_used(reg));
+ if (top_of_stack_state_ == NO_TOS_REGISTERS) {
+ __ pop(reg);
+ } else {
+ __ mov(reg, kTopRegister[top_of_stack_state_]);
+ top_of_stack_state_ = kPopState[top_of_stack_state_];
+ }
element_count_--;
- __ pop(reg);
}
+Register VirtualFrame::Peek() {
+ AssertIsNotSpilled();
+ if (top_of_stack_state_ == NO_TOS_REGISTERS) {
+ top_of_stack_state_ = kPushState[top_of_stack_state_];
+ Register answer = kTopRegister[top_of_stack_state_];
+ __ pop(answer);
+ return answer;
+ } else {
+ return kTopRegister[top_of_stack_state_];
+ }
+}
+
+
+Register VirtualFrame::PopToRegister(Register but_not_to_this_one) {
Søren Thygesen Gjesse 2010/04/07 10:46:51 Maybe assert that but_not_to_this_one is one of th
Erik Corry 2010/04/07 12:49:17 Done.
+ AssertIsNotSpilled();
+ element_count_--;
+ if (top_of_stack_state_ == NO_TOS_REGISTERS) {
+ if (but_not_to_this_one.is(r0)) {
+ __ pop(r1);
+ return r1;
+ } else {
+ __ pop(r0);
+ return r0;
+ }
+ } else {
Søren Thygesen Gjesse 2010/04/07 10:46:51 Isn't but_not_to_this_one ignored in the else part
Erik Corry 2010/04/07 12:49:17 Yes, because it never happens.
+ Register answer = kTopRegister[top_of_stack_state_];
+ top_of_stack_state_ = kPopState[top_of_stack_state_];
Søren Thygesen Gjesse 2010/04/07 10:46:51 ASSERT(!answer.is(but_not_to_this_one));
Erik Corry 2010/04/07 12:49:17 Done.
+ return answer;
+ }
+}
+
+
void VirtualFrame::EmitPush(Register reg) {
- ASSERT(stack_pointer_ == element_count() - 1);
element_count_++;
- stack_pointer_++;
- __ push(reg);
+ if (SpilledScope::is_spilled()) {
+ __ push(reg);
+ return;
+ }
+ if (top_of_stack_state_ == NO_TOS_REGISTERS) {
+ if (reg.is(r0)) {
+ top_of_stack_state_ = R0_TOS;
+ return;
+ }
+ if (reg.is(r1)) {
+ top_of_stack_state_ = R1_TOS;
+ return;
+ }
+ }
Søren Thygesen Gjesse 2010/04/07 10:46:51 Maybe add some kind of helper function "EnsureOneF
Erik Corry 2010/04/07 12:49:17 Done.
+ if (kVirtualElements[top_of_stack_state_] == kMaxTOSRegisters) {
+ __ push(kBottomRegister[top_of_stack_state_]);
+ }
+ top_of_stack_state_ = kPushState[top_of_stack_state_];
+ Register dest = kTopRegister[top_of_stack_state_];
+ if (!dest.is(reg)) {
+ __ mov(dest, reg);
+ }
}
+Register VirtualFrame::GetTOSRegister() {
+ if (SpilledScope::is_spilled()) return r0;
+
+ if (kVirtualElements[top_of_stack_state_] == kMaxTOSRegisters) {
+ Register answer = kBottomRegister[top_of_stack_state_];
+ __ push(answer);
+ top_of_stack_state_ = kPushState[top_of_stack_state_];
+ top_of_stack_state_ = kPopState[top_of_stack_state_];
+ return answer;
+ }
+
+ return kTopRegister[kPushState[top_of_stack_state_]];
+}
+
+
+void VirtualFrame::EmitPush(MemOperand operand) {
+ element_count_++;
+ if (SpilledScope::is_spilled()) {
+ __ ldr(r0, operand);
+ __ push(r0);
+ return;
+ }
+ if (kVirtualElements[top_of_stack_state_] == kMaxTOSRegisters) {
+ __ push(kBottomRegister[top_of_stack_state_]);
+ }
+ top_of_stack_state_ = kPushState[top_of_stack_state_];
+ __ ldr(kTopRegister[top_of_stack_state_], operand);
+}
+
+
void VirtualFrame::EmitPushMultiple(int count, int src_regs) {
- ASSERT(stack_pointer_ == element_count() - 1);
+ ASSERT(SpilledScope::is_spilled());
Adjust(count);
__ stm(db_w, sp, src_regs);
}

Powered by Google App Engine
This is Rietveld 408576698