Commit c85aa830 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Harden type-based elimination of MaybeGrowFastElements

... against potential typer bugs. Instead of simply eliminating the
operation, insert an aborting bounds check instead.

Also move this transformation out of SimplifiedLowering, which is
already complex enough without doing these kinds of optimizations.
Unfortunately this will result in some missed optimization opportunities
because we may have more precise types during SimplifiedLowering. Let's
see if this makes a visible performance difference.

Change-Id: I9c16ad33104c29fdba39bf729d69ee03fc9797d6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2129633
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67222}
parent 3df19d31
......@@ -3580,25 +3580,12 @@ class RepresentationSelector {
return VisitBinop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTaggedPointer);
case IrOpcode::kMaybeGrowFastElements: {
Type const index_type = TypeOf(node->InputAt(2));
Type const length_type = TypeOf(node->InputAt(3));
ProcessInput(node, 0, UseInfo::AnyTagged()); // object
ProcessInput(node, 1, UseInfo::AnyTagged()); // elements
ProcessInput(node, 2, UseInfo::TruncatingWord32()); // index
ProcessInput(node, 3, UseInfo::TruncatingWord32()); // length
ProcessRemainingInputs(node, 4);
SetOutput(node, MachineRepresentation::kTaggedPointer);
if (lower()) {
// If the index is known to be less than the length (or if
// we're in dead code), we know that we don't need to grow
// the elements, so we can just remove this operation all
// together and replace it with the elements that we have
// on the inputs.
if (index_type.IsNone() || length_type.IsNone() ||
index_type.Max() < length_type.Min()) {
DeferReplacement(node, node->InputAt(1));
}
}
return;
}
......
......@@ -38,6 +38,8 @@ Reduction TypedOptimization::Reduce(Node* node) {
switch (node->opcode()) {
case IrOpcode::kConvertReceiver:
return ReduceConvertReceiver(node);
case IrOpcode::kMaybeGrowFastElements:
return ReduceMaybeGrowFastElements(node);
case IrOpcode::kCheckHeapObject:
return ReduceCheckHeapObject(node);
case IrOpcode::kCheckNotTaggedHole:
......@@ -159,6 +161,31 @@ Reduction TypedOptimization::ReduceCheckHeapObject(Node* node) {
return NoChange();
}
Reduction TypedOptimization::ReduceMaybeGrowFastElements(Node* node) {
Node* const elements = NodeProperties::GetValueInput(node, 1);
Node* const index = NodeProperties::GetValueInput(node, 2);
Node* const length = NodeProperties::GetValueInput(node, 3);
Node* const effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
Type const index_type = NodeProperties::GetType(index);
Type const length_type = NodeProperties::GetType(length);
CHECK(index_type.Is(Type::Unsigned31()));
CHECK(length_type.Is(Type::Unsigned31()));
if (!index_type.IsNone() && !length_type.IsNone() &&
index_type.Max() < length_type.Min()) {
Node* check_bounds = graph()->NewNode(
simplified()->CheckBounds(FeedbackSource{},
CheckBoundsParameters::kAbortOnOutOfBounds),
index, length, effect, control);
ReplaceWithValue(node, elements);
return Replace(check_bounds);
}
return NoChange();
}
Reduction TypedOptimization::ReduceCheckNotTaggedHole(Node* node) {
Node* const input = NodeProperties::GetValueInput(node, 0);
Type const input_type = NodeProperties::GetType(input);
......@@ -285,7 +312,7 @@ Reduction TypedOptimization::ReduceNumberFloor(Node* node) {
// NumberToUint32(NumberDivide(lhs, rhs))
//
// and just smash the type [0...lhs.Max] on the {node},
// as the truncated result must be loewr than {lhs}'s maximum
// as the truncated result must be lower than {lhs}'s maximum
// value (note that {rhs} cannot be less than 1 due to the
// plain-number type constraint on the {node}).
NodeProperties::ChangeOp(node, simplified()->NumberToUint32());
......
......@@ -37,6 +37,7 @@ class V8_EXPORT_PRIVATE TypedOptimization final
private:
Reduction ReduceConvertReceiver(Node* node);
Reduction ReduceMaybeGrowFastElements(Node* node);
Reduction ReduceCheckHeapObject(Node* node);
Reduction ReduceCheckMaps(Node* node);
Reduction ReduceCheckNumber(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