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

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: Created 7 years, 2 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 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
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
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
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
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