Refine allocation policy for input operands at calls.

For instructions that are marked as calls we can use:

1. Fixed input registers

2. Use-at-start policy (register, memory or constant).

(Memory or constant would not need the use-at-start policy, but
not specifying use-at-start prevents the allocator from using
a register even if there is one available. That's why use-at-start
is required and guarded by assertion)
Review URL: http://codereview.chromium.org/6853010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7616 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2011-04-14 11:10:00 +00:00
parent 3bbcab1ca9
commit 418501faef
3 changed files with 31 additions and 32 deletions

View File

@ -61,22 +61,21 @@ void LOsrEntry::MarkSpilledRegister(int allocation_index,
#ifdef DEBUG #ifdef DEBUG
void LInstruction::VerifyCall() { void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as // Call instructions can use only fixed registers as temporaries and
// temporaries and outputs because all registers // outputs because all registers are blocked by the calling convention.
// are blocked by the calling convention. // Inputs operands must use a fixed register or use-at-start policy or
// Inputs must use a fixed register. // a non-register policy.
ASSERT(Output() == NULL || ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() || LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy()); !LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) { for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy()); operand->IsUsedAtStart());
} }
for (TempIterator it(this); it.HasNext(); it.Advance()) { for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
!LUnallocated::cast(operand)->HasRegisterPolicy());
} }
} }
#endif #endif

View File

@ -71,22 +71,21 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
#ifdef DEBUG #ifdef DEBUG
void LInstruction::VerifyCall() { void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as // Call instructions can use only fixed registers as temporaries and
// temporaries and outputs because all registers // outputs because all registers are blocked by the calling convention.
// are blocked by the calling convention. // Inputs operands must use a fixed register or use-at-start policy or
// Inputs must use a fixed register. // a non-register policy.
ASSERT(Output() == NULL || ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() || LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy()); !LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) { for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy()); operand->IsUsedAtStart());
} }
for (TempIterator it(this); it.HasNext(); it.Advance()) { for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
!LUnallocated::cast(operand)->HasRegisterPolicy());
} }
} }
#endif #endif
@ -2046,7 +2045,8 @@ LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LDeleteProperty* result = LDeleteProperty* result =
new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key())); new LDeleteProperty(UseAtStart(instr->object()),
UseOrConstantAtStart(instr->key()));
return MarkAsCall(DefineFixed(result, eax), instr); return MarkAsCall(DefineFixed(result, eax), instr);
} }

View File

@ -71,22 +71,21 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
#ifdef DEBUG #ifdef DEBUG
void LInstruction::VerifyCall() { void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as // Call instructions can use only fixed registers as temporaries and
// temporaries and outputs because all registers // outputs because all registers are blocked by the calling convention.
// are blocked by the calling convention. // Inputs operands must use a fixed register or use-at-start policy or
// Inputs must use a fixed register. // a non-register policy.
ASSERT(Output() == NULL || ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() || LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy()); !LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) { for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy()); operand->IsUsedAtStart());
} }
for (TempIterator it(this); it.HasNext(); it.Advance()) { for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next(); LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
!LUnallocated::cast(operand)->HasRegisterPolicy());
} }
} }
#endif #endif
@ -1984,7 +1983,8 @@ LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LDeleteProperty* result = LDeleteProperty* result =
new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key())); new LDeleteProperty(UseAtStart(instr->object()),
UseOrConstantAtStart(instr->key()));
return MarkAsCall(DefineFixed(result, rax), instr); return MarkAsCall(DefineFixed(result, rax), instr);
} }