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
void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as
// temporaries and outputs because all registers
// are blocked by the calling convention.
// Inputs must use a fixed register.
// Call instructions can use only fixed registers as temporaries and
// outputs because all registers are blocked by the calling convention.
// Inputs operands must use a fixed register or use-at-start policy or
// a non-register policy.
ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(operand->HasFixedPolicy() ||
operand->IsUsedAtStart());
}
for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
LUnallocated* operand = LUnallocated::cast(it.Next());
ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
}
}
#endif

View File

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

View File

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