| 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 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 | 1232 |
| 1233 HValue* HMul::Canonicalize() { | 1233 HValue* HMul::Canonicalize() { |
| 1234 if (IsIdentityOperation(left(), right(), 1)) return left(); | 1234 if (IsIdentityOperation(left(), right(), 1)) return left(); |
| 1235 if (IsIdentityOperation(right(), left(), 1)) return right(); | 1235 if (IsIdentityOperation(right(), left(), 1)) return right(); |
| 1236 return this; | 1236 return this; |
| 1237 } | 1237 } |
| 1238 | 1238 |
| 1239 | 1239 |
| 1240 bool HMul::MulMinusOne() { |
| 1241 if (left()->EqualsInteger32Constant(-1) || |
| 1242 right()->EqualsInteger32Constant(-1)) { |
| 1243 return true; |
| 1244 } |
| 1245 |
| 1246 return false; |
| 1247 } |
| 1248 |
| 1249 |
| 1240 HValue* HMod::Canonicalize() { | 1250 HValue* HMod::Canonicalize() { |
| 1241 return this; | 1251 return this; |
| 1242 } | 1252 } |
| 1243 | 1253 |
| 1244 | 1254 |
| 1245 HValue* HDiv::Canonicalize() { | 1255 HValue* HDiv::Canonicalize() { |
| 1246 if (IsIdentityOperation(left(), right(), 1)) return left(); | 1256 if (IsIdentityOperation(left(), right(), 1)) return left(); |
| 1247 return this; | 1257 return this; |
| 1248 } | 1258 } |
| 1249 | 1259 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 } | 1625 } |
| 1616 } | 1626 } |
| 1617 | 1627 |
| 1618 | 1628 |
| 1619 Range* HMul::InferRange(Zone* zone) { | 1629 Range* HMul::InferRange(Zone* zone) { |
| 1620 Representation r = representation(); | 1630 Representation r = representation(); |
| 1621 if (r.IsSmiOrInteger32()) { | 1631 if (r.IsSmiOrInteger32()) { |
| 1622 Range* a = left()->range(); | 1632 Range* a = left()->range(); |
| 1623 Range* b = right()->range(); | 1633 Range* b = right()->range(); |
| 1624 Range* res = a->Copy(zone); | 1634 Range* res = a->Copy(zone); |
| 1625 if (!res->MulAndCheckOverflow(r, b)) { | 1635 if (!res->MulAndCheckOverflow(r, b) || |
| 1626 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 | 1636 (((r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) || |
| 1627 // would be wrong, because truncated integer multiplication is too | 1637 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) && |
| 1628 // precise and therefore not the same as converting to Double and back. | 1638 MulMinusOne())) { |
| 1639 // Truncated int multiplication is too precise and therefore not the |
| 1640 // same as converting to Double and back. |
| 1641 // Handle truncated integer multiplication by -1 special. |
| 1629 ClearFlag(kCanOverflow); | 1642 ClearFlag(kCanOverflow); |
| 1630 } | 1643 } |
| 1631 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && | 1644 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
| 1632 !CheckFlag(kAllUsesTruncatingToInt32) && | 1645 !CheckFlag(kAllUsesTruncatingToInt32) && |
| 1633 ((a->CanBeZero() && b->CanBeNegative()) || | 1646 ((a->CanBeZero() && b->CanBeNegative()) || |
| 1634 (a->CanBeNegative() && b->CanBeZero()))); | 1647 (a->CanBeNegative() && b->CanBeZero()))); |
| 1635 return res; | 1648 return res; |
| 1636 } else { | 1649 } else { |
| 1637 return HValue::InferRange(zone); | 1650 return HValue::InferRange(zone); |
| 1638 } | 1651 } |
| 1639 } | 1652 } |
| 1640 | 1653 |
| 1641 | 1654 |
| 1642 Range* HDiv::InferRange(Zone* zone) { | 1655 Range* HDiv::InferRange(Zone* zone) { |
| 1643 if (representation().IsInteger32()) { | 1656 if (representation().IsInteger32()) { |
| 1644 Range* a = left()->range(); | 1657 Range* a = left()->range(); |
| 1645 Range* b = right()->range(); | 1658 Range* b = right()->range(); |
| 1646 Range* result = new(zone) Range(); | 1659 Range* result = new(zone) Range(); |
| 1647 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && | 1660 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| 1648 (a->CanBeMinusZero() || | 1661 (a->CanBeMinusZero() || |
| 1649 (a->CanBeZero() && b->CanBeNegative()))); | 1662 (a->CanBeZero() && b->CanBeNegative()))); |
| 1650 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1663 if (!a->Includes(kMinInt) || |
| 1664 !b->Includes(-1) || |
| 1665 CheckFlag(kAllUsesTruncatingToInt32)) { |
| 1666 // It is safe to clear kCanOverflow when kAllUsesTruncatingToInt32. |
| 1651 ClearFlag(HValue::kCanOverflow); | 1667 ClearFlag(HValue::kCanOverflow); |
| 1652 } | 1668 } |
| 1653 | 1669 |
| 1654 if (!b->CanBeZero()) { | 1670 if (!b->CanBeZero()) { |
| 1655 ClearFlag(HValue::kCanBeDivByZero); | 1671 ClearFlag(HValue::kCanBeDivByZero); |
| 1656 } | 1672 } |
| 1657 return result; | 1673 return result; |
| 1658 } else { | 1674 } else { |
| 1659 return HValue::InferRange(zone); | 1675 return HValue::InferRange(zone); |
| 1660 } | 1676 } |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2613 right()->PrintNameTo(stream); | 2629 right()->PrintNameTo(stream); |
| 2614 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 2630 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
| 2615 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 2631 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 2616 } | 2632 } |
| 2617 | 2633 |
| 2618 | 2634 |
| 2619 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { | 2635 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 2620 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2636 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 2621 Representation new_rep = RepresentationFromInputs(); | 2637 Representation new_rep = RepresentationFromInputs(); |
| 2622 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2638 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 2639 |
| 2640 if (representation().IsSmi() && HasNonSmiUse()) { |
| 2641 UpdateRepresentation( |
| 2642 Representation::Integer32(), h_infer, "use requirements"); |
| 2643 } |
| 2644 |
| 2623 if (observed_output_representation_.IsNone()) { | 2645 if (observed_output_representation_.IsNone()) { |
| 2624 new_rep = RepresentationFromUses(); | 2646 new_rep = RepresentationFromUses(); |
| 2625 UpdateRepresentation(new_rep, h_infer, "uses"); | 2647 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 2626 } else { | 2648 } else { |
| 2627 new_rep = RepresentationFromOutput(); | 2649 new_rep = RepresentationFromOutput(); |
| 2628 UpdateRepresentation(new_rep, h_infer, "output"); | 2650 UpdateRepresentation(new_rep, h_infer, "output"); |
| 2629 } | 2651 } |
| 2630 | |
| 2631 if (representation().IsSmi() && HasNonSmiUse()) { | |
| 2632 UpdateRepresentation( | |
| 2633 Representation::Integer32(), h_infer, "use requirements"); | |
| 2634 } | |
| 2635 } | 2652 } |
| 2636 | 2653 |
| 2637 | 2654 |
| 2638 Representation HBinaryOperation::RepresentationFromInputs() { | 2655 Representation HBinaryOperation::RepresentationFromInputs() { |
| 2639 // Determine the worst case of observed input representations and | 2656 // Determine the worst case of observed input representations and |
| 2640 // the currently assumed output representation. | 2657 // the currently assumed output representation. |
| 2641 Representation rep = representation(); | 2658 Representation rep = representation(); |
| 2642 for (int i = 1; i <= 2; ++i) { | 2659 for (int i = 1; i <= 2; ++i) { |
| 2643 rep = rep.generalize(observed_input_representation(i)); | 2660 rep = rep.generalize(observed_input_representation(i)); |
| 2644 } | 2661 } |
| 2645 // If any of the actual input representation is more general than what we | 2662 // If any of the actual input representation is more general than what we |
| 2646 // have so far but not Tagged, use that representation instead. | 2663 // have so far but not Tagged, use that representation instead. |
| 2647 Representation left_rep = left()->representation(); | 2664 Representation left_rep = left()->representation(); |
| 2648 Representation right_rep = right()->representation(); | 2665 Representation right_rep = right()->representation(); |
| 2649 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); | 2666 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); |
| 2650 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); | 2667 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); |
| 2651 | 2668 |
| 2652 return rep; | 2669 return rep; |
| 2653 } | 2670 } |
| 2654 | 2671 |
| 2655 | 2672 |
| 2656 bool HBinaryOperation::IgnoreObservedOutputRepresentation( | 2673 bool HBinaryOperation::IgnoreObservedOutputRepresentation( |
| 2657 Representation current_rep) { | 2674 Representation current_rep) { |
| 2658 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || | 2675 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || |
| 2659 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && | 2676 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && |
| 2660 // Mul in Integer32 mode would be too precise. | 2677 // Mul in Integer32 mode would be too precise. |
| 2661 !this->IsMul(); | 2678 (!this->IsMul() || HMul::cast(this)->MulMinusOne()); |
| 2662 } | 2679 } |
| 2663 | 2680 |
| 2664 | 2681 |
| 2665 Representation HBinaryOperation::RepresentationFromOutput() { | 2682 Representation HBinaryOperation::RepresentationFromOutput() { |
| 2666 Representation rep = representation(); | 2683 Representation rep = representation(); |
| 2667 // Consider observed output representation, but ignore it if it's Double, | 2684 // Consider observed output representation, but ignore it if it's Double, |
| 2668 // this instruction is not a division, and all its uses are truncating | 2685 // this instruction is not a division, and all its uses are truncating |
| 2669 // to Integer32. | 2686 // to Integer32. |
| 2670 if (observed_output_representation_.is_more_general_than(rep) && | 2687 if (observed_output_representation_.is_more_general_than(rep) && |
| 2671 !IgnoreObservedOutputRepresentation(rep)) { | 2688 !IgnoreObservedOutputRepresentation(rep)) { |
| (...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4223 break; | 4240 break; |
| 4224 case kExternalMemory: | 4241 case kExternalMemory: |
| 4225 stream->Add("[external-memory]"); | 4242 stream->Add("[external-memory]"); |
| 4226 break; | 4243 break; |
| 4227 } | 4244 } |
| 4228 | 4245 |
| 4229 stream->Add("@%d", offset()); | 4246 stream->Add("@%d", offset()); |
| 4230 } | 4247 } |
| 4231 | 4248 |
| 4232 } } // namespace v8::internal | 4249 } } // namespace v8::internal |
| OLD | NEW |