| Index: src/ia32/lithium-ia32.cc
|
| diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
|
| index b37589397fc94b4d9853fd7a6472feedb487fa9d..6b4db67aecd5501bd40069910fefa60cd5e2de94 100644
|
| --- a/src/ia32/lithium-ia32.cc
|
| +++ b/src/ia32/lithium-ia32.cc
|
| @@ -911,10 +911,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
|
| if (current->OperandCount() == 0) {
|
| instr = DefineAsRegister(new(zone()) LDummy());
|
| } else {
|
| + ASSERT(!current->OperandAt(0)->IsControlInstruction());
|
| instr = DefineAsRegister(new(zone())
|
| LDummyUse(UseAny(current->OperandAt(0))));
|
| }
|
| for (int i = 1; i < current->OperandCount(); ++i) {
|
| + if (current->OperandAt(i)->IsControlInstruction()) continue;
|
| LInstruction* dummy =
|
| new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
|
| dummy->set_hydrogen_value(current);
|
| @@ -1025,6 +1027,9 @@ LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
|
| + LInstruction* goto_instr = CheckElideControlInstruction(instr);
|
| + if (goto_instr != NULL) return goto_instr;
|
| +
|
| ASSERT(instr->value()->representation().IsTagged());
|
| LOperand* value = UseRegisterAtStart(instr->value());
|
| return new(zone()) LCmpMapAndBranch(value);
|
| @@ -1127,30 +1132,12 @@ LInstruction* LChunkBuilder::DoContext(HContext* instr) {
|
| }
|
|
|
|
|
| -LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
|
| - LOperand* context = UseRegisterAtStart(instr->value());
|
| - return DefineAsRegister(new(zone()) LOuterContext(context));
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
|
| LOperand* context = UseFixed(instr->context(), esi);
|
| return MarkAsCall(new(zone()) LDeclareGlobals(context), instr);
|
| }
|
|
|
|
|
| -LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
|
| - LOperand* context = UseRegisterAtStart(instr->value());
|
| - return DefineAsRegister(new(zone()) LGlobalObject(context));
|
| -}
|
| -
|
| -
|
| -LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
|
| - LOperand* global_object = UseRegisterAtStart(instr->value());
|
| - return DefineAsRegister(new(zone()) LGlobalReceiver(global_object));
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoCallJSFunction(
|
| HCallJSFunction* instr) {
|
| LOperand* function = UseFixed(instr->function(), edi);
|
| @@ -1197,6 +1184,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
|
| case kMathExp: return DoMathExp(instr);
|
| case kMathSqrt: return DoMathSqrt(instr);
|
| case kMathPowHalf: return DoMathPowHalf(instr);
|
| + case kMathClz32: return DoMathClz32(instr);
|
| default:
|
| UNREACHABLE();
|
| return NULL;
|
| @@ -1235,6 +1223,13 @@ LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
|
| + LOperand* input = UseRegisterAtStart(instr->value());
|
| + LMathClz32* result = new(zone()) LMathClz32(input);
|
| + return DefineAsRegister(result);
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
|
| ASSERT(instr->representation().IsDouble());
|
| ASSERT(instr->value()->representation().IsDouble());
|
| @@ -1281,9 +1276,7 @@ LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
|
| LOperand* context = UseFixed(instr->context(), esi);
|
| LOperand* function = UseFixed(instr->function(), edi);
|
| LCallFunction* call = new(zone()) LCallFunction(context, function);
|
| - LInstruction* result = DefineFixed(call, eax);
|
| - if (instr->IsTailCall()) return result;
|
| - return MarkAsCall(result, instr);
|
| + return MarkAsCall(DefineFixed(call, eax), instr);
|
| }
|
|
|
|
|
| @@ -1332,12 +1325,12 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
|
| if (instr->representation().IsSmiOrInteger32()) {
|
| ASSERT(instr->left()->representation().Equals(instr->representation()));
|
| ASSERT(instr->right()->representation().Equals(instr->representation()));
|
| - if (instr->HasPowerOf2Divisor()) {
|
| + if (instr->RightIsPowerOf2()) {
|
| ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
|
| - LOperand* value = UseRegisterAtStart(instr->left());
|
| + LOperand* value = UseRegister(instr->left());
|
| LDivI* div =
|
| new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL);
|
| - return AssignEnvironment(DefineSameAsFirst(div));
|
| + return AssignEnvironment(DefineAsRegister(div));
|
| }
|
| // The temporary operand is necessary to ensure that right is not allocated
|
| // into edx.
|
| @@ -1354,25 +1347,6 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
|
| }
|
|
|
|
|
| -HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
|
| - if (divisor->IsConstant() &&
|
| - HConstant::cast(divisor)->HasInteger32Value()) {
|
| - HConstant* constant_val = HConstant::cast(divisor);
|
| - return constant_val->CopyToRepresentation(Representation::Integer32(),
|
| - divisor->block()->zone());
|
| - }
|
| - // A value with an integer representation does not need to be transformed.
|
| - if (divisor->representation().IsInteger32()) {
|
| - return divisor;
|
| - // A change from an integer32 can be replaced by the integer32 value.
|
| - } else if (divisor->IsChange() &&
|
| - HChange::cast(divisor)->from().IsInteger32()) {
|
| - return HChange::cast(divisor)->value();
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
|
| HValue* right = instr->right();
|
| if (!right->IsConstant()) {
|
| @@ -1418,7 +1392,7 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
| ASSERT(instr->left()->representation().Equals(instr->representation()));
|
| ASSERT(instr->right()->representation().Equals(instr->representation()));
|
|
|
| - if (instr->HasPowerOf2Divisor()) {
|
| + if (instr->RightIsPowerOf2()) {
|
| ASSERT(!right->CanBeZero());
|
| LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
|
| UseOrConstant(right),
|
| @@ -1732,19 +1706,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
| }
|
|
|
|
|
| -LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
|
| - LOperand* object = UseRegisterAtStart(instr->value());
|
| - return DefineAsRegister(new(zone()) LElementsKind(object));
|
| -}
|
| -
|
| -
|
| -LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
|
| - LOperand* object = UseRegister(instr->value());
|
| - LValueOf* result = new(zone()) LValueOf(object, TempRegister());
|
| - return DefineSameAsFirst(result);
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
| LOperand* date = UseFixed(instr->value(), eax);
|
| LDateField* result =
|
| @@ -1814,13 +1775,6 @@ LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
|
| }
|
|
|
|
|
| -LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
|
| - LOperand* context = UseFixed(instr->context(), esi);
|
| - LOperand* value = UseFixed(instr->value(), eax);
|
| - return MarkAsCall(new(zone()) LThrow(context, value), instr);
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
|
| return NULL;
|
| }
|
| @@ -2126,13 +2080,6 @@ LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
|
| }
|
|
|
|
|
| -LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
|
| - HLoadExternalArrayPointer* instr) {
|
| - LOperand* input = UseRegisterAtStart(instr->value());
|
| - return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input));
|
| -}
|
| -
|
| -
|
| LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
|
| ASSERT(instr->key()->representation().IsSmiOrInteger32());
|
| ElementsKind elements_kind = instr->elements_kind();
|
| @@ -2158,7 +2105,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
|
|
|
| DefineAsRegister(result);
|
| bool can_deoptimize = instr->RequiresHoleCheck() ||
|
| - (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS);
|
| + (elements_kind == EXTERNAL_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;
|
| @@ -2181,9 +2128,9 @@ LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
|
|
|
| // Determine if we need a byte register in this case for the value.
|
| bool val_is_fixed_register =
|
| - elements_kind == EXTERNAL_BYTE_ELEMENTS ||
|
| - elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
|
| - elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
|
| + elements_kind == EXTERNAL_INT8_ELEMENTS ||
|
| + elements_kind == EXTERNAL_UINT8_ELEMENTS ||
|
| + elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
|
| elements_kind == UINT8_ELEMENTS ||
|
| elements_kind == INT8_ELEMENTS ||
|
| elements_kind == UINT8_CLAMPED_ELEMENTS;
|
| @@ -2378,12 +2325,8 @@ LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
|
| LOperand* context = UseFixed(instr->context(), esi);
|
| - LOperand* left = FLAG_new_string_add
|
| - ? UseFixed(instr->left(), edx)
|
| - : UseOrConstantAtStart(instr->left());
|
| - LOperand* right = FLAG_new_string_add
|
| - ? UseFixed(instr->right(), eax)
|
| - : UseOrConstantAtStart(instr->right());
|
| + LOperand* left = UseFixed(instr->left(), edx);
|
| + LOperand* right = UseFixed(instr->right(), eax);
|
| LStringAdd* string_add = new(zone()) LStringAdd(context, left, right);
|
| return MarkAsCall(DefineFixed(string_add, eax), instr);
|
| }
|
|
|