[turbofan] Widen fast-path of Array.p.reduce[Right]

This allows mixing of smi/object values and adds
support for holey double arrays.

Bug: v8:7340
Change-Id: I7e3a2b0aaa205b7af8c3af615fb9c9a965178b3f
Reviewed-on: https://chromium-review.googlesource.com/878123
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50781}
This commit is contained in:
Sigurd Schneider 2018-01-22 13:21:23 +01:00 committed by Commit Bot
parent 9fac6dcb03
commit d2681aa448

View File

@ -997,6 +997,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect, control);
return Replace(jsgraph()->UndefinedConstant());
}
Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
Node* node,
ArrayReduceDirection direction) {
@ -1024,23 +1025,22 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
NodeProperties::InferReceiverMaps(receiver, effect, &receiver_maps);
if (result == NodeProperties::kNoReceiverMaps) return NoChange();
ElementsKind kind = IsDoubleElementsKind(receiver_maps[0]->elements_kind())
? PACKED_DOUBLE_ELEMENTS
: PACKED_ELEMENTS;
ElementsKind kind = receiver_maps[0]->elements_kind();
for (Handle<Map> receiver_map : receiver_maps) {
ElementsKind next_kind = receiver_map->elements_kind();
if (!CanInlineArrayIteratingBuiltin(receiver_map)) return NoChange();
if (!IsFastElementsKind(next_kind) || next_kind == HOLEY_DOUBLE_ELEMENTS) {
if (!UnionElementsKindUptoSize(&kind, receiver_map->elements_kind()))
return NoChange();
}
if (IsDoubleElementsKind(kind) != IsDoubleElementsKind(next_kind)) {
return NoChange();
}
if (IsHoleyElementsKind(next_kind)) {
kind = HOLEY_ELEMENTS;
}
}
std::function<Node*(Node*)> hole_check = [this, kind](Node* element) {
if (IsDoubleElementsKind(kind)) {
return graph()->NewNode(simplified()->NumberIsFloat64Hole(), element);
} else {
return graph()->NewNode(simplified()->ReferenceEqual(), element,
jsgraph()->TheHoleConstant());
}
};
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
@ -1120,10 +1120,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
cur = SafeLoadElement(kind, receiver, control, &effect, &k, p.feedback());
Node* next_k = graph()->NewNode(next_op, k, jsgraph()->OneConstant());
Node* hole_test = graph()->NewNode(simplified()->ReferenceEqual(), cur,
jsgraph()->TheHoleConstant());
Node* hole_branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
hole_test, control);
hole_check(cur), control);
Node* found_el = graph()->NewNode(common()->IfFalse(), hole_branch);
control = found_el;
Node* is_hole = graph()->NewNode(common()->IfTrue(), hole_branch);
@ -1187,10 +1185,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle<JSFunction> function,
if (IsHoleyElementsKind(kind)) {
// Holey elements kind require a hole check and skipping of the element in
// the case of a hole.
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), element,
jsgraph()->TheHoleConstant());
Node* branch =
graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
hole_check(element), control);
hole_true = graph()->NewNode(common()->IfTrue(), branch);
hole_false = graph()->NewNode(common()->IfFalse(), branch);
control = hole_false;