| Index: src/ppc/lithium-ppc.cc
|
| diff --git a/src/ppc/lithium-ppc.cc b/src/ppc/lithium-ppc.cc
|
| index 42470c53a058a84a23f57a9ad5379d4c981e4a28..d54c7ec46af07b940d15204d2a1e21b4af19ac7e 100644
|
| --- a/src/ppc/lithium-ppc.cc
|
| +++ b/src/ppc/lithium-ppc.cc
|
| @@ -268,6 +268,20 @@ void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
|
| }
|
|
|
|
|
| +void LCallFunction::PrintDataTo(StringStream* stream) {
|
| + context()->PrintTo(stream);
|
| + stream->Add(" ");
|
| + function()->PrintTo(stream);
|
| + if (hydrogen()->HasVectorAndSlot()) {
|
| + stream->Add(" (type-feedback-vector ");
|
| + temp_vector()->PrintTo(stream);
|
| + stream->Add(" ");
|
| + temp_slot()->PrintTo(stream);
|
| + stream->Add(")");
|
| + }
|
| +}
|
| +
|
| +
|
| void LCallJSFunction::PrintDataTo(StringStream* stream) {
|
| stream->Add("= ");
|
| function()->PrintTo(stream);
|
| @@ -1104,9 +1118,17 @@ LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
|
| UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
|
| LOperand* name_register =
|
| UseFixed(instr->name(), LoadDescriptor::NameRegister());
|
| + LOperand* slot = NULL;
|
| + LOperand* vector = NULL;
|
| + if (FLAG_vector_ics) {
|
| + slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
|
| + vector =
|
| + UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
|
| + }
|
| +
|
| // Not marked as call. It can't deoptimize, and it never returns.
|
| return new (zone()) LTailCallThroughMegamorphicCache(
|
| - context, receiver_register, name_register);
|
| + context, receiver_register, name_register, slot, vector);
|
| }
|
|
|
|
|
| @@ -1241,7 +1263,15 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
|
| LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
|
| LOperand* context = UseFixed(instr->context(), cp);
|
| LOperand* function = UseFixed(instr->function(), r4);
|
| - LCallFunction* call = new (zone()) LCallFunction(context, function);
|
| + LOperand* slot = NULL;
|
| + LOperand* vector = NULL;
|
| + if (instr->HasVectorAndSlot()) {
|
| + slot = FixedTemp(r6);
|
| + vector = FixedTemp(r5);
|
| + }
|
| +
|
| + LCallFunction* call =
|
| + new (zone()) LCallFunction(context, function, slot, vector);
|
| return MarkAsCall(DefineFixed(call, r3), instr);
|
| }
|
|
|
| @@ -1399,8 +1429,15 @@ LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
|
| DCHECK(instr->right()->representation().Equals(instr->representation()));
|
| LOperand* dividend = UseRegister(instr->left());
|
| LOperand* divisor = UseRegister(instr->right());
|
| - LFlooringDivI* div = new (zone()) LFlooringDivI(dividend, divisor);
|
| - return AssignEnvironment(DefineAsRegister(div));
|
| + LInstruction* result =
|
| + DefineAsRegister(new (zone()) LFlooringDivI(dividend, divisor));
|
| + if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
|
| + instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
|
| + (instr->CheckFlag(HValue::kCanOverflow) &&
|
| + !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
|
| + result = AssignEnvironment(result);
|
| + }
|
| + return result;
|
| }
|
|
|
|
|
| @@ -1490,9 +1527,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
|
| bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
|
|
|
| + int32_t constant_value = 0;
|
| if (right->IsConstant()) {
|
| HConstant* constant = HConstant::cast(right);
|
| - int32_t constant_value = constant->Integer32Value();
|
| + constant_value = constant->Integer32Value();
|
| // Constants -1, 0 and 1 can be optimized if the result can overflow.
|
| // For other constants, it can be optimized only without overflow.
|
| if (!can_overflow || ((constant_value >= -1) && (constant_value <= 1))) {
|
| @@ -1515,34 +1553,15 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| right_op = UseRegister(right);
|
| }
|
| LMulI* mul = new (zone()) LMulI(left_op, right_op);
|
| - if (can_overflow || bailout_on_minus_zero) {
|
| + if (right_op->IsConstantOperand()
|
| + ? ((can_overflow && constant_value == -1) ||
|
| + (bailout_on_minus_zero && constant_value <= 0))
|
| + : (can_overflow || bailout_on_minus_zero)) {
|
| AssignEnvironment(mul);
|
| }
|
| return DefineAsRegister(mul);
|
|
|
| } else if (instr->representation().IsDouble()) {
|
| - if (instr->HasOneUse() &&
|
| - (instr->uses().value()->IsAdd() || instr->uses().value()->IsSub())) {
|
| - HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
|
| -
|
| - if (use->IsAdd() && instr == use->left()) {
|
| - // This mul is the lhs of an add. The add and mul will be folded into a
|
| - // multiply-add in DoAdd.
|
| - return NULL;
|
| - }
|
| - if (instr == use->right() && use->IsAdd() &&
|
| - !(use->left()->IsMul() && use->left()->HasOneUse())) {
|
| - // This mul is the rhs of an add, where the lhs is not another mul.
|
| - // The add and mul will be folded into a multiply-add in DoAdd.
|
| - return NULL;
|
| - }
|
| - if (instr == use->left() && use->IsSub()) {
|
| - // This mul is the lhs of a sub. The mul and sub will be folded into a
|
| - // multiply-sub in DoSub.
|
| - return NULL;
|
| - }
|
| - }
|
| -
|
| return DoArithmeticD(Token::MUL, instr);
|
| } else {
|
| return DoArithmeticT(Token::MUL, instr);
|
| @@ -1570,10 +1589,6 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
|
| }
|
| return result;
|
| } else if (instr->representation().IsDouble()) {
|
| - if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
|
| - return DoMultiplySub(instr->right(), HMul::cast(instr->left()));
|
| - }
|
| -
|
| return DoArithmeticD(Token::SUB, instr);
|
| } else {
|
| return DoArithmeticT(Token::SUB, instr);
|
| @@ -1638,15 +1653,6 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| LInstruction* result = DefineAsRegister(add);
|
| return result;
|
| } else if (instr->representation().IsDouble()) {
|
| - if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
|
| - return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
|
| - }
|
| -
|
| - if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
|
| - DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse());
|
| - return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
|
| - }
|
| -
|
| return DoArithmeticD(Token::ADD, instr);
|
| } else {
|
| return DoArithmeticT(Token::ADD, instr);
|
| @@ -2103,7 +2109,7 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
|
| LOperand* global_object =
|
| UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
|
| LOperand* vector = NULL;
|
| - if (FLAG_vector_ics) {
|
| + if (instr->HasVectorAndSlot()) {
|
| vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
|
| }
|
| LLoadGlobalGeneric* result =
|
| @@ -2163,7 +2169,7 @@ LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
|
| LOperand* object =
|
| UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
|
| LOperand* vector = NULL;
|
| - if (FLAG_vector_ics) {
|
| + if (instr->HasVectorAndSlot()) {
|
| vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
|
| }
|
|
|
| @@ -2230,7 +2236,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
|
| UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
|
| LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
|
| LOperand* vector = NULL;
|
| - if (FLAG_vector_ics) {
|
| + if (instr->HasVectorAndSlot()) {
|
| vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
|
| }
|
|
|
|
|