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