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

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

Issue 2149493002: [turbofan] Introduce CheckedUint32Div and CheckUint32Mod operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comment Created 4 years, 5 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') | src/compiler/simplified-operator.h » ('j') | 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 cc7279ece0a0b3d2443d1188936e5eea22dde1ed..c9d592c282aae49ad57806111d54a3db16af8d5f 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -183,7 +183,7 @@ class InputUseInfos {
class RepresentationSelector {
public:
// Information for each node tracked during the fixpoint.
- class NodeInfo {
+ class NodeInfo final {
public:
// Adds new use to the node. Returns true if something has changed
// and the node has to be requeued.
@@ -207,11 +207,11 @@ class RepresentationSelector {
// Helpers for feedback typing.
void set_feedback_type(Type* type) { feedback_type_ = type; }
- Type* feedback_type() { return feedback_type_; }
+ Type* feedback_type() const { return feedback_type_; }
void set_weakened() { weakened_ = true; }
- bool weakened() { return weakened_; }
- TypeCheckKind type_check() { return type_check_; }
- void set_type_check(TypeCheckKind type_check) { type_check_ = type_check; }
+ bool weakened() const { return weakened_; }
+ void set_restriction_type(Type* type) { restriction_type_ = type; }
+ Type* restriction_type() const { return restriction_type_; }
private:
enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
@@ -219,8 +219,8 @@ class RepresentationSelector {
MachineRepresentation representation_ =
MachineRepresentation::kNone; // Output representation.
Truncation truncation_ = Truncation::None(); // Information about uses.
- TypeCheckKind type_check_ = TypeCheckKind::kNone; // Runtime check kind.
+ Type* restriction_type_ = Type::Any();
Type* feedback_type_ = nullptr;
bool weakened_ = false;
};
@@ -343,23 +343,6 @@ class RepresentationSelector {
FeedbackTypeOf(node->InputAt(2)));
}
- static Type* TypeOfSpeculativeOp(TypeCheckKind type_check) {
- switch (type_check) {
- case TypeCheckKind::kNone:
- return Type::Any();
- case TypeCheckKind::kSigned32:
- return Type::Signed32();
- case TypeCheckKind::kNumber:
- return Type::Number();
- // Unexpected cases.
- case TypeCheckKind::kNumberOrUndefined:
- FATAL("Unexpected checked type.");
- break;
- }
- UNREACHABLE();
- return nullptr;
- }
-
bool UpdateFeedbackType(Node* node) {
if (node->op()->ValueOutputCount() == 0) return false;
@@ -379,6 +362,7 @@ class RepresentationSelector {
}
switch (node->opcode()) {
+ case IrOpcode::kNumberAdd:
case IrOpcode::kSpeculativeNumberAdd: {
// TODO(jarin) The ToNumber conversion is too conservative here,
// e.g. it will treat true as 1 even though the number check will
@@ -386,16 +370,13 @@ class RepresentationSelector {
// computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
- Type* static_type = op_typer_.NumberAdd(lhs, rhs);
- if (info->type_check() == TypeCheckKind::kNone) {
- new_type = static_type;
- } else {
- Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
- new_type = Type::Intersect(static_type, feedback_type, graph_zone());
- }
+ Type* computed_type = op_typer_.NumberAdd(lhs, rhs);
+ new_type = Type::Intersect(computed_type, info->restriction_type(),
+ graph_zone());
break;
}
+ case IrOpcode::kNumberSubtract:
case IrOpcode::kSpeculativeNumberSubtract: {
// TODO(jarin) The ToNumber conversion is too conservative here,
// e.g. it will treat true as 1 even though the number check will
@@ -403,16 +384,13 @@ class RepresentationSelector {
// computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
- Type* static_type = op_typer_.NumberSubtract(lhs, rhs);
- if (info->type_check() == TypeCheckKind::kNone) {
- new_type = static_type;
- } else {
- Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
- new_type = Type::Intersect(static_type, feedback_type, graph_zone());
- }
+ Type* computed_type = op_typer_.NumberSubtract(lhs, rhs);
+ new_type = Type::Intersect(computed_type, info->restriction_type(),
+ graph_zone());
break;
}
+ case IrOpcode::kNumberMultiply:
case IrOpcode::kSpeculativeNumberMultiply: {
// TODO(jarin) The ToNumber conversion is too conservative here,
// e.g. it will treat true as 1 even though the number check will
@@ -420,16 +398,13 @@ class RepresentationSelector {
// computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
- Type* static_type = op_typer_.NumberMultiply(lhs, rhs);
- if (info->type_check() == TypeCheckKind::kNone) {
- new_type = static_type;
- } else {
- Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
- new_type = Type::Intersect(static_type, feedback_type, graph_zone());
- }
+ Type* computed_type = op_typer_.NumberMultiply(lhs, rhs);
+ new_type = Type::Intersect(computed_type, info->restriction_type(),
+ graph_zone());
break;
}
+ case IrOpcode::kNumberDivide:
case IrOpcode::kSpeculativeNumberDivide: {
// TODO(jarin) The ToNumber conversion is too conservative here,
// e.g. it will treat true as 1 even though the number check will
@@ -437,16 +412,13 @@ class RepresentationSelector {
// computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
- Type* static_type = op_typer_.NumberDivide(lhs, rhs);
- if (info->type_check() == TypeCheckKind::kNone) {
- new_type = static_type;
- } else {
- Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
- new_type = Type::Intersect(static_type, feedback_type, graph_zone());
- }
+ Type* computed_type = op_typer_.NumberDivide(lhs, rhs);
+ new_type = Type::Intersect(computed_type, info->restriction_type(),
+ graph_zone());
break;
}
+ case IrOpcode::kNumberModulus:
case IrOpcode::kSpeculativeNumberModulus: {
// TODO(jarin) The ToNumber conversion is too conservative here,
// e.g. it will treat true as 1 even though the number check will
@@ -454,13 +426,9 @@ class RepresentationSelector {
// computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
- Type* static_type = op_typer_.NumberModulus(lhs, rhs);
- if (info->type_check() == TypeCheckKind::kNone) {
- new_type = static_type;
- } else {
- Type* feedback_type = TypeOfSpeculativeOp(info->type_check());
- new_type = Type::Intersect(static_type, feedback_type, graph_zone());
- }
+ Type* computed_type = op_typer_.NumberModulus(lhs, rhs);
+ new_type = Type::Intersect(computed_type, info->restriction_type(),
+ graph_zone());
break;
}
@@ -657,30 +625,25 @@ class RepresentationSelector {
bool propagate() const { return phase_ == PROPAGATE; }
void SetOutput(Node* node, MachineRepresentation representation,
- TypeCheckKind type_check = TypeCheckKind::kNone) {
+ Type* restriction_type = Type::Any()) {
NodeInfo* const info = GetInfo(node);
switch (phase_) {
case PROPAGATE:
- info->set_type_check(type_check);
+ info->set_restriction_type(restriction_type);
break;
case RETYPE:
- DCHECK_EQ(info->type_check(), type_check);
+ DCHECK(info->restriction_type()->Is(restriction_type));
+ DCHECK(restriction_type->Is(info->restriction_type()));
info->set_output(representation);
break;
case LOWER:
- DCHECK_EQ(info->type_check(), type_check);
DCHECK_EQ(info->representation(), representation);
+ DCHECK(info->restriction_type()->Is(restriction_type));
+ DCHECK(restriction_type->Is(info->restriction_type()));
break;
}
}
- void ResetOutput(Node* node, MachineRepresentation representation,
- TypeCheckKind type_check = TypeCheckKind::kNone) {
- NodeInfo* info = GetInfo(node);
- info->set_output(representation);
- info->set_type_check(type_check);
- }
-
Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
bool InputCannotBe(Node* node, Type* type) {
@@ -777,20 +740,20 @@ class RepresentationSelector {
// Helper for binops of the R x L -> O variety.
void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
MachineRepresentation output,
- TypeCheckKind type_check = TypeCheckKind::kNone) {
+ Type* restriction_type = Type::Any()) {
DCHECK_EQ(2, node->op()->ValueInputCount());
ProcessInput(node, 0, left_use);
ProcessInput(node, 1, right_use);
for (int i = 2; i < node->InputCount(); i++) {
EnqueueInput(node, i);
}
- SetOutput(node, output, type_check);
+ SetOutput(node, output, restriction_type);
}
// Helper for binops of the I x I -> O variety.
void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
- TypeCheckKind type_check = TypeCheckKind::kNone) {
- VisitBinop(node, input_use, input_use, output, type_check);
+ Type* restriction_type = Type::Any()) {
+ VisitBinop(node, input_use, input_use, output, restriction_type);
}
// Helper for unops of the I -> O variety.
@@ -1006,6 +969,10 @@ class RepresentationSelector {
return changer_->Uint32OperatorFor(node->opcode());
}
+ const Operator* Uint32OverflowOp(Node* node) {
+ return changer_->Uint32OverflowOperatorFor(node->opcode());
+ }
+
const Operator* Float64Op(Node* node) {
return changer_->Float64OperatorFor(node->opcode());
}
@@ -1108,8 +1075,12 @@ class RepresentationSelector {
NodeProperties::ChangeOp(node, new_op);
}
- void ChangeToInt32OverflowOp(Node* node, const Operator* new_op) {
- NodeProperties::ChangeOp(node, new_op);
+ void ChangeToInt32OverflowOp(Node* node) {
+ NodeProperties::ChangeOp(node, Int32OverflowOp(node));
+ }
+
+ void ChangeToUint32OverflowOp(Node* node) {
+ NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
}
void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
@@ -1144,10 +1115,8 @@ class RepresentationSelector {
if (hint == BinaryOperationHints::kSignedSmall ||
hint == BinaryOperationHints::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32, TypeCheckKind::kSigned32);
- if (lower()) {
- ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
- }
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
return;
}
}
@@ -1155,16 +1124,14 @@ class RepresentationSelector {
if (hint == BinaryOperationHints::kSignedSmall ||
hint == BinaryOperationHints::kSigned32) {
VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
- MachineRepresentation::kWord32, TypeCheckKind::kSigned32);
- if (lower()) {
- ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
- }
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
return;
}
// default case => Float64Add/Sub
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
- MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ MachineRepresentation::kFloat64, Type::Number());
if (lower()) {
ChangeToPureOp(node, Float64Op(node));
}
@@ -1348,24 +1315,20 @@ class RepresentationSelector {
}
case IrOpcode::kSpeculativeNumberMultiply:
case IrOpcode::kNumberMultiply: {
- if (BothInputsAreSigned32(node)) {
- if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
- // Multiply reduces to Int32Mul if the inputs and the output
- // are integers.
- VisitInt32Binop(node);
- if (lower()) ChangeToPureOp(node, Int32Op(node));
- return;
- }
- if (truncation.TruncatesToWord32() &&
+ if (BothInputsAre(node, Type::Integral32()) &&
+ (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
+ NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
+ (truncation.TruncatesToWord32() &&
NodeProperties::GetType(node)->Is(
- type_cache_.kSafeIntegerOrMinusZero)) {
- // Multiply reduces to Int32Mul if the inputs are integers,
- // the uses are truncating and the result is in the safe
- // integer range.
- VisitWord32TruncatingBinop(node);
- if (lower()) ChangeToPureOp(node, Int32Op(node));
- return;
- }
+ type_cache_.kSafeIntegerOrMinusZero)))) {
+ // Multiply reduces to Int32Mul if the inputs are integers, and
+ // (a) the output is either known to be Signed32, or
+ // (b) the output is known to be Unsigned32, or
+ // (c) the uses are truncating and the result is in the safe
+ // integer range.
+ VisitWord32TruncatingBinop(node);
+ if (lower()) ChangeToPureOp(node, Int32Op(node));
+ return;
}
// Number x Number => Float64Mul
if (BothInputsAre(node, Type::NumberOrUndefined())) {
@@ -1376,7 +1339,7 @@ class RepresentationSelector {
// Checked float64 x float64 => float64
DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode());
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
- MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
@@ -1405,16 +1368,27 @@ class RepresentationSelector {
// Try to use type feedback.
BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op());
+ // Handle the case when no uint32 checks on inputs are necessary
+ // (but an overflow check is needed on the output).
+ if (BothInputsAreUnsigned32(node)) {
+ if (hint == BinaryOperationHints::kSignedSmall ||
+ hint == BinaryOperationHints::kSigned32) {
+ VisitBinop(node, UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32, Type::Unsigned32());
+ if (lower()) ChangeToUint32OverflowOp(node);
+ return;
+ }
+ }
+
// 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 (BothInputsAreSigned32(node)) {
// If both the inputs the feedback are int32, use the overflow op.
if (hint == BinaryOperationHints::kSignedSmall ||
hint == BinaryOperationHints::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32,
- TypeCheckKind::kSigned32);
- if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
return;
}
}
@@ -1428,16 +1402,15 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, lowering->Int32Div(node));
} else {
VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
- MachineRepresentation::kWord32,
- TypeCheckKind::kSigned32);
- if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
}
return;
}
// default case => Float64Div
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
- MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
@@ -1471,7 +1444,7 @@ class RepresentationSelector {
// Checked float64 x float64 => float64
DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode());
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
- MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
@@ -1500,6 +1473,18 @@ class RepresentationSelector {
// Try to use type feedback.
BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op());
+ // Handle the case when no uint32 checks on inputs are necessary
+ // (but an overflow check is needed on the output).
+ if (BothInputsAreUnsigned32(node)) {
+ if (hint == BinaryOperationHints::kSignedSmall ||
+ hint == BinaryOperationHints::kSigned32) {
+ VisitBinop(node, UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32, Type::Unsigned32());
+ if (lower()) ChangeToUint32OverflowOp(node);
+ return;
+ }
+ }
+
// 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())) {
@@ -1507,9 +1492,8 @@ class RepresentationSelector {
if (hint == BinaryOperationHints::kSignedSmall ||
hint == BinaryOperationHints::kSigned32) {
VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32,
- TypeCheckKind::kSigned32);
- if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
return;
}
}
@@ -1523,16 +1507,15 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
} else {
VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
- MachineRepresentation::kWord32,
- TypeCheckKind::kSigned32);
- if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node));
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
}
return;
}
// default case => Float64Mod
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
- MachineRepresentation::kFloat64, TypeCheckKind::kNumber);
+ MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
« no previous file with comments | « src/compiler/representation-change.cc ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698