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

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

Issue 2309193003: [turbofan] Avoid overflow checks on SpeculativeNumberAdd/Subtract/Multiply. (Closed)
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/representation-change.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 0bb8a1ce2585fb1454485f152a4536296773c770..e3a7f9cbfa5fd1f4654a1f53e9117261b2997871 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -241,6 +241,12 @@ class RepresentationSelector {
bool weakened() const { return weakened_; }
void set_restriction_type(Type* type) { restriction_type_ = type; }
Type* restriction_type() const { return restriction_type_; }
+ void set_unrestricted_feedback_type(Type* type) {
+ unrestricted_feedback_type_ = type;
+ }
+ Type* unrestricted_feedback_type() const {
+ return unrestricted_feedback_type_;
+ }
private:
enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
@@ -251,6 +257,7 @@ class RepresentationSelector {
Type* restriction_type_ = Type::Any();
Type* feedback_type_ = nullptr;
+ Type* unrestricted_feedback_type_ = nullptr;
bool weakened_ = false;
};
@@ -364,6 +371,11 @@ class RepresentationSelector {
return type == nullptr ? Type::None() : type;
}
+ Type* UnrestrictedFeedbackTypeOf(Node* node) {
+ Type* type = GetInfo(node)->unrestricted_feedback_type();
+ return type == nullptr ? NodeProperties::GetType(node) : type;
+ }
+
Type* TypePhi(Node* node) {
int arity = node->op()->ValueInputCount();
Type* type = FeedbackTypeOf(node->InputAt(0));
@@ -406,13 +418,11 @@ class RepresentationSelector {
SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
-#define DECLARE_CASE(Name) \
- case IrOpcode::k##Name: { \
- new_type = \
- Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \
- FeedbackTypeOf(node->InputAt(1))), \
- info->restriction_type(), graph_zone()); \
- break; \
+#define DECLARE_CASE(Name) \
+ case IrOpcode::k##Name: { \
+ new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \
+ FeedbackTypeOf(node->InputAt(1))); \
+ break; \
}
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE
@@ -451,11 +461,17 @@ class RepresentationSelector {
default:
// Shortcut for operations that we do not handle.
if (type == nullptr) {
- GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
+ type = GetUpperBound(node);
+ info->set_unrestricted_feedback_type(type);
+ info->set_feedback_type(
+ Type::Intersect(type, info->restriction_type(), graph_zone()));
return true;
}
return false;
}
+ Type* unrestricted_feedback_type = new_type;
+ new_type =
+ Type::Intersect(new_type, info->restriction_type(), graph_zone());
// We need to guarantee that the feedback type is a subtype of the upper
// bound. Naively that should hold, but weakening can actually produce
// a bigger type if we are unlucky with ordering of phi typing. To be
@@ -463,7 +479,8 @@ class RepresentationSelector {
new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
if (type != nullptr && new_type->Is(type)) return false;
- GetInfo(node)->set_feedback_type(new_type);
+ info->set_unrestricted_feedback_type(unrestricted_feedback_type);
+ info->set_feedback_type(new_type);
if (FLAG_trace_representation) {
PrintNodeFeedbackType(node);
}
@@ -1106,22 +1123,6 @@ class RepresentationSelector {
return jsgraph_->simplified();
}
- void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
- Type* input0_type, Type* input1_type) {
- // If one of the inputs is positive and/or truncation is being applied,
- // there is no need to return -0.
- CheckForMinusZeroMode mz_mode =
- truncation.IsUsedAsWord32() ||
- (input0_type->Is(Type::OrderedNumber()) &&
- input0_type->Min() > 0) ||
- (input1_type->Is(Type::OrderedNumber()) &&
- input1_type->Min() > 0)
- ? CheckForMinusZeroMode::kDontCheckForMinusZero
- : CheckForMinusZeroMode::kCheckForMinusZero;
-
- NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
- }
-
void ChangeToInt32OverflowOp(Node* node) {
NodeProperties::ChangeOp(node, Int32OverflowOp(node));
}
@@ -1149,29 +1150,32 @@ class RepresentationSelector {
return;
}
- // 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) {
+ // We always take SignedSmall/Signed32 feedback otherwise.
+ NumberOperationHint const hint = NumberOperationHintOf(node->op());
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ // Check if we can guarantee truncations for the inputs.
+ if (BothInputsAre(node, Type::Signed32()) ||
+ (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
+ NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) {
VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
- return;
+ } else {
+ VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
+ MachineRepresentation::kWord32, Type::Signed32());
+ }
+ if (lower()) {
+ // Avoid overflow checks if the unrestricted feedback type of {node}
+ // suggests that the result will fit into Signed32/Unsigned32 range.
+ Type* const type = UnrestrictedFeedbackTypeOf(node);
+ if (type->Is(Type::Unsigned32())) {
+ ChangeToPureOp(node, Uint32Op(node));
+ } else if (type->Is(Type::Signed32())) {
+ ChangeToPureOp(node, Int32Op(node));
+ } else {
+ ChangeToInt32OverflowOp(node);
+ }
}
- }
-
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
return;
}
@@ -1181,7 +1185,6 @@ class RepresentationSelector {
if (lower()) {
ChangeToPureOp(node, Float64Op(node));
}
- return;
}
void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
@@ -1523,33 +1526,39 @@ class RepresentationSelector {
if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
- // Try to use type feedback.
- NumberOperationHint hint = NumberOperationHintOf(node->op());
- Type* input0_type = TypeOf(node->InputAt(0));
- Type* input1_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).
- if (BothInputsAre(node, Type::Signed32())) {
- // If both the inputs the feedback are int32, use the overflow op.
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
+ // We always take SignedSmall/Signed32 feedback otherwise.
+ NumberOperationHint const hint = NumberOperationHintOf(node->op());
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ // 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())) {
+ // If both the inputs the feedback are int32, use the overflow op.
VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) {
- LowerToCheckedInt32Mul(node, truncation, input0_type,
- input1_type);
- }
- return;
+ } else {
+ VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
+ MachineRepresentation::kWord32, Type::Signed32());
}
- }
-
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Signed32());
if (lower()) {
- LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
+ // Avoid overflow checks if the unrestricted feedback type of {node}
+ // suggests that the result will fit into Signed32/Unsigned32 range,
+ // or at least try to avoid the expensive minus zero checks.
+ Type* const type = UnrestrictedFeedbackTypeOf(node);
+ if (type->Is(Type::Unsigned32())) {
+ ChangeToPureOp(node, Uint32Op(node));
+ } else if (type->Is(Type::Signed32())) {
+ ChangeToPureOp(node, Int32Op(node));
+ } else {
+ CheckForMinusZeroMode const mode =
+ (truncation.IdentifiesMinusZeroAndZero() ||
+ !type->Maybe(Type::MinusZero()))
+ ? CheckForMinusZeroMode::kDontCheckForMinusZero
+ : CheckForMinusZeroMode::kCheckForMinusZero;
+ NodeProperties::ChangeOp(node,
+ simplified()->CheckedInt32Mul(mode));
+ }
}
return;
}
« no previous file with comments | « src/compiler/representation-change.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698