Commit b93cde37 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Allow non-speculative operators to consume feedback types.

Turn the retyping pass of SimplifiedLowering into a proper phase, and
make it possible to propagate feedback types through non-speculative
operators. This defers the output representation selection to the
retyping phase, and checks that we don't mess up.

As a first user, we consume input type feedback for NumberAbs as well.
Long-term we can add all other operators to the mix.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2139203002
Cr-Commit-Position: refs/heads/master@{#37672}
parent b571026f
...@@ -285,7 +285,7 @@ Type* OperationTyper::ToNumber(Type* type) { ...@@ -285,7 +285,7 @@ Type* OperationTyper::ToNumber(Type* type) {
return Type::Number(); return Type::Number();
} }
Type* OperationTyper::NumericAdd(Type* lhs, Type* rhs) { Type* OperationTyper::NumberAdd(Type* lhs, Type* rhs) {
DCHECK(lhs->Is(Type::Number())); DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number())); DCHECK(rhs->Is(Type::Number()));
...@@ -311,7 +311,7 @@ Type* OperationTyper::NumericAdd(Type* lhs, Type* rhs) { ...@@ -311,7 +311,7 @@ Type* OperationTyper::NumericAdd(Type* lhs, Type* rhs) {
return result; return result;
} }
Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) { Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) {
DCHECK(lhs->Is(Type::Number())); DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number())); DCHECK(rhs->Is(Type::Number()));
...@@ -329,7 +329,7 @@ Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) { ...@@ -329,7 +329,7 @@ Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) {
return Type::Number(); return Type::Number();
} }
Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) { Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) {
DCHECK(lhs->Is(Type::Number())); DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number())); DCHECK(rhs->Is(Type::Number()));
...@@ -346,7 +346,7 @@ Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) { ...@@ -346,7 +346,7 @@ Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) {
return Type::Number(); return Type::Number();
} }
Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) { Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
DCHECK(lhs->Is(Type::Number())); DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number())); DCHECK(rhs->Is(Type::Number()));
...@@ -363,7 +363,7 @@ Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) { ...@@ -363,7 +363,7 @@ Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) {
return maybe_nan ? Type::Number() : Type::OrderedNumber(); return maybe_nan ? Type::Number() : Type::OrderedNumber();
} }
Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) { Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) {
DCHECK(lhs->Is(Type::Number())); DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number())); DCHECK(rhs->Is(Type::Number()));
...@@ -387,6 +387,34 @@ Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) { ...@@ -387,6 +387,34 @@ Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) {
return Type::OrderedNumber(); return Type::OrderedNumber();
} }
Type* OperationTyper::NumberAbs(Type* type) {
DCHECK(type->Is(Type::Number()));
if (!type->IsInhabited()) {
return Type::None();
}
bool const maybe_nan = type->Maybe(Type::NaN());
bool const maybe_minuszero = type->Maybe(Type::MinusZero());
type = Type::Intersect(type, Type::PlainNumber(), zone());
double const max = type->Max();
double const min = type->Min();
if (min < 0) {
if (type->Is(cache_.kInteger)) {
type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone());
} else {
type = Type::PlainNumber();
}
}
if (maybe_minuszero) {
type = Type::Union(type, cache_.kSingletonZero, zone());
}
if (maybe_nan) {
type = Type::Union(type, Type::NaN(), zone());
}
return type;
}
Type* OperationTyper::ToPrimitive(Type* type) { Type* OperationTyper::ToPrimitive(Type* type) {
if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
return type; return type;
...@@ -439,11 +467,11 @@ Type* OperationTyper::TypeJSAdd(Type* lhs, Type* rhs) { ...@@ -439,11 +467,11 @@ Type* OperationTyper::TypeJSAdd(Type* lhs, Type* rhs) {
} }
lhs = ToNumber(lhs); lhs = ToNumber(lhs);
rhs = ToNumber(rhs); rhs = ToNumber(rhs);
return NumericAdd(lhs, rhs); return NumberAdd(lhs, rhs);
} }
Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) { Type* OperationTyper::TypeJSSubtract(Type* lhs, Type* rhs) {
return NumericSubtract(ToNumber(lhs), ToNumber(rhs)); return NumberSubtract(ToNumber(lhs), ToNumber(rhs));
} }
} // namespace compiler } // namespace compiler
......
...@@ -32,11 +32,13 @@ class OperationTyper { ...@@ -32,11 +32,13 @@ class OperationTyper {
Type* ToNumber(Type* type); Type* ToNumber(Type* type);
Type* WeakenRange(Type* current_range, Type* previous_range); Type* WeakenRange(Type* current_range, Type* previous_range);
Type* NumericAdd(Type* lhs, Type* rhs); Type* NumberAdd(Type* lhs, Type* rhs);
Type* NumericSubtract(Type* lhs, Type* rhs); Type* NumberSubtract(Type* lhs, Type* rhs);
Type* NumericMultiply(Type* lhs, Type* rhs); Type* NumberMultiply(Type* lhs, Type* rhs);
Type* NumericDivide(Type* lhs, Type* rhs); Type* NumberDivide(Type* lhs, Type* rhs);
Type* NumericModulus(Type* lhs, Type* rhs); Type* NumberModulus(Type* lhs, Type* rhs);
Type* NumberAbs(Type* type);
enum ComparisonOutcomeFlags { enum ComparisonOutcomeFlags {
kComparisonTrue = 1, kComparisonTrue = 1,
......
...@@ -80,6 +80,21 @@ enum class TypeCheckKind : uint8_t { ...@@ -80,6 +80,21 @@ enum class TypeCheckKind : uint8_t {
kNumber kNumber
}; };
inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
switch (type_check) {
case TypeCheckKind::kNone:
return os << "None";
case TypeCheckKind::kSigned32:
return os << "Signed32";
case TypeCheckKind::kNumberOrUndefined:
return os << "NumberOrUndefined";
case TypeCheckKind::kNumber:
return os << "Number";
}
UNREACHABLE();
return os;
}
// The {UseInfo} class is used to describe a use of an input of a node. // The {UseInfo} class is used to describe a use of an input of a node.
// //
// This information is used in two different ways, based on the phase: // This information is used in two different ways, based on the phase:
......
...@@ -51,7 +51,10 @@ enum Phase { ...@@ -51,7 +51,10 @@ enum Phase {
// the next phase can begin. // the next phase can begin.
PROPAGATE, PROPAGATE,
// 2.) LOWER: perform lowering for all {Simplified} nodes by replacing some // 2.) RETYPE: Propagate types from type feedback forwards.
RETYPE,
// 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
// operators for some nodes, expanding some nodes to multiple nodes, or // operators for some nodes, expanding some nodes to multiple nodes, or
// removing some (redundant) nodes. // removing some (redundant) nodes.
// During this phase, use the {RepresentationChanger} to insert // During this phase, use the {RepresentationChanger} to insert
...@@ -60,7 +63,6 @@ enum Phase { ...@@ -60,7 +63,6 @@ enum Phase {
LOWER LOWER
}; };
namespace { namespace {
...@@ -246,8 +248,12 @@ class RepresentationSelector { ...@@ -246,8 +248,12 @@ class RepresentationSelector {
// Forward propagation of types from type feedback. // Forward propagation of types from type feedback.
void RunTypePropagationPhase() { void RunTypePropagationPhase() {
DCHECK(typing_stack_.empty()); // Run type propagation.
TRACE("--{Type propagation phase}--\n");
phase_ = RETYPE;
ResetNodeInfoState();
DCHECK(typing_stack_.empty());
typing_stack_.push({graph()->end(), 0}); typing_stack_.push({graph()->end(), 0});
GetInfo(graph()->end())->set_pushed(); GetInfo(graph()->end())->set_pushed();
while (!typing_stack_.empty()) { while (!typing_stack_.empty()) {
...@@ -274,6 +280,8 @@ class RepresentationSelector { ...@@ -274,6 +280,8 @@ class RepresentationSelector {
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
info->set_visited(); info->set_visited();
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr);
if (updated) { if (updated) {
for (Node* const user : node->uses()) { for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
...@@ -291,6 +299,8 @@ class RepresentationSelector { ...@@ -291,6 +299,8 @@ class RepresentationSelector {
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
info->set_visited(); info->set_visited();
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr);
if (updated) { if (updated) {
for (Node* const user : node->uses()) { for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
...@@ -376,7 +386,7 @@ class RepresentationSelector { ...@@ -376,7 +386,7 @@ class RepresentationSelector {
// computes a more precise type. // computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
Type* static_type = op_typer_.NumericAdd(lhs, rhs); Type* static_type = op_typer_.NumberAdd(lhs, rhs);
if (info->type_check() == TypeCheckKind::kNone) { if (info->type_check() == TypeCheckKind::kNone) {
new_type = static_type; new_type = static_type;
} else { } else {
...@@ -393,7 +403,7 @@ class RepresentationSelector { ...@@ -393,7 +403,7 @@ class RepresentationSelector {
// computes a more precise type. // computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
Type* static_type = op_typer_.NumericSubtract(lhs, rhs); Type* static_type = op_typer_.NumberSubtract(lhs, rhs);
if (info->type_check() == TypeCheckKind::kNone) { if (info->type_check() == TypeCheckKind::kNone) {
new_type = static_type; new_type = static_type;
} else { } else {
...@@ -410,7 +420,7 @@ class RepresentationSelector { ...@@ -410,7 +420,7 @@ class RepresentationSelector {
// computes a more precise type. // computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
Type* static_type = op_typer_.NumericMultiply(lhs, rhs); Type* static_type = op_typer_.NumberMultiply(lhs, rhs);
if (info->type_check() == TypeCheckKind::kNone) { if (info->type_check() == TypeCheckKind::kNone) {
new_type = static_type; new_type = static_type;
} else { } else {
...@@ -427,7 +437,7 @@ class RepresentationSelector { ...@@ -427,7 +437,7 @@ class RepresentationSelector {
// computes a more precise type. // computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
Type* static_type = op_typer_.NumericDivide(lhs, rhs); Type* static_type = op_typer_.NumberDivide(lhs, rhs);
if (info->type_check() == TypeCheckKind::kNone) { if (info->type_check() == TypeCheckKind::kNone) {
new_type = static_type; new_type = static_type;
} else { } else {
...@@ -444,7 +454,7 @@ class RepresentationSelector { ...@@ -444,7 +454,7 @@ class RepresentationSelector {
// computes a more precise type. // computes a more precise type.
Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1)));
Type* static_type = op_typer_.NumericModulus(lhs, rhs); Type* static_type = op_typer_.NumberModulus(lhs, rhs);
if (info->type_check() == TypeCheckKind::kNone) { if (info->type_check() == TypeCheckKind::kNone) {
new_type = static_type; new_type = static_type;
} else { } else {
...@@ -454,24 +464,21 @@ class RepresentationSelector { ...@@ -454,24 +464,21 @@ class RepresentationSelector {
break; break;
} }
case IrOpcode::kNumberAbs: {
new_type = op_typer_.NumberAbs(FeedbackTypeOf(node->InputAt(0)));
break;
}
case IrOpcode::kPhi: { case IrOpcode::kPhi: {
new_type = TypePhi(node); new_type = TypePhi(node);
if (type != nullptr) { if (type != nullptr) {
new_type = Weaken(node, type, new_type); new_type = Weaken(node, type, new_type);
} }
// Recompute the phi representation based on the new type.
MachineRepresentation output =
GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
ResetOutput(node, output);
break; break;
} }
case IrOpcode::kSelect: { case IrOpcode::kSelect: {
new_type = TypeSelect(node); new_type = TypeSelect(node);
// Recompute representation based on the new type.
MachineRepresentation output =
GetOutputInfoForPhi(node, GetInfo(node)->truncation(), new_type);
ResetOutput(node, output);
break; break;
} }
...@@ -569,8 +576,6 @@ class RepresentationSelector { ...@@ -569,8 +576,6 @@ class RepresentationSelector {
void Run(SimplifiedLowering* lowering) { void Run(SimplifiedLowering* lowering) {
RunTruncationPropagationPhase(); RunTruncationPropagationPhase();
// Run type propagation.
ResetNodeInfoState();
RunTypePropagationPhase(); RunTypePropagationPhase();
// Run lowering and change insertion phase. // Run lowering and change insertion phase.
...@@ -647,14 +652,26 @@ class RepresentationSelector { ...@@ -647,14 +652,26 @@ class RepresentationSelector {
} }
} }
bool lower() { return phase_ == LOWER; } bool lower() const { return phase_ == LOWER; }
bool propagate() { return phase_ == PROPAGATE; } bool retype() const { return phase_ == RETYPE; }
bool propagate() const { return phase_ == PROPAGATE; }
void SetOutput(Node* node, MachineRepresentation representation, void SetOutput(Node* node, MachineRepresentation representation,
TypeCheckKind type_check = TypeCheckKind::kNone) { TypeCheckKind type_check = TypeCheckKind::kNone) {
DCHECK(MachineRepresentationIsSubtype(GetInfo(node)->representation(), NodeInfo* const info = GetInfo(node);
representation)); switch (phase_) {
ResetOutput(node, representation, type_check); case PROPAGATE:
info->set_type_check(type_check);
break;
case RETYPE:
DCHECK_EQ(info->type_check(), type_check);
info->set_output(representation);
break;
case LOWER:
DCHECK_EQ(info->type_check(), type_check);
DCHECK_EQ(info->representation(), representation);
break;
}
} }
void ResetOutput(Node* node, MachineRepresentation representation, void ResetOutput(Node* node, MachineRepresentation representation,
...@@ -715,10 +732,15 @@ class RepresentationSelector { ...@@ -715,10 +732,15 @@ class RepresentationSelector {
} }
void ProcessInput(Node* node, int index, UseInfo use) { void ProcessInput(Node* node, int index, UseInfo use) {
if (phase_ == PROPAGATE) { switch (phase_) {
EnqueueInput(node, index, use); case PROPAGATE:
} else { EnqueueInput(node, index, use);
ConvertInput(node, index, use); break;
case RETYPE:
break;
case LOWER:
ConvertInput(node, index, use);
break;
} }
} }
...@@ -827,12 +849,9 @@ class RepresentationSelector { ...@@ -827,12 +849,9 @@ class RepresentationSelector {
} }
// Infer representation for phi-like nodes. // Infer representation for phi-like nodes.
MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use, MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) {
Type* type = nullptr) {
// Compute the representation. // Compute the representation.
if (type == nullptr) { Type* type = TypeOf(node);
type = TypeOf(node);
}
if (type->Is(Type::None())) { if (type->Is(Type::None())) {
return MachineRepresentation::kNone; return MachineRepresentation::kNone;
} else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
...@@ -949,11 +968,11 @@ class RepresentationSelector { ...@@ -949,11 +968,11 @@ class RepresentationSelector {
} }
void VisitStateValues(Node* node) { void VisitStateValues(Node* node) {
if (phase_ == PROPAGATE) { if (propagate()) {
for (int i = 0; i < node->InputCount(); i++) { for (int i = 0; i < node->InputCount(); i++) {
EnqueueInput(node, i, UseInfo::Any()); EnqueueInput(node, i, UseInfo::Any());
} }
} else { } else if (lower()) {
Zone* zone = jsgraph_->zone(); Zone* zone = jsgraph_->zone();
ZoneVector<MachineType>* types = ZoneVector<MachineType>* types =
new (zone->New(sizeof(ZoneVector<MachineType>))) new (zone->New(sizeof(ZoneVector<MachineType>)))
...@@ -1578,16 +1597,16 @@ class RepresentationSelector { ...@@ -1578,16 +1597,16 @@ class RepresentationSelector {
return; return;
} }
case IrOpcode::kNumberAbs: { case IrOpcode::kNumberAbs: {
if (InputIs(node, Type::Unsigned32())) { if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32())) {
VisitUnop(node, UseInfo::TruncatingWord32(), VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else if (InputIs(node, Type::Signed32())) { } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32())) {
VisitUnop(node, UseInfo::TruncatingWord32(), VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, lowering->Int32Abs(node)); if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
} else if (InputIs(node, } else if (TypeOf(node->InputAt(0))
type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) { ->Is(type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) {
VisitUnop(node, UseInfo::TruncatingFloat64(), VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64); MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
......
...@@ -254,7 +254,6 @@ class Typer::Visitor : public Reducer { ...@@ -254,7 +254,6 @@ class Typer::Visitor : public Reducer {
static Type* ToNumber(Type*, Typer*); static Type* ToNumber(Type*, Typer*);
static Type* ToObject(Type*, Typer*); static Type* ToObject(Type*, Typer*);
static Type* ToString(Type*, Typer*); static Type* ToString(Type*, Typer*);
static Type* NumberAbs(Type*, Typer*);
static Type* NumberCeil(Type*, Typer*); static Type* NumberCeil(Type*, Typer*);
static Type* NumberFloor(Type*, Typer*); static Type* NumberFloor(Type*, Typer*);
static Type* NumberRound(Type*, Typer*); static Type* NumberRound(Type*, Typer*);
...@@ -491,34 +490,6 @@ Type* Typer::Visitor::ToString(Type* type, Typer* t) { ...@@ -491,34 +490,6 @@ Type* Typer::Visitor::ToString(Type* type, Typer* t) {
return Type::String(); return Type::String();
} }
// static
Type* Typer::Visitor::NumberAbs(Type* type, Typer* t) {
DCHECK(type->Is(Type::Number()));
Factory* const f = t->isolate()->factory();
bool const maybe_nan = type->Maybe(Type::NaN());
bool const maybe_minuszero = type->Maybe(Type::MinusZero());
type = Type::Intersect(type, Type::PlainNumber(), t->zone());
double const max = type->Max();
double const min = type->Min();
if (min < 0) {
if (type->Is(t->cache_.kInteger)) {
type =
Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), t->zone());
} else if (min == max) {
type = Type::Constant(f->NewNumber(std::fabs(min)), t->zone());
} else {
type = Type::PlainNumber();
}
}
if (maybe_minuszero) {
type = Type::Union(type, t->cache_.kSingletonZero, t->zone());
}
if (maybe_nan) {
type = Type::Union(type, Type::NaN(), t->zone());
}
return type;
}
// static // static
Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) {
DCHECK(type->Is(Type::Number())); DCHECK(type->Is(Type::Number()));
...@@ -1055,36 +1026,26 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { ...@@ -1055,36 +1026,26 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
} }
} }
// The addition must be numeric. // The addition must be numeric.
return t->operation_typer()->NumericAdd(ToNumber(lhs, t), ToNumber(rhs, t)); return t->operation_typer()->NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t));
} }
Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
return t->operation_typer()->NumericSubtract(ToNumber(lhs, t), return t->operation_typer()->NumberSubtract(ToNumber(lhs, t),
ToNumber(rhs, t)); ToNumber(rhs, t));
} }
Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
return t->operation_typer()->NumericMultiply(ToNumber(lhs, t), return t->operation_typer()->NumberMultiply(ToNumber(lhs, t),
ToNumber(rhs, t)); ToNumber(rhs, t));
} }
Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
return t->operation_typer()->NumericDivide(ToNumber(lhs, t), return t->operation_typer()->NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t));
ToNumber(rhs, t));
lhs = ToNumber(lhs, t);
rhs = ToNumber(rhs, t);
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
// Division is tricky, so all we do is try ruling out nan.
bool maybe_nan =
lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
(rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
return maybe_nan ? Type::Number() : Type::OrderedNumber();
} }
Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
return t->operation_typer()->NumericModulus(ToNumber(lhs, t), return t->operation_typer()->NumberModulus(ToNumber(lhs, t),
ToNumber(rhs, t)); ToNumber(rhs, t));
} }
...@@ -1645,7 +1606,7 @@ Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { ...@@ -1645,7 +1606,7 @@ Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); }
Type* Typer::Visitor::TypeNumberAbs(Node* node) { Type* Typer::Visitor::TypeNumberAbs(Node* node) {
return TypeUnaryOp(node, NumberAbs); return typer_->operation_typer()->NumberAbs(Operand(node, 0));
} }
Type* Typer::Visitor::TypeNumberClz32(Node* node) { Type* Typer::Visitor::TypeNumberClz32(Node* node) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment