Commit 97829f47 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: Only assign environments when they are actually needed.

Port r20376 (2c4baaf5)

BUG=
R=plind44@gmail.com

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20416 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b4c3d2f9
...@@ -939,18 +939,20 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { ...@@ -939,18 +939,20 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
if (goto_instr != NULL) return goto_instr; if (goto_instr != NULL) return goto_instr;
HValue* value = instr->value(); HValue* value = instr->value();
LBranch* result = new(zone()) LBranch(UseRegister(value)); Representation r = value->representation();
// Tagged values that are not known smis or booleans require a
// deoptimization environment. If the instruction is generic no
// environment is needed since all cases are handled.
Representation rep = value->representation();
HType type = value->type(); HType type = value->type();
ToBooleanStub::Types expected = instr->expected_input_types(); ToBooleanStub::Types expected = instr->expected_input_types();
if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
!expected.IsGeneric()) {
return AssignEnvironment(result); bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
type.IsJSArray() || type.IsHeapNumber() || type.IsString();
LInstruction* branch = new(zone()) LBranch(UseRegister(value));
if (!easy_case &&
((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
!expected.IsGeneric())) {
branch = AssignEnvironment(branch);
} }
return result; return branch;
} }
...@@ -1162,8 +1164,11 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { ...@@ -1162,8 +1164,11 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
? NULL ? NULL
: UseFixed(instr->context(), cp); : UseFixed(instr->context(), cp);
LOperand* input = UseRegister(instr->value()); LOperand* input = UseRegister(instr->value());
LMathAbs* result = new(zone()) LMathAbs(context, input); LInstruction* result =
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); DefineAsRegister(new(zone()) LMathAbs(context, input));
if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
if (!r.IsDouble()) result = AssignEnvironment(result);
return result;
} }
...@@ -1296,8 +1301,17 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { ...@@ -1296,8 +1301,17 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
ASSERT(instr->right()->representation().Equals(instr->representation())); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* dividend = UseRegister(instr->left()); LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right()); LOperand* divisor = UseRegister(instr->right());
LDivI* div = new(zone()) LDivI(dividend, divisor); LInstruction* result =
return AssignEnvironment(DefineAsRegister(div)); DefineAsRegister(new(zone()) LDivI(dividend, divisor));
if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
(instr->CheckFlag(HValue::kCanOverflow) &&
!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
(!instr->IsMathFloorOfDiv() &&
!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
result = AssignEnvironment(result);
}
return result;
} }
...@@ -1789,20 +1803,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { ...@@ -1789,20 +1803,21 @@ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
LInstruction* LChunkBuilder::DoChange(HChange* instr) { LInstruction* LChunkBuilder::DoChange(HChange* instr) {
Representation from = instr->from(); Representation from = instr->from();
Representation to = instr->to(); Representation to = instr->to();
HValue* val = instr->value();
if (from.IsSmi()) { if (from.IsSmi()) {
if (to.IsTagged()) { if (to.IsTagged()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LDummyUse(value)); return DefineSameAsFirst(new(zone()) LDummyUse(value));
} }
from = Representation::Tagged(); from = Representation::Tagged();
} }
if (from.IsTagged()) { if (from.IsTagged()) {
if (to.IsDouble()) { if (to.IsDouble()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(val);
LNumberUntagD* res = new(zone()) LNumberUntagD(value); LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
return AssignEnvironment(DefineAsRegister(res)); if (!val->representation().IsSmi()) result = AssignEnvironment(result);
return result;
} else if (to.IsSmi()) { } else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val); LOperand* value = UseRegister(val);
if (val->type().IsSmi()) { if (val->type().IsSmi()) {
return DefineSameAsFirst(new(zone()) LDummyUse(value)); return DefineSameAsFirst(new(zone()) LDummyUse(value));
...@@ -1810,66 +1825,62 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1810,66 +1825,62 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else { } else {
ASSERT(to.IsInteger32()); ASSERT(to.IsInteger32());
LOperand* value = NULL;
LInstruction* res = NULL;
HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) { if (val->type().IsSmi() || val->representation().IsSmi()) {
value = UseRegisterAtStart(val); LOperand* value = UseRegisterAtStart(val);
res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); return DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else { } else {
value = UseRegister(val); LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(f22); LOperand* temp2 = FixedTemp(f22);
res = DefineSameAsFirst(new(zone()) LTaggedToI(value, LInstruction* result =
temp1, DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
temp2)); if (!val->representation().IsSmi()) {
res = AssignEnvironment(res); // Note: Only deopts in deferred code.
result = AssignEnvironment(result);
}
return result;
} }
return res;
} }
} else if (from.IsDouble()) { } else if (from.IsDouble()) {
if (to.IsTagged()) { if (to.IsTagged()) {
info()->MarkAsDeferredCalling(); info()->MarkAsDeferredCalling();
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister(); LOperand* temp2 = TempRegister();
// Make sure that the temp and result_temp registers are
// different.
LUnallocated* result_temp = TempRegister(); LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
Define(result, result_temp); return AssignPointerMap(Define(result, result_temp));
return AssignPointerMap(result);
} else if (to.IsSmi()) { } else if (to.IsSmi()) {
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(val);
return AssignEnvironment( return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToSmi(value))); DefineAsRegister(new(zone()) LDoubleToSmi(value)));
} else { } else {
ASSERT(to.IsInteger32()); ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value()); LOperand* value = UseRegister(val);
LDoubleToI* res = new(zone()) LDoubleToI(value); LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
return AssignEnvironment(DefineAsRegister(res)); if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
return result;
} }
} else if (from.IsInteger32()) { } else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling(); info()->MarkAsDeferredCalling();
if (to.IsTagged()) { if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegisterAtStart(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) { if (!instr->CheckFlag(HValue::kCanOverflow)) {
LOperand* value = UseRegisterAtStart(val);
return DefineAsRegister(new(zone()) LSmiTag(value)); return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) { } else if (val->CheckFlag(HInstruction::kUint32)) {
LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister(); LOperand* temp2 = TempRegister();
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); return AssignPointerMap(DefineAsRegister(result));
} else { } else {
LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister(); LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister(); LOperand* temp2 = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); return AssignPointerMap(DefineAsRegister(result));
} }
} else if (to.IsSmi()) { } else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val); LOperand* value = UseRegister(val);
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
if (instr->CheckFlag(HValue::kCanOverflow)) { if (instr->CheckFlag(HValue::kCanOverflow)) {
...@@ -1878,12 +1889,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { ...@@ -1878,12 +1889,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
return result; return result;
} else { } else {
ASSERT(to.IsDouble()); ASSERT(to.IsDouble());
if (instr->value()->CheckFlag(HInstruction::kUint32)) { if (val->CheckFlag(HInstruction::kUint32)) {
return DefineAsRegister( return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
new(zone()) LUint32ToDouble(UseRegister(instr->value())));
} else { } else {
return DefineAsRegister( return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
new(zone()) LInteger32ToDouble(Use(instr->value())));
} }
} }
} }
...@@ -1925,6 +1934,7 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { ...@@ -1925,6 +1934,7 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
} }
LCheckMaps* result = new(zone()) LCheckMaps(value); LCheckMaps* result = new(zone()) LCheckMaps(value);
if (!instr->CanOmitMapChecks()) { if (!instr->CanOmitMapChecks()) {
// Note: Only deopts in deferred code.
AssignEnvironment(result); AssignEnvironment(result);
if (instr->has_migration_target()) return AssignPointerMap(result); if (instr->has_migration_target()) return AssignPointerMap(result);
} }
...@@ -2025,7 +2035,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { ...@@ -2025,7 +2035,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
LOperand* context = UseRegisterAtStart(instr->value()); LOperand* context = UseRegisterAtStart(instr->value());
LInstruction* result = LInstruction* result =
DefineAsRegister(new(zone()) LLoadContextSlot(context)); DefineAsRegister(new(zone()) LLoadContextSlot(context));
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
result = AssignEnvironment(result);
}
return result;
} }
...@@ -2040,7 +2053,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { ...@@ -2040,7 +2053,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
value = UseRegister(instr->value()); value = UseRegister(instr->value());
} }
LInstruction* result = new(zone()) LStoreContextSlot(context, value); LInstruction* result = new(zone()) LStoreContextSlot(context, value);
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
result = AssignEnvironment(result);
}
return result;
} }
...@@ -2075,7 +2091,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ...@@ -2075,7 +2091,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsSmiOrInteger32()); ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyed* result = NULL; LInstruction* result = NULL;
if (!instr->is_typed_elements()) { if (!instr->is_typed_elements()) {
LOperand* obj = NULL; LOperand* obj = NULL;
...@@ -2085,24 +2101,28 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ...@@ -2085,24 +2101,28 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->representation().IsSmiOrTagged()); ASSERT(instr->representation().IsSmiOrTagged());
obj = UseRegisterAtStart(instr->elements()); obj = UseRegisterAtStart(instr->elements());
} }
result = new(zone()) LLoadKeyed(obj, key); result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
} else { } else {
ASSERT( ASSERT(
(instr->representation().IsInteger32() && (instr->representation().IsInteger32() &&
!IsDoubleOrFloatElementsKind(instr->elements_kind())) || !IsDoubleOrFloatElementsKind(elements_kind)) ||
(instr->representation().IsDouble() && (instr->representation().IsDouble() &&
IsDoubleOrFloatElementsKind(instr->elements_kind()))); IsDoubleOrFloatElementsKind(elements_kind)));
LOperand* backing_store = UseRegister(instr->elements()); LOperand* backing_store = UseRegister(instr->elements());
result = new(zone()) LLoadKeyed(backing_store, key); result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
} }
DefineAsRegister(result); if ((instr->is_external() || instr->is_fixed_typed_array()) ?
// An unsigned int array load might overflow and cause a deopt, make sure it // see LCodeGen::DoLoadKeyedExternalArray
// has an environment. ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
bool can_deoptimize = instr->RequiresHoleCheck() || elements_kind == UINT32_ELEMENTS) &&
elements_kind == EXTERNAL_UINT32_ELEMENTS || !instr->CheckFlag(HInstruction::kUint32)) :
elements_kind == UINT32_ELEMENTS; // see LCodeGen::DoLoadKeyedFixedDoubleArray and
return can_deoptimize ? AssignEnvironment(result) : result; // LCodeGen::DoLoadKeyedFixedArray
instr->RequiresHoleCheck()) {
result = AssignEnvironment(result);
}
return result;
} }
...@@ -2233,11 +2253,11 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { ...@@ -2233,11 +2253,11 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
// We need a temporary register for write barrier of the map field. // We need a temporary register for write barrier of the map field.
LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL; LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp); LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
if (instr->field_representation().IsHeapObject()) { if (!instr->access().IsExternalMemory() &&
if (!instr->value()->type().IsHeapObject()) { instr->field_representation().IsHeapObject() &&
return AssignEnvironment(result); !instr->value()->type().IsHeapObject()) {
} result = AssignEnvironment(result);
} }
return result; return result;
} }
...@@ -2269,7 +2289,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { ...@@ -2269,7 +2289,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LOperand* context = UseAny(instr->context()); LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result = LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index); new(zone()) LStringCharCodeAt(context, string, index);
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); return AssignPointerMap(DefineAsRegister(result));
} }
......
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