| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 | 1234 |
| 1235 HValue* HMul::Canonicalize() { | 1235 HValue* HMul::Canonicalize() { |
| 1236 if (IsIdentityOperation(left(), right(), 1)) return left(); | 1236 if (IsIdentityOperation(left(), right(), 1)) return left(); |
| 1237 if (IsIdentityOperation(right(), left(), 1)) return right(); | 1237 if (IsIdentityOperation(right(), left(), 1)) return right(); |
| 1238 return this; | 1238 return this; |
| 1239 } | 1239 } |
| 1240 | 1240 |
| 1241 | 1241 |
| 1242 bool HMul::MulMinusOne() { |
| 1243 if (left()->EqualsInteger32Constant(-1) || |
| 1244 right()->EqualsInteger32Constant(-1)) { |
| 1245 return true; |
| 1246 } |
| 1247 |
| 1248 return false; |
| 1249 } |
| 1250 |
| 1251 |
| 1242 HValue* HMod::Canonicalize() { | 1252 HValue* HMod::Canonicalize() { |
| 1243 return this; | 1253 return this; |
| 1244 } | 1254 } |
| 1245 | 1255 |
| 1246 | 1256 |
| 1247 HValue* HDiv::Canonicalize() { | 1257 HValue* HDiv::Canonicalize() { |
| 1248 if (IsIdentityOperation(left(), right(), 1)) return left(); | 1258 if (IsIdentityOperation(left(), right(), 1)) return left(); |
| 1249 return this; | 1259 return this; |
| 1250 } | 1260 } |
| 1251 | 1261 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 } | 1627 } |
| 1618 } | 1628 } |
| 1619 | 1629 |
| 1620 | 1630 |
| 1621 Range* HMul::InferRange(Zone* zone) { | 1631 Range* HMul::InferRange(Zone* zone) { |
| 1622 Representation r = representation(); | 1632 Representation r = representation(); |
| 1623 if (r.IsSmiOrInteger32()) { | 1633 if (r.IsSmiOrInteger32()) { |
| 1624 Range* a = left()->range(); | 1634 Range* a = left()->range(); |
| 1625 Range* b = right()->range(); | 1635 Range* b = right()->range(); |
| 1626 Range* res = a->Copy(zone); | 1636 Range* res = a->Copy(zone); |
| 1627 if (!res->MulAndCheckOverflow(r, b)) { | 1637 if (!res->MulAndCheckOverflow(r, b) || |
| 1628 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 | 1638 (((r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) || |
| 1629 // would be wrong, because truncated integer multiplication is too | 1639 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) && |
| 1630 // precise and therefore not the same as converting to Double and back. | 1640 MulMinusOne())) { |
| 1641 // Truncated int multiplication is too precise and therefore not the |
| 1642 // same as converting to Double and back. |
| 1643 // Handle truncated integer multiplication by -1 special. |
| 1631 ClearFlag(kCanOverflow); | 1644 ClearFlag(kCanOverflow); |
| 1632 } | 1645 } |
| 1633 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && | 1646 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
| 1634 !CheckFlag(kAllUsesTruncatingToInt32) && | 1647 !CheckFlag(kAllUsesTruncatingToInt32) && |
| 1635 ((a->CanBeZero() && b->CanBeNegative()) || | 1648 ((a->CanBeZero() && b->CanBeNegative()) || |
| 1636 (a->CanBeNegative() && b->CanBeZero()))); | 1649 (a->CanBeNegative() && b->CanBeZero()))); |
| 1637 return res; | 1650 return res; |
| 1638 } else { | 1651 } else { |
| 1639 return HValue::InferRange(zone); | 1652 return HValue::InferRange(zone); |
| 1640 } | 1653 } |
| 1641 } | 1654 } |
| 1642 | 1655 |
| 1643 | 1656 |
| 1644 Range* HDiv::InferRange(Zone* zone) { | 1657 Range* HDiv::InferRange(Zone* zone) { |
| 1645 if (representation().IsInteger32()) { | 1658 if (representation().IsInteger32()) { |
| 1646 Range* a = left()->range(); | 1659 Range* a = left()->range(); |
| 1647 Range* b = right()->range(); | 1660 Range* b = right()->range(); |
| 1648 Range* result = new(zone) Range(); | 1661 Range* result = new(zone) Range(); |
| 1649 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && | 1662 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| 1650 (a->CanBeMinusZero() || | 1663 (a->CanBeMinusZero() || |
| 1651 (a->CanBeZero() && b->CanBeNegative()))); | 1664 (a->CanBeZero() && b->CanBeNegative()))); |
| 1652 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1665 if (!a->Includes(kMinInt) || |
| 1666 !b->Includes(-1) || |
| 1667 CheckFlag(kAllUsesTruncatingToInt32)) { |
| 1668 // It is safe to clear kCanOverflow when kAllUsesTruncatingToInt32. |
| 1653 ClearFlag(HValue::kCanOverflow); | 1669 ClearFlag(HValue::kCanOverflow); |
| 1654 } | 1670 } |
| 1655 | 1671 |
| 1656 if (!b->CanBeZero()) { | 1672 if (!b->CanBeZero()) { |
| 1657 ClearFlag(HValue::kCanBeDivByZero); | 1673 ClearFlag(HValue::kCanBeDivByZero); |
| 1658 } | 1674 } |
| 1659 return result; | 1675 return result; |
| 1660 } else { | 1676 } else { |
| 1661 return HValue::InferRange(zone); | 1677 return HValue::InferRange(zone); |
| 1662 } | 1678 } |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2320 HValue* value = values()->at(i); | 2336 HValue* value = values()->at(i); |
| 2321 if (HasAssignedIndexAt(i)) { | 2337 if (HasAssignedIndexAt(i)) { |
| 2322 env->Bind(GetAssignedIndexAt(i), value); | 2338 env->Bind(GetAssignedIndexAt(i), value); |
| 2323 } else { | 2339 } else { |
| 2324 env->Push(value); | 2340 env->Push(value); |
| 2325 } | 2341 } |
| 2326 } | 2342 } |
| 2327 } | 2343 } |
| 2328 | 2344 |
| 2329 | 2345 |
| 2346 static void ReplayEnvironmentNested(const ZoneList<HValue*>* values, |
| 2347 HCapturedObject* other) { |
| 2348 for (int i = 0; i < values->length(); ++i) { |
| 2349 HValue* value = values->at(i); |
| 2350 if (value->IsCapturedObject()) { |
| 2351 if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) { |
| 2352 values->at(i) = other; |
| 2353 } else { |
| 2354 ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other); |
| 2355 } |
| 2356 } |
| 2357 } |
| 2358 } |
| 2359 |
| 2360 |
| 2330 // Replay captured objects by replacing all captured objects with the | 2361 // Replay captured objects by replacing all captured objects with the |
| 2331 // same capture id in the current and all outer environments. | 2362 // same capture id in the current and all outer environments. |
| 2332 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { | 2363 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { |
| 2333 ASSERT(env != NULL); | 2364 ASSERT(env != NULL); |
| 2334 while (env != NULL) { | 2365 while (env != NULL) { |
| 2335 for (int i = 0; i < env->length(); ++i) { | 2366 ReplayEnvironmentNested(env->values(), this); |
| 2336 HValue* value = env->values()->at(i); | |
| 2337 if (value->IsCapturedObject() && | |
| 2338 HCapturedObject::cast(value)->capture_id() == this->capture_id()) { | |
| 2339 env->SetValueAt(i, this); | |
| 2340 } | |
| 2341 } | |
| 2342 env = env->outer(); | 2367 env = env->outer(); |
| 2343 } | 2368 } |
| 2344 } | 2369 } |
| 2345 | 2370 |
| 2346 | 2371 |
| 2347 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, | 2372 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, |
| 2348 Zone* zone) { | 2373 Zone* zone) { |
| 2349 ASSERT(return_target->IsInlineReturnTarget()); | 2374 ASSERT(return_target->IsInlineReturnTarget()); |
| 2350 return_targets_.Add(return_target, zone); | 2375 return_targets_.Add(return_target, zone); |
| 2351 } | 2376 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2591 right()->PrintNameTo(stream); | 2616 right()->PrintNameTo(stream); |
| 2592 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 2617 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
| 2593 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 2618 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 2594 } | 2619 } |
| 2595 | 2620 |
| 2596 | 2621 |
| 2597 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { | 2622 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 2598 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2623 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 2599 Representation new_rep = RepresentationFromInputs(); | 2624 Representation new_rep = RepresentationFromInputs(); |
| 2600 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2625 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 2626 |
| 2627 if (representation().IsSmi() && HasNonSmiUse()) { |
| 2628 UpdateRepresentation( |
| 2629 Representation::Integer32(), h_infer, "use requirements"); |
| 2630 } |
| 2631 |
| 2601 if (observed_output_representation_.IsNone()) { | 2632 if (observed_output_representation_.IsNone()) { |
| 2602 new_rep = RepresentationFromUses(); | 2633 new_rep = RepresentationFromUses(); |
| 2603 UpdateRepresentation(new_rep, h_infer, "uses"); | 2634 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 2604 } else { | 2635 } else { |
| 2605 new_rep = RepresentationFromOutput(); | 2636 new_rep = RepresentationFromOutput(); |
| 2606 UpdateRepresentation(new_rep, h_infer, "output"); | 2637 UpdateRepresentation(new_rep, h_infer, "output"); |
| 2607 } | 2638 } |
| 2608 | |
| 2609 if (representation().IsSmi() && HasNonSmiUse()) { | |
| 2610 UpdateRepresentation( | |
| 2611 Representation::Integer32(), h_infer, "use requirements"); | |
| 2612 } | |
| 2613 } | 2639 } |
| 2614 | 2640 |
| 2615 | 2641 |
| 2616 Representation HBinaryOperation::RepresentationFromInputs() { | 2642 Representation HBinaryOperation::RepresentationFromInputs() { |
| 2617 // Determine the worst case of observed input representations and | 2643 // Determine the worst case of observed input representations and |
| 2618 // the currently assumed output representation. | 2644 // the currently assumed output representation. |
| 2619 Representation rep = representation(); | 2645 Representation rep = representation(); |
| 2620 for (int i = 1; i <= 2; ++i) { | 2646 for (int i = 1; i <= 2; ++i) { |
| 2621 rep = rep.generalize(observed_input_representation(i)); | 2647 rep = rep.generalize(observed_input_representation(i)); |
| 2622 } | 2648 } |
| 2623 // If any of the actual input representation is more general than what we | 2649 // If any of the actual input representation is more general than what we |
| 2624 // have so far but not Tagged, use that representation instead. | 2650 // have so far but not Tagged, use that representation instead. |
| 2625 Representation left_rep = left()->representation(); | 2651 Representation left_rep = left()->representation(); |
| 2626 Representation right_rep = right()->representation(); | 2652 Representation right_rep = right()->representation(); |
| 2627 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); | 2653 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); |
| 2628 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); | 2654 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); |
| 2629 | 2655 |
| 2630 return rep; | 2656 return rep; |
| 2631 } | 2657 } |
| 2632 | 2658 |
| 2633 | 2659 |
| 2634 bool HBinaryOperation::IgnoreObservedOutputRepresentation( | 2660 bool HBinaryOperation::IgnoreObservedOutputRepresentation( |
| 2635 Representation current_rep) { | 2661 Representation current_rep) { |
| 2636 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || | 2662 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || |
| 2637 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && | 2663 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && |
| 2638 // Mul in Integer32 mode would be too precise. | 2664 // Mul in Integer32 mode would be too precise. |
| 2639 !this->IsMul(); | 2665 (!this->IsMul() || HMul::cast(this)->MulMinusOne()); |
| 2640 } | 2666 } |
| 2641 | 2667 |
| 2642 | 2668 |
| 2643 Representation HBinaryOperation::RepresentationFromOutput() { | 2669 Representation HBinaryOperation::RepresentationFromOutput() { |
| 2644 Representation rep = representation(); | 2670 Representation rep = representation(); |
| 2645 // Consider observed output representation, but ignore it if it's Double, | 2671 // Consider observed output representation, but ignore it if it's Double, |
| 2646 // this instruction is not a division, and all its uses are truncating | 2672 // this instruction is not a division, and all its uses are truncating |
| 2647 // to Integer32. | 2673 // to Integer32. |
| 2648 if (observed_output_representation_.is_more_general_than(rep) && | 2674 if (observed_output_representation_.is_more_general_than(rep) && |
| 2649 !IgnoreObservedOutputRepresentation(rep)) { | 2675 !IgnoreObservedOutputRepresentation(rep)) { |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4201 break; | 4227 break; |
| 4202 case kExternalMemory: | 4228 case kExternalMemory: |
| 4203 stream->Add("[external-memory]"); | 4229 stream->Add("[external-memory]"); |
| 4204 break; | 4230 break; |
| 4205 } | 4231 } |
| 4206 | 4232 |
| 4207 stream->Add("@%d", offset()); | 4233 stream->Add("@%d", offset()); |
| 4208 } | 4234 } |
| 4209 | 4235 |
| 4210 } } // namespace v8::internal | 4236 } } // namespace v8::internal |
| OLD | NEW |