Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(977)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 24521002: Special handle for mul/div minus one when kAllUsesTruncatingToInt32 (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: remove unnecessary ASSERT statement Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/hydrogen-instructions.h ('k') | test/mjsunit/div-mul-minus-one.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | test/mjsunit/div-mul-minus-one.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698