Index: src/arm64/lithium-arm64.cc |
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc |
index 4bed135bca576a259a4e137bde030afdfd3d2c0c..1888affd683f74e78ebea1c6f441c0f7585c063d 100644 |
--- a/src/arm64/lithium-arm64.cc |
+++ b/src/arm64/lithium-arm64.cc |
@@ -1074,63 +1074,61 @@ LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { |
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(); |
} |
- |
if (from.IsTagged()) { |
if (to.IsDouble()) { |
- LOperand* value = UseRegister(instr->value()); |
+ LOperand* value = UseRegister(val); |
LOperand* temp = TempRegister(); |
- LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); |
- return AssignEnvironment(DefineAsRegister(res)); |
+ LInstruction* result = |
+ DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); |
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
+ return result; |
} else if (to.IsSmi()) { |
- LOperand* value = UseRegister(instr->value()); |
- if (instr->value()->type().IsSmi()) { |
+ LOperand* value = UseRegister(val); |
+ if (val->type().IsSmi()) { |
return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
} |
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
} else { |
ASSERT(to.IsInteger32()); |
- LInstruction* res = NULL; |
- |
- if (instr->value()->type().IsSmi() || |
- instr->value()->representation().IsSmi()) { |
- LOperand* value = UseRegisterAtStart(instr->value()); |
- res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
+ if (val->type().IsSmi() || val->representation().IsSmi()) { |
+ LOperand* value = UseRegisterAtStart(val); |
+ return DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
} else { |
- LOperand* value = UseRegister(instr->value()); |
+ LOperand* value = UseRegister(val); |
LOperand* temp1 = TempRegister(); |
LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24); |
- res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); |
- res = AssignEnvironment(res); |
+ LInstruction* result = |
+ DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); |
+ if (!val->representation().IsSmi()) { |
+ // Note: Only deopts in deferred code. |
+ result = AssignEnvironment(result); |
+ } |
+ return result; |
} |
- |
- return res; |
} |
} else if (from.IsDouble()) { |
if (to.IsTagged()) { |
info()->MarkAsDeferredCalling(); |
- LOperand* value = UseRegister(instr->value()); |
+ LOperand* value = UseRegister(val); |
LOperand* temp1 = TempRegister(); |
LOperand* temp2 = TempRegister(); |
- |
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); |
return AssignPointerMap(DefineAsRegister(result)); |
} else { |
ASSERT(to.IsSmi() || to.IsInteger32()); |
- LOperand* value = UseRegister(instr->value()); |
- |
if (instr->CanTruncateToInt32()) { |
- LTruncateDoubleToIntOrSmi* result = |
- new(zone()) LTruncateDoubleToIntOrSmi(value); |
- return DefineAsRegister(result); |
+ LOperand* value = UseRegister(val); |
+ return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value)); |
} else { |
+ LOperand* value = UseRegister(val); |
LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value); |
return AssignEnvironment(DefineAsRegister(result)); |
} |
@@ -1138,37 +1136,35 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
} else if (from.IsInteger32()) { |
info()->MarkAsDeferredCalling(); |
if (to.IsTagged()) { |
- if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
- LOperand* value = UseRegister(instr->value()); |
- LNumberTagU* result = new(zone()) LNumberTagU(value, |
- TempRegister(), |
- TempRegister()); |
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
+ if (val->CheckFlag(HInstruction::kUint32)) { |
+ LOperand* value = UseRegister(val); |
+ LNumberTagU* result = |
+ new(zone()) LNumberTagU(value, TempRegister(), TempRegister()); |
+ return AssignPointerMap(DefineAsRegister(result)); |
} else { |
STATIC_ASSERT((kMinInt == Smi::kMinValue) && |
(kMaxInt == Smi::kMaxValue)); |
- LOperand* value = UseRegisterAtStart(instr->value()); |
+ LOperand* value = UseRegisterAtStart(val); |
return DefineAsRegister(new(zone()) LSmiTag(value)); |
} |
} else if (to.IsSmi()) { |
- LOperand* value = UseRegisterAtStart(instr->value()); |
+ LOperand* value = UseRegisterAtStart(val); |
LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); |
- if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
+ if (val->CheckFlag(HInstruction::kUint32)) { |
result = AssignEnvironment(result); |
} |
return result; |
} else { |
ASSERT(to.IsDouble()); |
- if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
+ if (val->CheckFlag(HInstruction::kUint32)) { |
return DefineAsRegister( |
- new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value()))); |
+ new(zone()) LUint32ToDouble(UseRegisterAtStart(val))); |
} else { |
return DefineAsRegister( |
- new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value()))); |
+ new(zone()) LInteger32ToDouble(UseRegisterAtStart(val))); |
} |
} |
} |
- |
UNREACHABLE(); |
return NULL; |
} |
@@ -1189,21 +1185,20 @@ LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { |
- if (instr->CanOmitMapChecks()) { |
- // LCheckMaps does nothing in this case. |
- return new(zone()) LCheckMaps(NULL); |
- } else { |
- LOperand* value = UseRegisterAtStart(instr->value()); |
- LOperand* temp = TempRegister(); |
- |
- if (instr->has_migration_target()) { |
- info()->MarkAsDeferredCalling(); |
- LInstruction* result = new(zone()) LCheckMaps(value, temp); |
- return AssignPointerMap(AssignEnvironment(result)); |
- } else { |
- return AssignEnvironment(new(zone()) LCheckMaps(value, temp)); |
- } |
+ LOperand* value = NULL; |
+ LOperand* temp = NULL; |
+ if (!instr->CanOmitMapChecks()) { |
+ value = UseRegisterAtStart(instr->value()); |
+ temp = TempRegister(); |
+ if (instr->has_migration_target()) info()->MarkAsDeferredCalling(); |
+ } |
+ LInstruction* result = new(zone()) LCheckMaps(value, temp); |
+ if (!instr->CanOmitMapChecks()) { |
+ // Note: Only deopts in deferred code. |
+ result = AssignEnvironment(result); |
+ if (instr->has_migration_target()) return AssignPointerMap(result); |
} |
+ return result; |
} |
@@ -1418,8 +1413,12 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { |
LOperand* divisor = UseRegister(instr->right()); |
LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
? NULL : TempRegister(); |
- LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
- return AssignEnvironment(DefineAsRegister(div)); |
+ LInstruction* result = |
+ DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); |
+ if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
+ result = AssignEnvironment(result); |
+ } |
+ return result; |
} |
@@ -1622,7 +1621,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; |
} |
@@ -1687,17 +1689,14 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); |
- LLoadKeyedExternal* result = |
- new(zone()) LLoadKeyedExternal(elements, key, temp); |
- // An unsigned int array load might overflow and cause a deopt. Make sure it |
- // has an environment. |
- if (instr->RequiresHoleCheck() || |
- elements_kind == EXTERNAL_UINT32_ELEMENTS || |
- elements_kind == UINT32_ELEMENTS) { |
- return AssignEnvironment(DefineAsRegister(result)); |
- } else { |
- return DefineAsRegister(result); |
+ LInstruction* result = DefineAsRegister( |
+ new(zone()) LLoadKeyedExternal(elements, key, temp)); |
+ if ((elements_kind == EXTERNAL_UINT32_ELEMENTS || |
+ elements_kind == UINT32_ELEMENTS) && |
+ !instr->CheckFlag(HInstruction::kUint32)) { |
+ result = AssignEnvironment(result); |
} |
+ return result; |
} |
} |
@@ -1885,13 +1884,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
- bool needs_environment = can_overflow || bailout_on_minus_zero; |
HValue* least_const = instr->BetterLeftOperand(); |
HValue* most_const = instr->BetterRightOperand(); |
- LOperand* left; |
- |
// LMulConstI can handle a subset of constants: |
// With support for overflow detection: |
// -1, 0, 1, 2 |
@@ -1911,26 +1907,27 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
IsPowerOf2(constant_abs - 1))))) { |
LConstantOperand* right = UseConstant(most_const); |
bool need_register = IsPowerOf2(constant_abs) && !small_constant; |
- left = need_register ? UseRegister(least_const) |
- : UseRegisterAtStart(least_const); |
- LMulConstIS* mul = new(zone()) LMulConstIS(left, right); |
- if (needs_environment) AssignEnvironment(mul); |
- return DefineAsRegister(mul); |
+ LOperand* left = need_register ? UseRegister(least_const) |
+ : UseRegisterAtStart(least_const); |
+ LInstruction* result = |
+ DefineAsRegister(new(zone()) LMulConstIS(left, right)); |
+ if ((bailout_on_minus_zero && constant <= 0) || can_overflow) { |
+ result = AssignEnvironment(result); |
+ } |
+ return result; |
} |
} |
- left = UseRegisterAtStart(least_const); |
// LMulI/S can handle all cases, but it requires that a register is |
// allocated for the second operand. |
- LInstruction* result; |
- if (instr->representation().IsSmi()) { |
- LOperand* right = UseRegisterAtStart(most_const); |
- result = DefineAsRegister(new(zone()) LMulS(left, right)); |
- } else { |
- LOperand* right = UseRegisterAtStart(most_const); |
- result = DefineAsRegister(new(zone()) LMulI(left, right)); |
+ LOperand* left = UseRegisterAtStart(least_const); |
+ LOperand* right = UseRegisterAtStart(most_const); |
+ LInstruction* result = instr->representation().IsSmi() |
+ ? DefineAsRegister(new(zone()) LMulS(left, right)) |
+ : DefineAsRegister(new(zone()) LMulI(left, right)); |
+ if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) { |
+ result = AssignEnvironment(result); |
} |
- if (needs_environment) AssignEnvironment(result); |
return result; |
} else if (instr->representation().IsDouble()) { |
return DoArithmeticD(Token::MUL, instr); |
@@ -2160,7 +2157,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { |
value = UseRegister(instr->value()); |
} |
LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); |
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; |
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { |
+ result = AssignEnvironment(result); |
+ } |
+ return result; |
} |
@@ -2294,7 +2294,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)); |
} |
@@ -2430,21 +2430,15 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
LOperand* temp1 = TempRegister(); |
LOperand* temp2 = TempRegister(); |
LOperand* temp3 = TempRegister(); |
- LMathAbsTagged* result = |
- new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3); |
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
+ LInstruction* result = DefineAsRegister( |
+ new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3)); |
+ // Note: Only deopts in deferred code. |
+ return AssignEnvironment(AssignPointerMap(result)); |
} else { |
LOperand* input = UseRegisterAtStart(instr->value()); |
- LMathAbs* result = new(zone()) LMathAbs(input); |
- if (r.IsDouble()) { |
- // The Double case can never fail so it doesn't need an environment. |
- return DefineAsRegister(result); |
- } else { |
- ASSERT(r.IsInteger32() || r.IsSmi()); |
- // The Integer32 and Smi cases need an environment because they can |
- // deoptimize on minimum representable number. |
- return AssignEnvironment(DefineAsRegister(result)); |
- } |
+ LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input)); |
+ if (!r.IsDouble()) result = AssignEnvironment(result); |
+ return result; |
} |
} |
case kMathExp: { |