diff options
author | isaacs <i@izs.me> | 2012-05-15 19:53:16 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-05-16 14:22:33 -0700 |
commit | 3f3f958c14cf4e963a73d6f037ac381c77fe78bb (patch) | |
tree | 391e35b59e76d038534fbd375f1bbe0dc55076cf /deps/v8/src/hydrogen-instructions.cc | |
parent | 4099d1eebae4e78864a6879c0b9e08f31d48d8cb (diff) | |
download | node-new-3f3f958c14cf4e963a73d6f037ac381c77fe78bb.tar.gz |
Upgrade V8 to 3.11.1
Diffstat (limited to 'deps/v8/src/hydrogen-instructions.cc')
-rw-r--r-- | deps/v8/src/hydrogen-instructions.cc | 121 |
1 files changed, 110 insertions, 11 deletions
diff --git a/deps/v8/src/hydrogen-instructions.cc b/deps/v8/src/hydrogen-instructions.cc index f698da46d4..c66a7a137d 100644 --- a/deps/v8/src/hydrogen-instructions.cc +++ b/deps/v8/src/hydrogen-instructions.cc @@ -416,6 +416,7 @@ void HValue::Kill() { SetFlag(kIsDead); for (int i = 0; i < OperandCount(); ++i) { HValue* operand = OperandAt(i); + if (operand == NULL) continue; HUseListNode* first = operand->use_list_; if (first != NULL && first->value() == this && first->index() == i) { operand->use_list_ = first->tail(); @@ -462,7 +463,8 @@ void HValue::PrintChangesTo(StringStream* stream) { add_comma = true; \ stream->Add(#type); \ } - GVN_FLAG_LIST(PRINT_DO); + GVN_TRACKED_FLAG_LIST(PRINT_DO); + GVN_UNTRACKED_FLAG_LIST(PRINT_DO); #undef PRINT_DO } stream->Add("]"); @@ -599,6 +601,9 @@ void HInstruction::InsertAfter(HInstruction* previous) { SetBlock(block); previous->next_ = this; if (next != NULL) next->previous_ = this; + if (block->last() == previous) { + block->set_last(this); + } } @@ -608,6 +613,7 @@ void HInstruction::Verify() { HBasicBlock* cur_block = block(); for (int i = 0; i < OperandCount(); ++i) { HValue* other_operand = OperandAt(i); + if (other_operand == NULL) continue; HBasicBlock* other_block = other_operand->block(); if (cur_block == other_block) { if (!other_operand->IsPhi()) { @@ -866,6 +872,17 @@ HValue* HBitwise::Canonicalize() { } +HValue* HBitNot::Canonicalize() { + // Optimize ~~x, a common pattern used for ToInt32(x). + if (value()->IsBitNot()) { + HValue* result = HBitNot::cast(value())->value(); + ASSERT(result->representation().IsInteger32()); + return result; + } + return this; +} + + HValue* HAdd::Canonicalize() { if (!representation().IsInteger32()) return this; if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow); @@ -916,6 +933,62 @@ void HJSArrayLength::PrintDataTo(StringStream* stream) { } +HValue* HUnaryMathOperation::Canonicalize() { + if (op() == kMathFloor) { + // If the input is integer32 then we replace the floor instruction + // with its input. This happens before the representation changes are + // introduced. + if (value()->representation().IsInteger32()) return value(); + +#ifdef V8_TARGET_ARCH_ARM + if (value()->IsDiv() && (value()->UseCount() == 1)) { + // TODO(2038): Implement this optimization for non ARM architectures. + HDiv* hdiv = HDiv::cast(value()); + HValue* left = hdiv->left(); + HValue* right = hdiv->right(); + // Try to simplify left and right values of the division. + HValue* new_left = + LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(left); + HValue* new_right = + LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); + + // Return if left or right are not optimizable. + if ((new_left == NULL) || (new_right == NULL)) return this; + + // Insert the new values in the graph. + if (new_left->IsInstruction() && + !HInstruction::cast(new_left)->IsLinked()) { + HInstruction::cast(new_left)->InsertBefore(this); + } + if (new_right->IsInstruction() && + !HInstruction::cast(new_right)->IsLinked()) { + HInstruction::cast(new_right)->InsertBefore(this); + } + HMathFloorOfDiv* instr = new HMathFloorOfDiv(context(), + new_left, + new_right); + // Replace this HMathFloor instruction by the new HMathFloorOfDiv. + instr->InsertBefore(this); + ReplaceAllUsesWith(instr); + Kill(); + // We know the division had no other uses than this HMathFloor. Delete it. + // Also delete the arguments of the division if they are not used any + // more. + hdiv->DeleteAndReplaceWith(NULL); + ASSERT(left->IsChange() || left->IsConstant()); + ASSERT(right->IsChange() || right->IsConstant()); + if (left->HasNoUses()) left->DeleteAndReplaceWith(NULL); + if (right->HasNoUses()) right->DeleteAndReplaceWith(NULL); + + // Return NULL to remove this instruction from the graph. + return NULL; + } +#endif // V8_TARGET_ARCH_ARM + } + return this; +} + + HValue* HCheckInstanceType::Canonicalize() { if (check_ == IS_STRING && !value()->type().IsUninitialized() && @@ -965,16 +1038,13 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) { } -void HCheckMap::PrintDataTo(StringStream* stream) { +void HCheckMaps::PrintDataTo(StringStream* stream) { value()->PrintNameTo(stream); - stream->Add(" %p", *map()); - if (mode() == REQUIRE_EXACT_MAP) { - stream->Add(" [EXACT]"); - } else if (!has_element_transitions_) { - stream->Add(" [EXACT*]"); - } else { - stream->Add(" [MATCH ELEMENTS]"); + stream->Add(" [%p", *map_set()->first()); + for (int i = 1; i < map_set()->length(); ++i) { + stream->Add(",%p", *map_set()->at(i)); } + stream->Add("]"); } @@ -1533,6 +1603,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, SetOperandAt(1, object); set_representation(Representation::Tagged()); SetGVNFlag(kDependsOnMaps); + int map_transitions = 0; for (int i = 0; i < types->length() && types_.length() < kMaxLoadPolymorphism; ++i) { @@ -1554,13 +1625,20 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, case CONSTANT_FUNCTION: types_.Add(types->at(i)); break; + case MAP_TRANSITION: + // We should just ignore these since they are not relevant to a load + // operation. This means we will deopt if we actually see this map + // from optimized code. + map_transitions++; + break; default: break; } } } - if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) { + if (types_.length() + map_transitions == types->length() && + FLAG_deoptimize_uncommon_cases) { SetFlag(kUseGVN); } else { SetAllSideEffects(); @@ -1736,6 +1814,9 @@ void HStoreNamedField::PrintDataTo(StringStream* stream) { stream->Add(" = "); value()->PrintNameTo(stream); stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); + if (NeedsWriteBarrier()) { + stream->Add(" (write-barrier)"); + } if (!transition().is_null()) { stream->Add(" (transition map %p)", *transition()); } @@ -1879,7 +1960,7 @@ HType HValue::CalculateInferredType() { } -HType HCheckMap::CalculateInferredType() { +HType HCheckMaps::CalculateInferredType() { return value()->type(); } @@ -2089,6 +2170,17 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) { } +bool HStoreKeyedFastDoubleElement::NeedsCanonicalization() { + // If value was loaded from unboxed double backing store or + // converted from an integer then we don't have to canonicalize it. + if (value()->IsLoadKeyedFastDoubleElement() || + (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) { + return false; + } + return true; +} + + #define H_CONSTANT_INT32(val) \ new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ Representation::Integer32()) @@ -2257,6 +2349,13 @@ void HIn::PrintDataTo(StringStream* stream) { } +void HBitwise::PrintDataTo(StringStream* stream) { + stream->Add(Token::Name(op_)); + stream->Add(" "); + HBitwiseBinaryOperation::PrintDataTo(stream); +} + + Representation HPhi::InferredRepresentation() { bool double_occurred = false; bool int32_occurred = false; |