Only assign environments when they are actually needed. (x64 only)

Twin of https://code.google.com/p/v8/source/detail?r=20231.

R=yangguo@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20271 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 95908dbb
......@@ -947,18 +947,20 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
if (goto_instr != NULL) return goto_instr;
HValue* value = instr->value();
LBranch* result = new(zone()) LBranch(UseRegister(value));
// 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.
ToBooleanStub::Types expected = instr->expected_input_types();
Representation rep = value->representation();
Representation r = value->representation();
HType type = value->type();
if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() &&
!expected.IsGeneric()) {
return AssignEnvironment(result);
ToBooleanStub::Types expected = instr->expected_input_types();
if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
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;
}
......@@ -1143,8 +1145,12 @@ LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
LOperand* context = UseAny(instr->context());
LOperand* input = UseRegisterAtStart(instr->value());
LMathAbs* result = new(zone()) LMathAbs(context, input);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
LInstruction* result =
DefineSameAsFirst(new(zone()) LMathAbs(context, input));
Representation r = instr->value()->representation();
if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
if (!r.IsDouble()) result = AssignEnvironment(result);
return result;
}
......@@ -1798,8 +1804,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (from.IsTagged()) {
if (to.IsDouble()) {
LOperand* value = UseRegister(instr->value());
LNumberUntagD* res = new(zone()) LNumberUntagD(value);
return AssignEnvironment(DefineAsRegister(res));
LInstruction* res = DefineAsRegister(new(zone()) LNumberUntagD(value));
if (!instr->value()->representation().IsSmi()) {
res = AssignEnvironment(res);
}
return res;
} else if (to.IsSmi()) {
HValue* val = instr->value();
LOperand* value = UseRegister(val);
......@@ -1816,8 +1825,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else {
bool truncating = instr->CanTruncateToInt32();
LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp);
return AssignEnvironment(DefineSameAsFirst(res));
LInstruction* res =
DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
if (!instr->value()->representation().IsSmi()) {
// Note: Only deopts in deferred code.
res = AssignEnvironment(res);
}
return res;
}
}
} else if (from.IsDouble()) {
......@@ -1837,8 +1851,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
} else {
ASSERT(to.IsInteger32());
LOperand* value = UseRegister(instr->value());
return AssignEnvironment(
DefineAsRegister(new(zone()) LDoubleToI(value)));
LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
if (!instr->CanTruncateToInt32()) {
result = AssignEnvironment(result);
}
return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
......@@ -1851,10 +1868,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(xmm1);
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
return AssignPointerMap(DefineSameAsFirst(result));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
return AssignPointerMap(DefineSameAsFirst(result));
}
} else if (to.IsSmi()) {
HValue* val = instr->value();
......@@ -1915,6 +1932,7 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
}
LCheckMaps* result = new(zone()) LCheckMaps(value);
if (!instr->CanOmitMapChecks()) {
// Note: Only deopts in deferred code.
AssignEnvironment(result);
if (instr->has_migration_target()) return AssignPointerMap(result);
}
......@@ -2014,7 +2032,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
LInstruction* result =
DefineAsRegister(new(zone()) LLoadContextSlot(context));
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
result = AssignEnvironment(result);
}
return result;
}
......@@ -2031,7 +2052,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
temp = NULL;
}
LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp);
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
result = AssignEnvironment(result);
}
return result;
}
......@@ -2076,28 +2100,32 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
ASSERT(instr->key()->representation().IsInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyed* result = NULL;
LInstruction* result = NULL;
if (!instr->is_typed_elements()) {
LOperand* obj = UseRegisterAtStart(instr->elements());
result = new(zone()) LLoadKeyed(obj, key);
result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
} else {
ASSERT(
(instr->representation().IsInteger32() &&
!(IsDoubleOrFloatElementsKind(instr->elements_kind()))) ||
!(IsDoubleOrFloatElementsKind(elements_kind))) ||
(instr->representation().IsDouble() &&
(IsDoubleOrFloatElementsKind(instr->elements_kind()))));
(IsDoubleOrFloatElementsKind(elements_kind))));
LOperand* backing_store = UseRegister(instr->elements());
result = new(zone()) LLoadKeyed(backing_store, key);
result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
}
DefineAsRegister(result);
bool can_deoptimize = instr->RequiresHoleCheck() ||
(elements_kind == EXTERNAL_UINT32_ELEMENTS) ||
(elements_kind == UINT32_ELEMENTS);
// An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment.
return can_deoptimize ? AssignEnvironment(result) : result;
if ((instr->is_external() || instr->is_fixed_typed_array()) ?
// see LCodeGen::DoLoadKeyedExternalArray
((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
elements_kind == UINT32_ELEMENTS) &&
!instr->CheckFlag(HInstruction::kUint32)) :
// see LCodeGen::DoLoadKeyedFixedDoubleArray and
// LCodeGen::DoLoadKeyedFixedArray
instr->RequiresHoleCheck()) {
result = AssignEnvironment(result);
}
return result;
}
......@@ -2258,11 +2286,13 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
LOperand* temp = (!is_in_object || needs_write_barrier ||
needs_write_barrier_for_map) ? TempRegister() : NULL;
LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
if (instr->field_representation().IsHeapObject()) {
if (!instr->value()->type().IsHeapObject()) {
return AssignEnvironment(result);
}
LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
if (!instr->access().IsExternalMemory() &&
instr->field_representation().IsHeapObject() &&
(val->IsConstantOperand()
? HConstant::cast(instr->value())->HasSmiValue()
: !instr->value()->type().IsHeapObject())) {
result = AssignEnvironment(result);
}
return result;
}
......@@ -2294,7 +2324,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
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