Commit 0298df88 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Add feedback to CheckSmi

This change is quite invasive, because CheckSmi is lowered
through representation change depending on UseInfo to several
different checked conversion operators. This CL adds feedback
to every checked conversion operator to Int32.

Bug: v8:7127, v8:7204
Change-Id: Icb780e5a69d321c2ec161c3c2a32984bdcf101f1
Reviewed-on: https://chromium-review.googlesource.com/831521Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50167}
parent d69b2df9
......@@ -2575,7 +2575,7 @@ void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
PrepareEagerCheckpoint();
Node* acc = environment()->LookupAccumulator();
Node* acc_smi = NewNode(simplified()->CheckSmi(), acc);
Node* acc_smi = NewNode(simplified()->CheckSmi(VectorSlotPair()), acc);
BuildSwitchOnSmi(acc_smi);
}
......
......@@ -1787,10 +1787,11 @@ Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
Node* node, Node* frame_state) {
DCHECK(SmiValuesAre31Bits());
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* add = __ Int32AddWithOverflow(value, value);
Node* check = __ Projection(1, add);
__ DeoptimizeIf(DeoptimizeReason::kOverflow, VectorSlotPair(), check,
__ DeoptimizeIf(DeoptimizeReason::kOverflow, params.feedback(), check,
frame_state);
return __ Projection(0, add);
}
......@@ -1798,8 +1799,9 @@ Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(
Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
Node* frame_state) {
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* unsafe = __ Int32LessThan(value, __ Int32Constant(0));
__ DeoptimizeIf(DeoptimizeReason::kLostPrecision, VectorSlotPair(), unsafe,
__ DeoptimizeIf(DeoptimizeReason::kLostPrecision, params.feedback(), unsafe,
frame_state);
return value;
}
......@@ -1807,17 +1809,19 @@ Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node,
Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(
Node* node, Node* frame_state) {
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant());
__ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, VectorSlotPair(), check,
__ DeoptimizeIfNot(DeoptimizeReason::kLostPrecision, params.feedback(), check,
frame_state);
return ChangeUint32ToSmi(value);
}
Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
CheckForMinusZeroMode mode, Node* value, Node* frame_state) {
CheckForMinusZeroMode mode, const VectorSlotPair& feedback, Node* value,
Node* frame_state) {
Node* value32 = __ RoundFloat64ToInt32(value);
Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32));
__ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, VectorSlotPair(),
__ DeoptimizeIfNot(DeoptimizeReason::kLostPrecisionOrNaN, feedback,
check_same, frame_state);
if (mode == CheckForMinusZeroMode::kCheckForMinusZero) {
......@@ -1833,8 +1837,8 @@ Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value),
__ Int32Constant(0));
__ DeoptimizeIf(DeoptimizeReason::kMinusZero, VectorSlotPair(),
check_negative, frame_state);
__ DeoptimizeIf(DeoptimizeReason::kMinusZero, feedback, check_negative,
frame_state);
__ Goto(&check_done);
__ Bind(&check_done);
......@@ -1844,23 +1848,27 @@ Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32(
Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node,
Node* frame_state) {
CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
const CheckMinusZeroParameters& params =
CheckMinusZeroParametersOf(node->op());
Node* value = node->InputAt(0);
return BuildCheckedFloat64ToInt32(mode, value, frame_state);
return BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), value,
frame_state);
}
Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(
Node* node, Node* frame_state) {
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* check = ObjectIsSmi(value);
__ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, VectorSlotPair(), check,
__ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
frame_state);
return ChangeSmiToInt32(value);
}
Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
Node* frame_state) {
CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op());
const CheckMinusZeroParameters& params =
CheckMinusZeroParametersOf(node->op());
Node* value = node->InputAt(0);
auto if_not_smi = __ MakeDeferredLabel();
......@@ -1876,10 +1884,11 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
__ Bind(&if_not_smi);
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant());
__ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, VectorSlotPair(),
__ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, params.feedback(),
check_map, frame_state);
Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value);
vfalse = BuildCheckedFloat64ToInt32(mode, vfalse, frame_state);
vfalse = BuildCheckedFloat64ToInt32(params.mode(), params.feedback(), vfalse,
frame_state);
__ Goto(&done, vfalse);
__ Bind(&done);
......@@ -1887,12 +1896,13 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node,
}
Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
CheckTaggedInputMode mode, Node* value, Node* frame_state) {
CheckTaggedInputMode mode, const VectorSlotPair& feedback, Node* value,
Node* frame_state) {
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant());
switch (mode) {
case CheckTaggedInputMode::kNumber: {
__ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, VectorSlotPair(),
__ DeoptimizeIfNot(DeoptimizeReason::kNotAHeapNumber, feedback,
check_number, frame_state);
break;
}
......@@ -1906,8 +1916,8 @@ Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64(
__ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
Node* check_oddball =
__ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE));
__ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball,
VectorSlotPair(), check_oddball, frame_state);
__ DeoptimizeIfNot(DeoptimizeReason::kNotANumberOrOddball, feedback,
check_oddball, frame_state);
STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
__ Goto(&check_done);
......@@ -1931,8 +1941,8 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
// In the Smi case, just convert to int32 and then float64.
// Otherwise, check heap numberness and load the number.
Node* number =
BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state);
Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
mode, VectorSlotPair(), value, frame_state);
__ Goto(&done, number);
__ Bind(&if_smi);
......@@ -1947,9 +1957,10 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node,
Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
Node* node, Node* frame_state) {
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* check = ObjectIsSmi(value);
__ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, VectorSlotPair(), check,
__ DeoptimizeIfNot(DeoptimizeReason::kNotASmi, params.feedback(), check,
frame_state);
return value;
......@@ -1958,9 +1969,11 @@ Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(
Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(
Node* node, Node* frame_state) {
Node* value = node->InputAt(0);
const CheckParameters& params = CheckParametersOf(node->op());
Node* check = ObjectIsSmi(value);
__ DeoptimizeIf(DeoptimizeReason::kSmi, VectorSlotPair(), check, frame_state);
__ DeoptimizeIf(DeoptimizeReason::kSmi, params.feedback(), check,
frame_state);
return value;
}
......@@ -1986,7 +1999,8 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) {
Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
Node* node, Node* frame_state) {
CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op());
const CheckTaggedInputParameters& params =
CheckTaggedInputParametersOf(node->op());
Node* value = node->InputAt(0);
auto if_not_smi = __ MakeLabel();
......@@ -2000,8 +2014,8 @@ Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(
// Otherwise, check that it's a heap number or oddball and truncate the value
// to int32.
__ Bind(&if_not_smi);
Node* number =
BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state);
Node* number = BuildCheckedHeapNumberOrOddballToFloat64(
params.mode(), params.feedback(), value, frame_state);
number = __ TruncateFloat64ToWord32(number);
__ Goto(&done, number);
......
......@@ -154,9 +154,11 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Maybe<Node*> LowerFloat64RoundTruncate(Node* node);
Node* AllocateHeapNumberWithValue(Node* node);
Node* BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode, Node* value,
Node* BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
const VectorSlotPair& feedback, Node* value,
Node* frame_state);
Node* BuildCheckedHeapNumberOrOddballToFloat64(CheckTaggedInputMode mode,
const VectorSlotPair& feedback,
Node* value,
Node* frame_state);
Node* BuildFloat64RoundDown(Node* value);
......
......@@ -1044,8 +1044,8 @@ Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) {
// Array.prototype.push inlining for this function.
for (auto& value : values) {
if (IsSmiElementsKind(receiver_map->elements_kind())) {
value = effect =
graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
} else if (IsDoubleElementsKind(receiver_map->elements_kind())) {
value = effect =
graph()->NewNode(simplified()->CheckNumber(VectorSlotPair()), value,
......
......@@ -617,8 +617,8 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node,
if (IsSmiElementsKind(elements_kind)) {
for (auto& value : values) {
if (!NodeProperties::GetType(value)->Is(Type::SignedSmall())) {
value = effect =
graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
}
}
} else if (IsDoubleElementsKind(elements_kind)) {
......
......@@ -597,8 +597,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
representation = MachineRepresentation::kTaggedPointer;
} else {
// Check that the {value} is a Smi.
value = effect = graph()->NewNode(simplified()->CheckSmi(), value,
effect, control);
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
property_cell_value_type = Type::SignedSmall();
representation = MachineRepresentation::kTaggedSigned;
}
......@@ -1877,8 +1877,8 @@ JSNativeContextSpecialization::BuildPropertyStore(
}
if (field_representation == MachineRepresentation::kTaggedSigned) {
value = effect = graph()->NewNode(simplified()->CheckSmi(), value,
effect, control);
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
field_access.write_barrier_kind = kNoWriteBarrier;
} else if (field_representation ==
......@@ -2396,8 +2396,8 @@ JSNativeContextSpecialization::BuildElementAccess(
} else {
DCHECK_EQ(AccessMode::kStore, access_mode);
if (IsSmiElementsKind(elements_kind)) {
value = effect =
graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
} else if (IsDoubleElementsKind(elements_kind)) {
value = effect =
graph()->NewNode(simplified()->CheckNumber(VectorSlotPair()), value,
......
......@@ -224,14 +224,14 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
if (SmiValuesAre32Bits()) {
op = simplified()->ChangeInt32ToTagged();
} else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedInt32ToTaggedSigned();
op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
}
} else if (output_type->Is(Type::Unsigned32()) &&
use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedUint32ToTaggedSigned();
op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
......@@ -247,7 +247,7 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
if (SmiValuesAre32Bits()) {
op = simplified()->ChangeInt32ToTagged();
} else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedInt32ToTaggedSigned();
op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
......@@ -256,17 +256,18 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
use_info.type_check() == TypeCheckKind::kSignedSmall) {
// float64 -> uint32 -> tagged signed
node = InsertChangeFloat64ToUint32(node);
op = simplified()->CheckedUint32ToTaggedSigned();
op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
} else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedFloat64ToInt32(
output_type->Maybe(Type::MinusZero())
? CheckForMinusZeroMode::kCheckForMinusZero
: CheckForMinusZeroMode::kDontCheckForMinusZero);
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
node = InsertConversion(node, op, use_node);
if (SmiValuesAre32Bits()) {
op = simplified()->ChangeInt32ToTagged();
} else {
op = simplified()->CheckedInt32ToTaggedSigned();
op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
}
} else {
return TypeError(node, output_rep, output_type,
......@@ -279,12 +280,13 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
op = simplified()->CheckedFloat64ToInt32(
output_type->Maybe(Type::MinusZero())
? CheckForMinusZeroMode::kCheckForMinusZero
: CheckForMinusZeroMode::kDontCheckForMinusZero);
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
node = InsertConversion(node, op, use_node);
if (SmiValuesAre32Bits()) {
op = simplified()->ChangeInt32ToTagged();
} else {
op = simplified()->CheckedInt32ToTaggedSigned();
op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
}
} else {
return TypeError(node, output_rep, output_type,
......@@ -292,7 +294,7 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
}
} else if (CanBeTaggedPointer(output_rep)) {
if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedTaggedToTaggedSigned();
op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
} else if (output_type->Is(Type::SignedSmall())) {
op = simplified()->ChangeTaggedToTaggedSigned();
} else {
......@@ -304,7 +306,7 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
// TODO(turbofan): Consider adding a Bailout operator that just deopts.
// Also use that for MachineRepresentation::kPointer case above.
node = InsertChangeBitToTagged(node);
op = simplified()->CheckedTaggedToTaggedSigned();
op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
......@@ -378,7 +380,7 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
}
// TODO(turbofan): Consider adding a Bailout operator that just deopts
// for TaggedSigned output representation.
op = simplified()->CheckedTaggedToTaggedPointer();
op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
......@@ -637,7 +639,8 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
op = simplified()->CheckedFloat64ToInt32(
output_type->Maybe(Type::MinusZero())
? use_info.minus_zero_check()
: CheckForMinusZeroMode::kDontCheckForMinusZero);
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
} else if (output_type->Is(Type::Unsigned32())) {
op = machine()->ChangeFloat64ToUint32();
} else if (use_info.truncation().IsUsedAsWord32()) {
......@@ -655,7 +658,8 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
op = simplified()->CheckedFloat64ToInt32(
output_type->Maybe(Type::MinusZero())
? use_info.minus_zero_check()
: CheckForMinusZeroMode::kDontCheckForMinusZero);
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
} else if (output_type->Is(Type::Unsigned32())) {
op = machine()->ChangeFloat64ToUint32();
} else if (use_info.truncation().IsUsedAsWord32()) {
......@@ -671,12 +675,13 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
} else if (output_type->Is(Type::Signed32())) {
op = simplified()->ChangeTaggedToInt32();
} else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
op = simplified()->CheckedTaggedSignedToInt32();
op = simplified()->CheckedTaggedSignedToInt32(use_info.feedback());
} else if (use_info.type_check() == TypeCheckKind::kSigned32) {
op = simplified()->CheckedTaggedToInt32(
output_type->Maybe(Type::MinusZero())
? use_info.minus_zero_check()
: CheckForMinusZeroMode::kDontCheckForMinusZero);
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
} else if (output_type->Is(Type::Unsigned32())) {
op = simplified()->ChangeTaggedToUint32();
} else if (use_info.truncation().IsUsedAsWord32()) {
......@@ -684,10 +689,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
op = simplified()->TruncateTaggedToWord32();
} else if (use_info.type_check() == TypeCheckKind::kNumber) {
op = simplified()->CheckedTruncateTaggedToWord32(
CheckTaggedInputMode::kNumber);
CheckTaggedInputMode::kNumber, use_info.feedback());
} else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
op = simplified()->CheckedTruncateTaggedToWord32(
CheckTaggedInputMode::kNumberOrOddball);
CheckTaggedInputMode::kNumberOrOddball, use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord32);
......@@ -704,7 +709,7 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
if (output_type->Is(Type::Signed32())) {
return node;
} else if (output_type->Is(Type::Unsigned32())) {
op = simplified()->CheckedUint32ToInt32();
op = simplified()->CheckedUint32ToInt32(use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord32);
......
......@@ -147,13 +147,18 @@ inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
// to the preferred representation. The preferred representation might be
// insufficient to do the conversion (e.g. word32->float64 conv), so we also
// need the signedness information to produce the correct value.
// Additionally, use info may contain {CheckParameters} which contains
// information for the deoptimizer such as a CallIC on which speculation
// should be disallowed if the check fails.
class UseInfo {
public:
UseInfo(MachineRepresentation representation, Truncation truncation,
TypeCheckKind type_check = TypeCheckKind::kNone)
TypeCheckKind type_check = TypeCheckKind::kNone,
const VectorSlotPair& feedback = VectorSlotPair())
: representation_(representation),
truncation_(truncation),
type_check_(type_check) {}
type_check_(type_check),
feedback_(feedback) {}
static UseInfo TruncatingWord32() {
return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
}
......@@ -187,14 +192,16 @@ class UseInfo {
return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
TypeCheckKind::kHeapObject);
}
static UseInfo CheckedSignedSmallAsTaggedSigned() {
static UseInfo CheckedSignedSmallAsTaggedSigned(
const VectorSlotPair& feedback) {
return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any(),
TypeCheckKind::kSignedSmall);
TypeCheckKind::kSignedSmall, feedback);
}
static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros) {
static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros,
const VectorSlotPair& feedback) {
return UseInfo(MachineRepresentation::kWord32,
Truncation::Any(identify_zeros),
TypeCheckKind::kSignedSmall);
Truncation::Any(identify_zeros), TypeCheckKind::kSignedSmall,
feedback);
}
static UseInfo CheckedSigned32AsWord32(IdentifyZeros identify_zeros) {
return UseInfo(MachineRepresentation::kWord32,
......@@ -238,11 +245,13 @@ class UseInfo {
? CheckForMinusZeroMode::kDontCheckForMinusZero
: CheckForMinusZeroMode::kCheckForMinusZero;
}
const VectorSlotPair& feedback() const { return feedback_; }
private:
MachineRepresentation representation_;
Truncation truncation_;
TypeCheckKind type_check_;
VectorSlotPair feedback_;
};
// Contains logic related to changing the representation of values for constants
......
......@@ -92,7 +92,8 @@ UseInfo CheckedUseInfoAsWord32FromHint(
switch (hint) {
case NumberOperationHint::kSignedSmall:
case NumberOperationHint::kSignedSmallInputs:
return UseInfo::CheckedSignedSmallAsWord32(identify_zeros);
return UseInfo::CheckedSignedSmallAsWord32(identify_zeros,
VectorSlotPair());
case NumberOperationHint::kSigned32:
return UseInfo::CheckedSigned32AsWord32(identify_zeros);
case NumberOperationHint::kNumber:
......@@ -1682,8 +1683,10 @@ class RepresentationSelector {
Node* rhs = node->InputAt(1);
if (IsNodeRepresentationTagged(lhs) &&
IsNodeRepresentationTagged(rhs)) {
VisitBinop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
MachineRepresentation::kBit);
VisitBinop(
node,
UseInfo::CheckedSignedSmallAsTaggedSigned(VectorSlotPair()),
MachineRepresentation::kBit);
ChangeToPureOp(
node, changer_->TaggedSignedOperatorFor(node->opcode()));
......@@ -2047,8 +2050,8 @@ class RepresentationSelector {
MachineRepresentation::kWord32, Type::Unsigned31());
if (lower()) {
node->RemoveInput(1);
NodeProperties::ChangeOp(node,
simplified()->CheckedUint32ToInt32());
NodeProperties::ChangeOp(
node, simplified()->CheckedUint32ToInt32(VectorSlotPair()));
}
return;
}
......@@ -2429,13 +2432,17 @@ class RepresentationSelector {
return;
}
case IrOpcode::kCheckSmi: {
const CheckParameters& params = CheckParametersOf(node->op());
if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
VisitUnop(node,
UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros),
UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros,
params.feedback()),
MachineRepresentation::kWord32);
} else {
VisitUnop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
MachineRepresentation::kTaggedSigned);
VisitUnop(
node,
UseInfo::CheckedSignedSmallAsTaggedSigned(params.feedback()),
MachineRepresentation::kTaggedSigned);
}
if (lower()) DeferReplacement(node, node->InputAt(0));
return;
......
This diff is collapsed.
......@@ -134,7 +134,32 @@ size_t hash_value(CheckTaggedInputMode);
std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
CheckTaggedInputMode CheckTaggedInputModeOf(const Operator*) WARN_UNUSED_RESULT;
CheckTaggedInputMode CheckTaggedInputModeOf(const Operator*);
class CheckTaggedInputParameters {
public:
CheckTaggedInputParameters(CheckTaggedInputMode mode,
const VectorSlotPair& feedback)
: mode_(mode), feedback_(feedback) {}
CheckTaggedInputMode mode() const { return mode_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
CheckTaggedInputMode mode_;
VectorSlotPair feedback_;
};
const CheckTaggedInputParameters& CheckTaggedInputParametersOf(const Operator*)
WARN_UNUSED_RESULT;
std::ostream& operator<<(std::ostream&,
const CheckTaggedInputParameters& params);
size_t hash_value(const CheckTaggedInputParameters& params);
bool operator==(CheckTaggedInputParameters const&,
CheckTaggedInputParameters const&);
enum class CheckForMinusZeroMode : uint8_t {
kCheckForMinusZero,
......@@ -148,6 +173,30 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) WARN_UNUSED_RESULT;
class CheckMinusZeroParameters {
public:
CheckMinusZeroParameters(CheckForMinusZeroMode mode,
const VectorSlotPair& feedback)
: mode_(mode), feedback_(feedback) {}
CheckForMinusZeroMode mode() const { return mode_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
CheckForMinusZeroMode mode_;
VectorSlotPair feedback_;
};
const CheckMinusZeroParameters& CheckMinusZeroParametersOf(const Operator* op)
WARN_UNUSED_RESULT;
std::ostream& operator<<(std::ostream&, const CheckMinusZeroParameters& params);
size_t hash_value(const CheckMinusZeroParameters& params);
bool operator==(CheckMinusZeroParameters const&,
CheckMinusZeroParameters const&);
// Flags for map checks.
enum class CheckMapsFlag : uint8_t {
kNone = 0u,
......@@ -496,7 +545,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* CheckHeapObject();
const Operator* CheckInternalizedString();
const Operator* CheckNumber(const VectorSlotPair& feedback);
const Operator* CheckSmi();
const Operator* CheckSmi(const VectorSlotPair& feedback);
const Operator* CheckString();
const Operator* CheckSeqString();
const Operator* CheckSymbol();
......@@ -509,16 +558,19 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* CheckedUint32Div();
const Operator* CheckedUint32Mod();
const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
const Operator* CheckedInt32ToTaggedSigned();
const Operator* CheckedUint32ToInt32();
const Operator* CheckedUint32ToTaggedSigned();
const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode);
const Operator* CheckedTaggedSignedToInt32();
const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
const Operator* CheckedInt32ToTaggedSigned(const VectorSlotPair& feedback);
const Operator* CheckedUint32ToInt32(const VectorSlotPair& feedback);
const Operator* CheckedUint32ToTaggedSigned(const VectorSlotPair& feedback);
const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode,
const VectorSlotPair& feedback);
const Operator* CheckedTaggedSignedToInt32(const VectorSlotPair& feedback);
const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode,
const VectorSlotPair& feedback);
const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
const Operator* CheckedTaggedToTaggedSigned();
const Operator* CheckedTaggedToTaggedPointer();
const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode);
const Operator* CheckedTaggedToTaggedSigned(const VectorSlotPair& feedback);
const Operator* CheckedTaggedToTaggedPointer(const VectorSlotPair& feedback);
const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode,
const VectorSlotPair& feedback);
const Operator* ConvertReceiver(ConvertReceiverMode);
......
......@@ -30,8 +30,8 @@ class V8_EXPORT_PRIVATE VectorSlotPair {
int index() const;
private:
const Handle<FeedbackVector> vector_;
const FeedbackSlot slot_;
Handle<FeedbackVector> vector_;
FeedbackSlot slot_;
};
bool operator==(VectorSlotPair const&, VectorSlotPair const&);
......
......@@ -285,7 +285,7 @@ static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
from_type->Maybe(Type::MinusZero())
? use_info.minus_zero_check()
: CheckForMinusZeroMode::kDontCheckForMinusZero;
CHECK_EQ(mode, CheckMinusZeroModeOf(c->op()));
CHECK_EQ(mode, CheckMinusZeroParametersOf(c->op()).mode());
}
}
......@@ -444,11 +444,13 @@ TEST(SignednessInWord32) {
static void TestMinusZeroCheck(IrOpcode::Value expected, Type* from_type) {
RepresentationChangerTester r;
CheckChange(expected, MachineRepresentation::kFloat64, from_type,
UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros));
CheckChange(
expected, MachineRepresentation::kFloat64, from_type,
UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros, VectorSlotPair()));
CheckChange(expected, MachineRepresentation::kFloat64, from_type,
UseInfo::CheckedSignedSmallAsWord32(kIdentifyZeros));
CheckChange(
expected, MachineRepresentation::kFloat64, from_type,
UseInfo::CheckedSignedSmallAsWord32(kIdentifyZeros, VectorSlotPair()));
CheckChange(expected, MachineRepresentation::kFloat64, from_type,
UseInfo::CheckedSigned32AsWord32(kDistinguishZeros));
......
......@@ -356,10 +356,10 @@ TEST_F(SimplifiedOperatorReducerTest, CheckedFloat64ToInt32WithConstant) {
Node* effect = graph()->start();
Node* control = graph()->start();
TRACED_FOREACH(int32_t, n, kInt32Values) {
Reduction r = Reduce(
graph()->NewNode(simplified()->CheckedFloat64ToInt32(
CheckForMinusZeroMode::kDontCheckForMinusZero),
Float64Constant(n), effect, control));
Reduction r = Reduce(graph()->NewNode(
simplified()->CheckedFloat64ToInt32(
CheckForMinusZeroMode::kDontCheckForMinusZero, VectorSlotPair()),
Float64Constant(n), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsInt32Constant(n));
}
......@@ -415,8 +415,8 @@ TEST_F(SimplifiedOperatorReducerTest, CheckSmiWithChangeInt31ToTaggedSigned) {
Node* control = graph()->start();
Node* value =
graph()->NewNode(simplified()->ChangeInt31ToTaggedSigned(), param0);
Reduction reduction = Reduce(
graph()->NewNode(simplified()->CheckSmi(), value, effect, control));
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
......@@ -425,8 +425,8 @@ TEST_F(SimplifiedOperatorReducerTest, CheckSmiWithNumberConstant) {
Node* effect = graph()->start();
Node* control = graph()->start();
Node* value = NumberConstant(1.0);
Reduction reduction = Reduce(
graph()->NewNode(simplified()->CheckSmi(), value, effect, control));
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
......@@ -435,10 +435,10 @@ TEST_F(SimplifiedOperatorReducerTest, CheckSmiWithCheckSmi) {
Node* param0 = Parameter(0);
Node* effect = graph()->start();
Node* control = graph()->start();
Node* value = effect =
graph()->NewNode(simplified()->CheckSmi(), param0, effect, control);
Reduction reduction = Reduce(
graph()->NewNode(simplified()->CheckSmi(), value, effect, control));
Node* value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), param0, effect, control);
Reduction reduction = Reduce(graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control));
ASSERT_TRUE(reduction.Changed());
EXPECT_EQ(value, reduction.replacement());
}
......
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