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.
- Representation rep = value->representation();
+ Representation r = value->representation();
HType type = value->type();
ToBooleanStub::Types expected = instr->expected_input_types();
- if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() &&
- !expected.IsGeneric()) {
- return AssignEnvironment(result);
+ 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;
}
? NULL
: UseFixed(instr->context(), cp);
LOperand* input = UseRegister(instr->value());
- LMathAbs* result = new(zone()) LMathAbs(context, input);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ LInstruction* result =
+ DefineAsRegister(new(zone()) LMathAbs(context, input));
+ if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
+ if (!r.IsDouble()) result = AssignEnvironment(result);
+ return result;
}
LOperand* dividend = UseRegister(instr->left());
LOperand* divisor = UseRegister(instr->right());
LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
- 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::kCanBeDivByZero) ||
+ instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+ (instr->CheckFlag(HValue::kCanOverflow) &&
+ (!CpuFeatures::IsSupported(SUDIV) ||
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
+ (!instr->IsMathFloorOfDiv() &&
+ !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
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());
- LNumberUntagD* res = new(zone()) LNumberUntagD(value);
- return AssignEnvironment(DefineAsRegister(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));
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = NULL;
- LInstruction* res = NULL;
- HValue* val = instr->value();
if (val->type().IsSmi() || val->representation().IsSmi()) {
- value = UseRegisterAtStart(val);
- res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+ LOperand* value = UseRegisterAtStart(val);
+ return DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- value = UseRegister(val);
+ LOperand* value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(d11);
- res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
- temp1,
- temp2));
- res = AssignEnvironment(res);
+ LInstruction* result =
+ DefineSameAsFirst(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();
-
- // Make sure that the temp and result_temp registers are
- // different.
LUnallocated* result_temp = TempRegister();
LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
- Define(result, result_temp);
- return AssignPointerMap(result);
+ 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());
- LDoubleToI* res = new(zone()) LDoubleToI(value);
- return AssignEnvironment(DefineAsRegister(res));
+ LOperand* value = UseRegister(val);
+ LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
+ if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
+ return result;
}
} else if (from.IsInteger32()) {
info()->MarkAsDeferredCalling();
if (to.IsTagged()) {
- HValue* val = instr->value();
- LOperand* value = UseRegisterAtStart(val);
if (!instr->CheckFlag(HValue::kCanOverflow)) {
+ LOperand* value = UseRegisterAtStart(val);
return DefineAsRegister(new(zone()) LSmiTag(value));
} else if (val->CheckFlag(HInstruction::kUint32)) {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
} else {
+ LOperand* value = UseRegisterAtStart(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(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)) {
return result;
} else {
ASSERT(to.IsDouble());
- if (instr->value()->CheckFlag(HInstruction::kUint32)) {
- return DefineAsRegister(
- new(zone()) LUint32ToDouble(UseRegister(instr->value())));
+ if (val->CheckFlag(HInstruction::kUint32)) {
+ return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
} else {
- return DefineAsRegister(
- new(zone()) LInteger32ToDouble(Use(instr->value())));
+ return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
}
}
}
}
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);
}
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;
}
value = UseRegister(instr->value());
}
LInstruction* result = new(zone()) LStoreContextSlot(context, value);
- return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
+ if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+ result = AssignEnvironment(result);
+ }
+ return result;
}
ASSERT(instr->key()->representation().IsSmiOrInteger32());
ElementsKind elements_kind = instr->elements_kind();
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
- LLoadKeyed* result = NULL;
+ LInstruction* result = NULL;
if (!instr->is_typed_elements()) {
LOperand* obj = NULL;
ASSERT(instr->representation().IsSmiOrTagged());
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);
- // An unsigned int array load might overflow and cause a deopt, make sure it
- // has an environment.
- bool can_deoptimize = instr->RequiresHoleCheck() ||
- elements_kind == EXTERNAL_UINT32_ELEMENTS ||
- elements_kind == UINT32_ELEMENTS;
- 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;
}
// We need a temporary register for write barrier of the map field.
LOperand* temp = 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() &&
+ !instr->value()->type().IsHeapObject()) {
+ result = AssignEnvironment(result);
}
return result;
}
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
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));
}
} 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;
}
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;
}
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;
}
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;
}
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;
}
}
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
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);
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;
}
LOperand* context = UseAny(instr->context());
LStringCharCodeAt* result =
new(zone()) LStringCharCodeAt(context, string, index);
- return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+ return AssignPointerMap(DefineAsRegister(result));
}
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: {
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;
}
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));
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);
}
} 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));
} 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)) {
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)));
}
}
}
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));
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));
}
}