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

Unified Diff: src/compiler/simplified-lowering.cc

Issue 2527083002: [turbofan] Use bounds checks to eliminate subsequent inc/dec overflow checks. (Closed)
Patch Set: Remove dead code Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/redundancy-elimination.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index 9a1565656bf227f2175d097b4e8b1424d5f1a3e1..cb32fc9ae35967c59bffa9e412f9cf7b1d5d30ad 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -209,8 +209,30 @@ class InputUseInfos {
#endif // DEBUG
-} // namespace
+bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
+ Zone* type_zone) {
+ // We assume the inputs are checked Signed32 (or known statically
+ // to be Signed32). Technically, theinputs could also be minus zero, but
+ // that cannot cause overflow.
+ left = Type::Intersect(left, Type::Signed32(), type_zone);
+ right = Type::Intersect(right, Type::Signed32(), type_zone);
+ if (!left->IsInhabited() || !right->IsInhabited()) return false;
+ switch (op->opcode()) {
+ case IrOpcode::kSpeculativeNumberAdd:
+ return (left->Max() + right->Max() > kMaxInt) ||
+ (left->Min() + right->Min() < kMinInt);
+
+ case IrOpcode::kSpeculativeNumberSubtract:
+ return (left->Max() - right->Min() > kMaxInt) ||
+ (left->Min() - right->Max() < kMinInt);
+
+ default:
+ UNREACHABLE();
+ }
+ return true;
+}
+} // namespace
class RepresentationSelector {
public:
@@ -1164,6 +1186,7 @@ class RepresentationSelector {
if (BothInputsAre(node, Type::PlainPrimitive())) {
if (truncation.IsUnused()) return VisitUnused(node);
}
+
if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
(GetUpperBound(node)->Is(Type::Signed32()) ||
GetUpperBound(node)->Is(Type::Unsigned32()) ||
@@ -1177,33 +1200,38 @@ class RepresentationSelector {
// Try to use type feedback.
NumberOperationHint hint = NumberOperationHintOf(node->op());
- // Handle the case when no int32 checks on inputs are necessary
- // (but an overflow check is needed on the output).
- if (BothInputsAre(node, Type::Signed32()) ||
- (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
- NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) {
- // If both the inputs the feedback are int32, use the overflow op.
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ Type* left_feedback_type = TypeOf(node->InputAt(0));
+ Type* right_feedback_type = TypeOf(node->InputAt(1));
+ // Handle the case when no int32 checks on inputs are necessary (but
+ // an overflow check is needed on the output).
+ // TODO(jarin) We should not look at the upper bound because the typer
+ // could have already baked in some feedback into the upper bound.
+ if (BothInputsAre(node, Type::Signed32()) ||
+ (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
+ GetUpperBound(node)->Is(type_cache_.kSafeInteger))) {
VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
- return;
+ } else {
+ UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint);
+ // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
+ // a minus zero check for the right hand side, since we already
+ // know that the left hand side is a proper Signed32 value,
+ // potentially guarded by a check.
+ UseInfo right_use = CheckedUseInfoAsWord32FromHint(
+ hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
+ VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
+ Type::Signed32());
+ }
+ if (lower()) {
+ if (CanOverflowSigned32(node->op(), left_feedback_type,
+ right_feedback_type, graph_zone())) {
+ ChangeToInt32OverflowOp(node);
+ } else {
+ ChangeToPureOp(node, Int32Op(node));
+ }
}
- }
-
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint);
- // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
- // a minus zero check for the right hand side, since we already
- // know that the left hand side is a proper Signed32 value,
- // potentially guarded by a check.
- UseInfo right_use = CheckedUseInfoAsWord32FromHint(
- hint, CheckForMinusZeroMode::kDontCheckForMinusZero);
- VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
- Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
return;
}
« no previous file with comments | « src/compiler/redundancy-elimination.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698