Only assign environments when they are actually needed. (ARM and ARM64 only)

Twin of https://codereview.chromium.org/210783003/ and https://codereview.chromium.org/211153003/.

Cleaned up DoChange a bit on the way, making things more uniform across platforms, removed useless comments etc.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/214613004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20376 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0d04cba7
This diff is collapsed.
This diff is collapsed.
......@@ -927,7 +927,7 @@ class LCheckInstanceType V8_FINAL : public LTemplateInstruction<0, 1, 1> {
class LCheckMaps V8_FINAL : public LTemplateInstruction<0, 1, 1> {
public:
explicit LCheckMaps(LOperand* value, LOperand* temp = NULL) {
explicit LCheckMaps(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
......
......@@ -1882,29 +1882,23 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
// Only mark conversions that might need to allocate as calling rather than
// all changes. This makes simple, non-allocating conversion not have to force
// building a stack frame.
if (from.IsTagged()) {
if (to.IsDouble()) {
LOperand* value = UseRegister(instr->value());
// Temp register only necessary for minus zero check.
LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
LInstruction* result = DefineAsRegister(
new(zone()) LNumberUntagD(value, temp));
if (!instr->value()->representation().IsSmi()) {
result = AssignEnvironment(result);
}
LInstruction* result =
DefineAsRegister(new(zone()) LNumberUntagD(value, temp));
if (!val->representation().IsSmi()) result = AssignEnvironment(result);
return result;
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
......@@ -1912,18 +1906,18 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) {
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
LOperand* value = UseRegister(val);
bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp =
(CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating)
? FixedTemp(xmm1) : NULL;
LInstruction* result = DefineSameAsFirst(
new(zone()) LTaggedToI(UseRegister(val), xmm_temp));
if (!instr->value()->representation().IsSmi()) {
LInstruction* result =
DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
if (!val->representation().IsSmi()) {
// Note: Only deopts in deferred code.
result = AssignEnvironment(result);
}
......@@ -1933,23 +1927,20 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
LOperand* value = UseRegisterAtStart(instr->value());
LOperand* value = UseRegisterAtStart(val);
LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
// Make sure that temp and result_temp are different registers.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
bool truncating = instr->CanTruncateToInt32();
bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating;
LOperand* value = needs_temp ?
UseTempRegister(instr->value()) : UseRegister(instr->value());
LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val);
LOperand* temp = needs_temp ? TempRegister() : NULL;
LInstruction* result =
DefineAsRegister(new(zone()) LDoubleToI(value, temp));
......@@ -1959,23 +1950,23 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1)
: NULL;
LOperand* temp2 =
CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1) : NULL;
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignPointerMap(DefineSameAsFirst(result));
} else {
LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp);
return AssignPointerMap(DefineSameAsFirst(result));
}
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineSameAsFirst(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
......@@ -1984,13 +1975,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return result;
} else {
ASSERT(to.IsDouble());
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* temp = FixedTemp(xmm1);
return DefineAsRegister(
new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
new(zone()) LUint32ToDouble(UseRegister(val), temp));
} else {
return DefineAsRegister(
new(zone()) LInteger32ToDouble(Use(instr->value())));
return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
}
}
}
......
......@@ -1804,26 +1804,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from();
Representation to = instr->to();
HValue* val = instr->value();
if (from.IsSmi()) {
if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value));
}
from = Representation::Tagged();
}
// Only mark conversions that might need to allocate as calling rather than
// all changes. This makes simple, non-allocating conversion not have to force
// building a stack frame.
if (from.IsTagged()) {
if (to.IsDouble()) {
LOperand* value = UseRegister(instr->value());
LInstruction* res = DefineAsRegister(new(zone()) LNumberUntagD(value));
if (!instr->value()->representation().IsSmi()) {
res = AssignEnvironment(res);
}
return res;
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
if (!val->representation().IsSmi()) result = AssignEnvironment(result);
return result;
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value));
......@@ -1831,78 +1826,73 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (val->type().IsSmi() || val->representation().IsSmi()) {
LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
LOperand* value = UseRegister(val);
bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
LInstruction* res =
LInstruction* result =
DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
if (!instr->value()->representation().IsSmi()) {
if (!val->representation().IsSmi()) {
// Note: Only deopts in deferred code.
res = AssignEnvironment(res);
result = AssignEnvironment(result);
}
return res;
return result;
}
}
} else if (from.IsDouble()) {
if (to.IsTagged()) {
info()->MarkAsDeferredCalling();
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
LOperand* temp = TempRegister();
// Make sure that temp and result_temp are different registers.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
return AssignPointerMap(Define(result, result_temp));
} else if (to.IsSmi()) {
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else {
ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value());
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
if (!instr->CanTruncateToInt32()) {
result = AssignEnvironment(result);
}
if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
LOperand* value = UseRegister(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(xmm1);
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignPointerMap(DefineSameAsFirst(result));
} else {
LOperand* value = UseRegister(val);
LNumberTagI* result = new(zone()) LNumberTagI(value);
return AssignPointerMap(DefineSameAsFirst(result));
}
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) {
ASSERT(val->CheckFlag(HValue::kUint32));
result = AssignEnvironment(result);
}
return result;
} else {
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
ASSERT(to.IsDouble());
if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* temp = FixedTemp(xmm1);
return DefineAsRegister(
new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
new(zone()) LUint32ToDouble(UseRegister(val), temp));
} else {
ASSERT(to.IsDouble());
LOperand* value = Use(instr->value());
LOperand* value = Use(val);
return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
}
}
......
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