Lithium: avoid registers for constants when possible.
BUG= Review URL: https://codereview.chromium.org/14364010 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14460 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
cb2e54d1ff
commit
84355ae411
@ -552,6 +552,11 @@ LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseConstant(HValue* value) {
|
||||
return chunk_->DefineConstantOperand(HConstant::cast(value));
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseAny(HValue* value) {
|
||||
return value->IsConstant()
|
||||
? chunk_->DefineConstantOperand(HConstant::cast(value))
|
||||
@ -2378,7 +2383,9 @@ LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
|
||||
|
||||
LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
|
||||
info()->MarkAsDeferredCalling();
|
||||
LOperand* size = UseTempRegister(instr->size());
|
||||
LOperand* size = instr->size()->IsConstant()
|
||||
? UseConstant(instr->size())
|
||||
: UseTempRegister(instr->size());
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = TempRegister();
|
||||
LAllocate* result = new(zone()) LAllocate(size, temp1, temp2);
|
||||
|
@ -2787,6 +2787,9 @@ class LChunkBuilder BASE_EMBEDDED {
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
|
||||
|
||||
// An input operand in a constant operand.
|
||||
MUST_USE_RESULT LOperand* UseConstant(HValue* value);
|
||||
|
||||
// An input operand in register, stack slot or a constant operand.
|
||||
// Will not be moved to a register even if one is freely available.
|
||||
MUST_USE_RESULT LOperand* UseAny(HValue* value);
|
||||
|
@ -5473,7 +5473,6 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
|
||||
Register size = ToRegister(instr->size());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
||||
// TODO(3095996): Get rid of this. For now, we need to make the
|
||||
@ -5482,8 +5481,16 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
|
||||
__ mov(result, Operand(Smi::FromInt(0)));
|
||||
|
||||
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
||||
__ SmiTag(size, size);
|
||||
__ push(size);
|
||||
if (instr->size()->IsRegister()) {
|
||||
Register size = ToRegister(instr->size());
|
||||
ASSERT(!size.is(result));
|
||||
__ SmiTag(size);
|
||||
__ push(size);
|
||||
} else {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Push(Smi::FromInt(size));
|
||||
}
|
||||
|
||||
if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
|
||||
CallRuntimeFromDeferred(
|
||||
Runtime::kAllocateInOldPointerSpace, 1, instr);
|
||||
|
@ -3265,6 +3265,12 @@ class HConstant: public HTemplateInstruction<0> {
|
||||
std::isnan(double_value_));
|
||||
}
|
||||
|
||||
bool InNewSpace() {
|
||||
if (handle().is_null()) return false;
|
||||
ALLOW_HANDLE_DEREF(isolate(), "using raw address");
|
||||
return isolate()->heap()->InNewSpace(*handle());
|
||||
}
|
||||
|
||||
bool ImmortalImmovable() const {
|
||||
if (has_int32_value_) {
|
||||
return false;
|
||||
|
@ -1494,6 +1494,7 @@ HInstruction* HGraphBuilder::BuildStoreMap(HValue* object,
|
||||
HInstruction* store_map =
|
||||
new(zone) HStoreNamedField(object, map_field_name, map,
|
||||
true, JSObject::kMapOffset);
|
||||
store_map->ClearGVNFlag(kChangesInobjectFields);
|
||||
store_map->SetGVNFlag(kChangesMaps);
|
||||
AddInstruction(store_map);
|
||||
return store_map;
|
||||
|
@ -6025,18 +6025,24 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
|
||||
Register size = ToRegister(instr->size());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
||||
__ SmiTag(size);
|
||||
PushSafepointRegistersScope scope(this);
|
||||
// TODO(3095996): Get rid of this. For now, we need to make the
|
||||
// result register contain a valid pointer because it is already
|
||||
// contained in the register pointer map.
|
||||
if (!size.is(result)) {
|
||||
__ StoreToSafepointRegisterSlot(result, size);
|
||||
__ mov(result, Immediate(Smi::FromInt(0)));
|
||||
|
||||
PushSafepointRegistersScope scope(this);
|
||||
if (instr->size()->IsRegister()) {
|
||||
Register size = ToRegister(instr->size());
|
||||
ASSERT(!size.is(result));
|
||||
__ SmiTag(ToRegister(instr->size()));
|
||||
__ push(size);
|
||||
} else {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ push(Immediate(Smi::FromInt(size)));
|
||||
}
|
||||
__ push(size);
|
||||
|
||||
if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
|
||||
CallRuntimeFromDeferred(
|
||||
Runtime::kAllocateInOldPointerSpace, 1, instr, instr->context());
|
||||
|
@ -601,6 +601,11 @@ LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseConstant(HValue* value) {
|
||||
return chunk_->DefineConstantOperand(HConstant::cast(value));
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseAny(HValue* value) {
|
||||
return value->IsConstant()
|
||||
? chunk_->DefineConstantOperand(HConstant::cast(value))
|
||||
@ -2287,19 +2292,6 @@ LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
|
||||
}
|
||||
|
||||
|
||||
// DoStoreKeyed and DoStoreNamedField have special considerations for allowing
|
||||
// use of a constant instead of a register.
|
||||
static bool StoreConstantValueAllowed(HValue* value) {
|
||||
if (value->IsConstant()) {
|
||||
HConstant* constant_value = HConstant::cast(value);
|
||||
return constant_value->HasSmiValue()
|
||||
|| constant_value->HasDoubleValue()
|
||||
|| constant_value->ImmortalImmovable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
|
||||
if (!instr->is_external()) {
|
||||
ASSERT(instr->elements()->representation().IsTagged());
|
||||
@ -2327,17 +2319,8 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
|
||||
val = UseTempRegister(instr->value());
|
||||
key = UseTempRegister(instr->key());
|
||||
} else {
|
||||
if (StoreConstantValueAllowed(instr->value())) {
|
||||
val = UseRegisterOrConstantAtStart(instr->value());
|
||||
} else {
|
||||
val = UseRegisterAtStart(instr->value());
|
||||
}
|
||||
|
||||
if (StoreConstantValueAllowed(instr->key())) {
|
||||
key = UseRegisterOrConstantAtStart(instr->key());
|
||||
} else {
|
||||
key = UseRegisterAtStart(instr->key());
|
||||
}
|
||||
val = UseRegisterOrConstantAtStart(instr->value());
|
||||
key = UseRegisterOrConstantAtStart(instr->key());
|
||||
}
|
||||
return new(zone()) LStoreKeyed(obj, key, val);
|
||||
}
|
||||
@ -2438,10 +2421,13 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
||||
: UseRegisterAtStart(instr->object());
|
||||
}
|
||||
|
||||
bool can_be_constant = instr->value()->IsConstant() &&
|
||||
!HConstant::cast(instr->value())->InNewSpace();
|
||||
|
||||
LOperand* val;
|
||||
if (needs_write_barrier) {
|
||||
val = UseTempRegister(instr->value());
|
||||
} else if (StoreConstantValueAllowed(instr->value())) {
|
||||
} else if (can_be_constant) {
|
||||
val = UseRegisterOrConstant(instr->value());
|
||||
} else {
|
||||
val = UseRegister(instr->value());
|
||||
@ -2516,8 +2502,9 @@ LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
|
||||
LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
|
||||
info()->MarkAsDeferredCalling();
|
||||
LOperand* context = UseAny(instr->context());
|
||||
// TODO(mvstanton): why can't size be a constant if possible?
|
||||
LOperand* size = UseTempRegister(instr->size());
|
||||
LOperand* size = instr->size()->IsConstant()
|
||||
? UseConstant(instr->size())
|
||||
: UseTempRegister(instr->size());
|
||||
LOperand* temp = TempRegister();
|
||||
LAllocate* result = new(zone()) LAllocate(context, size, temp);
|
||||
return AssignPointerMap(DefineAsRegister(result));
|
||||
|
@ -2908,6 +2908,9 @@ class LChunkBuilder BASE_EMBEDDED {
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
|
||||
|
||||
// An input operand in a constant operand.
|
||||
MUST_USE_RESULT LOperand* UseConstant(HValue* value);
|
||||
|
||||
// An input operand in register, stack slot or a constant operand.
|
||||
// Will not be moved to a register even if one is freely available.
|
||||
MUST_USE_RESULT LOperand* UseAny(HValue* value);
|
||||
|
@ -5122,17 +5122,24 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
|
||||
|
||||
|
||||
void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
|
||||
Register size = ToRegister(instr->size());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
||||
// TODO(3095996): Get rid of this. For now, we need to make the
|
||||
// result register contain a valid pointer because it is already
|
||||
// contained in the register pointer map.
|
||||
__ Set(result, 0);
|
||||
__ Move(result, Smi::FromInt(0));
|
||||
|
||||
PushSafepointRegistersScope scope(this);
|
||||
__ Integer32ToSmi(size, size);
|
||||
__ push(size);
|
||||
if (instr->size()->IsRegister()) {
|
||||
Register size = ToRegister(instr->size());
|
||||
ASSERT(!size.is(result));
|
||||
__ Integer32ToSmi(size, size);
|
||||
__ push(size);
|
||||
} else {
|
||||
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
|
||||
__ Push(Smi::FromInt(size));
|
||||
}
|
||||
|
||||
if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
|
||||
CallRuntimeFromDeferred(
|
||||
Runtime::kAllocateInOldPointerSpace, 1, instr);
|
||||
|
@ -557,6 +557,11 @@ LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseConstant(HValue* value) {
|
||||
return chunk_->DefineConstantOperand(HConstant::cast(value));
|
||||
}
|
||||
|
||||
|
||||
LOperand* LChunkBuilder::UseAny(HValue* value) {
|
||||
return value->IsConstant()
|
||||
? chunk_->DefineConstantOperand(HConstant::cast(value))
|
||||
@ -2115,19 +2120,6 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
|
||||
}
|
||||
|
||||
|
||||
// DoStoreKeyed and DoStoreNamedField have special considerations for allowing
|
||||
// use of a constant instead of a register.
|
||||
static bool StoreConstantValueAllowed(HValue* value) {
|
||||
if (value->IsConstant()) {
|
||||
HConstant* constant_value = HConstant::cast(value);
|
||||
return constant_value->HasSmiValue()
|
||||
|| constant_value->HasDoubleValue()
|
||||
|| constant_value->ImmortalImmovable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
|
||||
ElementsKind elements_kind = instr->elements_kind();
|
||||
bool clobbers_key = instr->key()->representation().IsTagged();
|
||||
@ -2151,18 +2143,12 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
|
||||
val = UseTempRegister(instr->value());
|
||||
key = UseTempRegister(instr->key());
|
||||
} else {
|
||||
if (StoreConstantValueAllowed(instr->value())) {
|
||||
val = UseRegisterOrConstantAtStart(instr->value());
|
||||
} else {
|
||||
val = UseRegisterAtStart(instr->value());
|
||||
}
|
||||
val = UseRegisterOrConstantAtStart(instr->value());
|
||||
|
||||
if (clobbers_key) {
|
||||
key = UseTempRegister(instr->key());
|
||||
} else if (StoreConstantValueAllowed(instr->key())) {
|
||||
key = UseRegisterOrConstantAtStart(instr->key());
|
||||
} else {
|
||||
key = UseRegisterAtStart(instr->key());
|
||||
key = UseRegisterOrConstantAtStart(instr->key());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2258,10 +2244,13 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
|
||||
: UseRegisterAtStart(instr->object());
|
||||
}
|
||||
|
||||
bool can_be_constant = instr->value()->IsConstant() &&
|
||||
!HConstant::cast(instr->value())->InNewSpace();
|
||||
|
||||
LOperand* val;
|
||||
if (needs_write_barrier) {
|
||||
val = UseTempRegister(instr->value());
|
||||
} else if (StoreConstantValueAllowed(instr->value())) {
|
||||
} else if (can_be_constant) {
|
||||
val = UseRegisterOrConstant(instr->value());
|
||||
} else {
|
||||
val = UseRegister(instr->value());
|
||||
@ -2323,7 +2312,9 @@ LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
|
||||
|
||||
LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
|
||||
info()->MarkAsDeferredCalling();
|
||||
LOperand* size = UseTempRegister(instr->size());
|
||||
LOperand* size = instr->size()->IsConstant()
|
||||
? UseConstant(instr->size())
|
||||
: UseTempRegister(instr->size());
|
||||
LOperand* temp = TempRegister();
|
||||
LAllocate* result = new(zone()) LAllocate(size, temp);
|
||||
return AssignPointerMap(DefineAsRegister(result));
|
||||
|
@ -2674,6 +2674,9 @@ class LChunkBuilder BASE_EMBEDDED {
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
|
||||
MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
|
||||
|
||||
// An input operand in a constant operand.
|
||||
MUST_USE_RESULT LOperand* UseConstant(HValue* value);
|
||||
|
||||
// An input operand in register, stack slot or a constant operand.
|
||||
// Will not be moved to a register even if one is freely available.
|
||||
MUST_USE_RESULT LOperand* UseAny(HValue* value);
|
||||
|
Loading…
Reference in New Issue
Block a user