Commit 04b4df2c authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Extend undefined-to-number truncation to all oddballs.

Extends the truncation and type checks for NumberOrUndefined in
representation selection and truncation analysis to deal with all
oddballs not just undefined. Also extend the type hints to always
report NumberOrOddball. This is necessary for the bitwise and shift
operators where NUMBER feedback actually means NUMBER or ODDBALL.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2149583002
Cr-Commit-Position: refs/heads/master@{#37711}
parent 7ae653f7
......@@ -39,7 +39,7 @@ class JSBinopReduction final {
BinaryOperationHints::Hint combined = hints.combined();
if (combined == BinaryOperationHints::kSignedSmall ||
combined == BinaryOperationHints::kSigned32 ||
combined == BinaryOperationHints::kNumberOrUndefined) {
combined == BinaryOperationHints::kNumberOrOddball) {
return combined;
}
return BinaryOperationHints::kAny;
......@@ -56,7 +56,7 @@ class JSBinopReduction final {
CompareOperationHints hints = CompareOperationHintsOf(node_->op());
CompareOperationHints::Hint combined = hints.combined();
if (combined == CompareOperationHints::kSignedSmall ||
combined == CompareOperationHints::kNumber) {
combined == CompareOperationHints::kNumberOrOddball) {
return combined;
}
return CompareOperationHints::kAny;
......@@ -435,7 +435,7 @@ JSTypedLowering::JSTypedLowering(Editor* editor,
Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
JSBinopReduction r(this, node);
BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
if (feedback == BinaryOperationHints::kNumberOrUndefined &&
if (feedback == BinaryOperationHints::kNumberOrOddball &&
r.BothInputsAre(Type::PlainPrimitive()) &&
r.NeitherInputCanBe(Type::StringOrReceiver())) {
// JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
......@@ -486,7 +486,7 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
JSBinopReduction r(this, node);
BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
if (feedback == BinaryOperationHints::kNumberOrUndefined &&
if (feedback == BinaryOperationHints::kNumberOrOddball &&
r.BothInputsAre(Type::PlainPrimitive())) {
// JSSubtract(x:plain-primitive, y:plain-primitive)
// => NumberSubtract(ToNumber(x), ToNumber(y))
......@@ -533,7 +533,7 @@ Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
JSBinopReduction r(this, node);
BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
if (feedback == BinaryOperationHints::kNumberOrUndefined &&
if (feedback == BinaryOperationHints::kNumberOrOddball &&
r.BothInputsAre(Type::PlainPrimitive())) {
// JSDivide(x:plain-primitive,
// y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y))
......@@ -556,7 +556,7 @@ Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
JSBinopReduction r(this, node);
BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
if (feedback == BinaryOperationHints::kNumberOrUndefined &&
if (feedback == BinaryOperationHints::kNumberOrOddball &&
r.BothInputsAre(Type::PlainPrimitive())) {
// JSModulus(x:plain-primitive,
// y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y))
......
......@@ -63,6 +63,11 @@ Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
LessGeneral(rep2, TruncationKind::kFloat64)) {
return TruncationKind::kFloat64;
}
// Handle the generalization of any-representable values.
if (LessGeneral(rep1, TruncationKind::kAny) &&
LessGeneral(rep2, TruncationKind::kAny)) {
return TruncationKind::kAny;
}
// All other combinations are illegal.
FATAL("Tried to combine incompatible truncations");
return TruncationKind::kNone;
......@@ -278,7 +283,7 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
op = machine()->TruncateFloat64ToFloat32();
}
} else if (output_rep == MachineRepresentation::kTagged) {
if (output_type->Is(Type::NumberOrUndefined())) {
if (output_type->Is(Type::NumberOrOddball())) {
// tagged -> float64 -> float32
if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64();
......@@ -344,10 +349,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
op = machine()->ChangeInt32ToFloat64();
} else if (output_type->Is(Type::Number())) {
op = simplified()->ChangeTaggedToFloat64();
} else if (output_type->Is(Type::NumberOrUndefined())) {
} else if (output_type->Is(Type::NumberOrOddball())) {
// TODO(jarin) Here we should check that truncation is Number.
op = simplified()->TruncateTaggedToFloat64();
} else if (use_info.type_check() == TypeCheckKind::kNumberOrUndefined) {
} else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
op = simplified()->CheckedTaggedToFloat64();
}
} else if (output_rep == MachineRepresentation::kFloat32) {
......
......@@ -73,12 +73,7 @@ class Truncation final {
static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
};
enum class TypeCheckKind : uint8_t {
kNone,
kSigned32,
kNumberOrUndefined,
kNumber
};
enum class TypeCheckKind : uint8_t { kNone, kSigned32, kNumberOrOddball };
inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
switch (type_check) {
......@@ -86,10 +81,8 @@ inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
return os << "None";
case TypeCheckKind::kSigned32:
return os << "Signed32";
case TypeCheckKind::kNumberOrUndefined:
return os << "NumberOrUndefined";
case TypeCheckKind::kNumber:
return os << "Number";
case TypeCheckKind::kNumberOrOddball:
return os << "NumberOrOddball";
}
UNREACHABLE();
return os;
......@@ -141,9 +134,9 @@ class UseInfo {
return UseInfo(MachineRepresentation::kWord32, Truncation::Any(),
TypeCheckKind::kSigned32);
}
static UseInfo CheckedNumberOrUndefinedAsFloat64() {
static UseInfo CheckedNumberOrOddballAsFloat64() {
return UseInfo(MachineRepresentation::kFloat64, Truncation::Any(),
TypeCheckKind::kNumberOrUndefined);
TypeCheckKind::kNumberOrOddball);
}
// Undetermined representation.
......
......@@ -1130,7 +1130,7 @@ class RepresentationSelector {
}
// default case => Float64Add/Sub
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) {
ChangeToPureOp(node, Float64Op(node));
......@@ -1283,9 +1283,9 @@ class RepresentationSelector {
if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
DCHECK_EQ(CompareOperationHints::kNumber, hint);
DCHECK_EQ(CompareOperationHints::kNumberOrOddball, hint);
// default case => Float64 comparison
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kBit);
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
......@@ -1338,7 +1338,7 @@ class RepresentationSelector {
}
// Checked float64 x float64 => float64
DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode());
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
......@@ -1409,7 +1409,7 @@ class RepresentationSelector {
}
// default case => Float64Div
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
......@@ -1443,7 +1443,7 @@ class RepresentationSelector {
}
// Checked float64 x float64 => float64
DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode());
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
......@@ -1514,7 +1514,7 @@ class RepresentationSelector {
}
// default case => Float64Mod
VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(),
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
......@@ -1969,8 +1969,7 @@ class RepresentationSelector {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
if (lower()) lowering->DoStringToNumber(node);
} else if (truncation.TruncatesToWord32()) {
// TODO(jarin): Extend this to Number \/ Oddball
if (InputIs(node, Type::NumberOrUndefined())) {
if (InputIs(node, Type::NumberOrOddball())) {
VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, node->InputAt(0));
......@@ -1983,8 +1982,7 @@ class RepresentationSelector {
}
}
} else if (truncation.TruncatesToFloat64()) {
// TODO(jarin): Extend this to Number \/ Oddball
if (InputIs(node, Type::NumberOrUndefined())) {
if (InputIs(node, Type::NumberOrOddball())) {
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, node->InputAt(0));
......
......@@ -20,7 +20,7 @@ BinaryOperationHints::Hint ToBinaryOperationHint(Type* type) {
if (type->Is(Type::None())) return BinaryOperationHints::kNone;
if (type->Is(Type::SignedSmall())) return BinaryOperationHints::kSignedSmall;
if (type->Is(Type::Signed32())) return BinaryOperationHints::kSigned32;
if (type->Is(Type::Number())) return BinaryOperationHints::kNumberOrUndefined;
if (type->Is(Type::Number())) return BinaryOperationHints::kNumberOrOddball;
if (type->Is(Type::String())) return BinaryOperationHints::kString;
return BinaryOperationHints::kAny;
}
......@@ -35,7 +35,7 @@ CompareOperationHints::Hint ToCompareOperationHint(
case CompareICState::SMI:
return CompareOperationHints::kSignedSmall;
case CompareICState::NUMBER:
return CompareOperationHints::kNumber;
return CompareOperationHints::kNumberOrOddball;
case CompareICState::STRING:
return CompareOperationHints::kString;
case CompareICState::INTERNALIZED_STRING:
......
......@@ -16,8 +16,8 @@ std::ostream& operator<<(std::ostream& os, BinaryOperationHints::Hint hint) {
return os << "SignedSmall";
case BinaryOperationHints::kSigned32:
return os << "Signed32";
case BinaryOperationHints::kNumberOrUndefined:
return os << "NumberOrUndefined";
case BinaryOperationHints::kNumberOrOddball:
return os << "NumberOrOddball";
case BinaryOperationHints::kString:
return os << "String";
case BinaryOperationHints::kAny:
......@@ -39,8 +39,8 @@ std::ostream& operator<<(std::ostream& os, CompareOperationHints::Hint hint) {
return os << "Boolean";
case CompareOperationHints::kSignedSmall:
return os << "SignedSmall";
case CompareOperationHints::kNumber:
return os << "Number";
case CompareOperationHints::kNumberOrOddball:
return os << "NumberOrOddball";
case CompareOperationHints::kString:
return os << "String";
case CompareOperationHints::kInternalizedString:
......@@ -112,10 +112,10 @@ bool BinaryOperationHints::Is(Hint h1, Hint h2) {
case kNone:
return true;
case kSignedSmall:
return h2 == kSigned32 || h2 == kNumberOrUndefined || h2 == kAny;
return h2 == kSigned32 || h2 == kNumberOrOddball || h2 == kAny;
case kSigned32:
return h2 == kNumberOrUndefined || h2 == kAny;
case kNumberOrUndefined:
return h2 == kNumberOrOddball || h2 == kAny;
case kNumberOrOddball:
return h2 == kAny;
case kString:
return h2 == kAny;
......
......@@ -15,14 +15,7 @@ namespace compiler {
// Type hints for an binary operation.
class BinaryOperationHints final {
public:
enum Hint {
kNone,
kSignedSmall,
kSigned32,
kNumberOrUndefined,
kString,
kAny
};
enum Hint { kNone, kSignedSmall, kSigned32, kNumberOrOddball, kString, kAny };
BinaryOperationHints() : BinaryOperationHints(kNone, kNone, kNone) {}
BinaryOperationHints(Hint left, Hint right, Hint result)
......@@ -71,7 +64,7 @@ class CompareOperationHints final {
kNone,
kBoolean,
kSignedSmall,
kNumber,
kNumberOrOddball,
kString,
kInternalizedString,
kUniqueName,
......
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