[turbofan] Optimize strict equality of unique values.
If both inputs to JSStrictEqual/JSStrictNotEqual are unique values (i.e. values with a canonical representation), we can lower the comparison to ReferenceEqual instead of StringEqual or CompareIC. Review URL: https://codereview.chromium.org/1154303002 Cr-Commit-Position: refs/heads/master@{#28646}
This commit is contained in:
parent
496d3827ad
commit
b66226a9d9
@ -566,6 +566,10 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
|
||||
return r.ChangeToPureOperator(
|
||||
simplified()->ReferenceEqual(Type::Receiver()), invert);
|
||||
}
|
||||
if (r.BothInputsAre(Type::Unique())) {
|
||||
return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()),
|
||||
invert);
|
||||
}
|
||||
if (r.BothInputsAre(Type::String())) {
|
||||
return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
|
||||
}
|
||||
|
@ -436,18 +436,27 @@ TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
|
||||
TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
|
||||
Node* const the_hole = HeapConstant(factory()->the_hole_value());
|
||||
Node* const context = UndefinedConstant();
|
||||
Node* const effect = graph()->start();
|
||||
Node* const control = graph()->start();
|
||||
TRACED_FOREACH(Type*, type, kJSTypes) {
|
||||
Node* const lhs = Parameter(type);
|
||||
Reduction r = Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs,
|
||||
the_hole, context, effect, control));
|
||||
Reduction r = Reduce(
|
||||
graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole, context));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsFalseConstant());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
|
||||
Node* const lhs = Parameter(Type::Unique(), 0);
|
||||
Node* const rhs = Parameter(Type::Unique(), 1);
|
||||
Node* const context = Parameter(Type::Any(), 2);
|
||||
Reduction r =
|
||||
Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context));
|
||||
ASSERT_TRUE(r.Changed());
|
||||
EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// JSShiftLeft
|
||||
|
||||
|
@ -748,6 +748,32 @@ class IsTailCallMatcher final : public NodeMatcher {
|
||||
};
|
||||
|
||||
|
||||
class IsReferenceEqualMatcher final : public NodeMatcher {
|
||||
public:
|
||||
IsReferenceEqualMatcher(const Matcher<Type*>& type_matcher,
|
||||
const Matcher<Node*>& lhs_matcher,
|
||||
const Matcher<Node*>& rhs_matcher)
|
||||
: NodeMatcher(IrOpcode::kReferenceEqual),
|
||||
type_matcher_(type_matcher),
|
||||
lhs_matcher_(lhs_matcher),
|
||||
rhs_matcher_(rhs_matcher) {}
|
||||
|
||||
bool MatchAndExplain(Node* node, MatchResultListener* listener) const final {
|
||||
return (NodeMatcher::MatchAndExplain(node, listener) &&
|
||||
// TODO(bmeurer): The type parameter is currently ignored.
|
||||
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
|
||||
lhs_matcher_, listener) &&
|
||||
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
|
||||
rhs_matcher_, listener));
|
||||
}
|
||||
|
||||
private:
|
||||
const Matcher<Type*> type_matcher_;
|
||||
const Matcher<Node*> lhs_matcher_;
|
||||
const Matcher<Node*> rhs_matcher_;
|
||||
};
|
||||
|
||||
|
||||
class IsAllocateMatcher final : public NodeMatcher {
|
||||
public:
|
||||
IsAllocateMatcher(const Matcher<Node*>& size_matcher,
|
||||
@ -1607,6 +1633,14 @@ Matcher<Node*> IsTailCall(
|
||||
}
|
||||
|
||||
|
||||
Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
|
||||
const Matcher<Node*>& lhs_matcher,
|
||||
const Matcher<Node*>& rhs_matcher) {
|
||||
return MakeMatcher(
|
||||
new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher));
|
||||
}
|
||||
|
||||
|
||||
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
|
||||
const Matcher<Node*>& effect_matcher,
|
||||
const Matcher<Node*>& control_matcher) {
|
||||
|
@ -17,6 +17,10 @@ class ExternalReference;
|
||||
class HeapObject;
|
||||
template <class T>
|
||||
class Unique;
|
||||
template <class>
|
||||
class TypeImpl;
|
||||
struct ZoneTypeConfig;
|
||||
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
@ -127,6 +131,9 @@ Matcher<Node*> IsTailCall(
|
||||
const Matcher<Node*>& control_matcher);
|
||||
|
||||
Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
|
||||
Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
|
||||
const Matcher<Node*>& lhs_matcher,
|
||||
const Matcher<Node*>& rhs_matcher);
|
||||
Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher,
|
||||
const Matcher<Node*>& rhs_matcher);
|
||||
Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
|
||||
|
Loading…
Reference in New Issue
Block a user