Commit 5d312f02 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Remove String.fromCharCode if possible

This CL removes String.fromCharCode from comparisons and uses
a WordEqual on char codes if possible.

Bug: v8:7531
Change-Id: Idb3529d4709df3976bf92f3ddb51f81de54c7465
Reviewed-on: https://chromium-review.googlesource.com/960082
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51905}
parent 0f196dd3
......@@ -6,6 +6,7 @@
#include "src/compilation-dependencies.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/compiler/type-cache.h"
......@@ -105,6 +106,8 @@ Reduction TypedOptimization::Reduce(Node* node) {
return ReducePhi(node);
case IrOpcode::kReferenceEqual:
return ReduceReferenceEqual(node);
case IrOpcode::kStringEqual:
return ReduceStringEqual(node);
case IrOpcode::kSameValue:
return ReduceSameValue(node);
case IrOpcode::kSelect:
......@@ -359,6 +362,60 @@ Reduction TypedOptimization::ReduceReferenceEqual(Node* node) {
return NoChange();
}
Reduction TypedOptimization::TryReduceStringEqualOfCharAtAndConstant(
Node* equal, Node* char_at, Node* constant) {
DCHECK_EQ(IrOpcode::kStringFromCharCode, char_at->opcode());
HeapObjectMatcher m(constant);
if (!m.HasValue() || !m.Value()->IsString()) return NoChange();
Handle<String> string = Handle<String>::cast(m.Value());
if (string->length() != 1) {
// StringEqual can never be true. Out-of-bounds
// accesses will be handled by the deopt through CheckBounds.
return Replace(jsgraph()->BooleanConstant(false));
}
Node* number_equal = graph()->NewNode(
simplified()->NumberEqual(), NodeProperties::GetValueInput(char_at, 0),
jsgraph()->Constant(string->Get(0)));
ReplaceWithValue(equal, number_equal);
return Replace(number_equal);
}
Reduction TypedOptimization::ReduceStringEqual(Node* node) {
DCHECK_EQ(IrOpcode::kStringEqual, node->opcode());
Node* const lhs = NodeProperties::GetValueInput(node, 0);
Node* const rhs = NodeProperties::GetValueInput(node, 1);
if (lhs->opcode() == IrOpcode::kStringFromCharCode) {
if (rhs->opcode() == IrOpcode::kStringFromCharCode) {
Node* left = NodeProperties::GetValueInput(lhs, 0);
Node* right = NodeProperties::GetValueInput(rhs, 0);
Type* left_type = NodeProperties::GetType(left);
Type* right_type = NodeProperties::GetType(right);
if (!left_type->Is(type_cache_.kUint16)) {
// Convert to signed int32 to satisfy type of {NumberBitwiseAnd}.
left = graph()->NewNode(simplified()->NumberToInt32(), left);
left = graph()->NewNode(
simplified()->NumberBitwiseAnd(), left,
jsgraph()->Constant(std::numeric_limits<uint16_t>::max()));
}
if (!right_type->Is(type_cache_.kUint16)) {
// Convert to signed int32 to satisfy type of {NumberBitwiseAnd}.
right = graph()->NewNode(simplified()->NumberToInt32(), right);
right = graph()->NewNode(
simplified()->NumberBitwiseAnd(), right,
jsgraph()->Constant(std::numeric_limits<uint16_t>::max()));
}
Node* equal = graph()->NewNode(simplified()->NumberEqual(), left, right);
ReplaceWithValue(node, equal);
return Replace(equal);
} else {
return TryReduceStringEqualOfCharAtAndConstant(node, lhs, rhs);
}
} else if (rhs->opcode() == IrOpcode::kStringFromCharCode) {
return TryReduceStringEqualOfCharAtAndConstant(node, rhs, lhs);
}
return NoChange();
}
Reduction TypedOptimization::ReduceSameValue(Node* node) {
DCHECK_EQ(IrOpcode::kSameValue, node->opcode());
Node* const lhs = NodeProperties::GetValueInput(node, 0);
......
......@@ -50,6 +50,7 @@ class V8_EXPORT_PRIVATE TypedOptimization final
Reduction ReduceNumberToUint8Clamped(Node* node);
Reduction ReducePhi(Node* node);
Reduction ReduceReferenceEqual(Node* node);
Reduction ReduceStringEqual(Node* node);
Reduction ReduceSameValue(Node* node);
Reduction ReduceSelect(Node* node);
Reduction ReduceSpeculativeToNumber(Node* node);
......@@ -57,6 +58,9 @@ class V8_EXPORT_PRIVATE TypedOptimization final
Reduction ReduceTypeOf(Node* node);
Reduction ReduceToBoolean(Node* node);
Reduction TryReduceStringEqualOfCharAtAndConstant(Node* equal, Node* char_at,
Node* constant);
CompilationDependencies* dependencies() const { return dependencies_; }
Factory* factory() const;
Graph* graph() const;
......
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