Commit 524abd76 authored by epertoso's avatar epertoso Committed by Commit bot

[turbofan] Adds speculative operator for bitwise and, or and xor.

BUG=

Review-Url: https://codereview.chromium.org/2201073002
Cr-Commit-Position: refs/heads/master@{#38246}
parent aba8a815
......@@ -581,13 +581,26 @@ Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
return NoChange();
}
Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
Reduction JSTypedLowering::ReduceInt32Binop(Node* node,
const Operator* int_op) {
if (flags() & kDisableIntegerBinaryOpReduction) return NoChange();
JSBinopReduction r(this, node);
BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
if (feedback != BinaryOperationHints::kAny) {
Operator const* speculative_op;
if (int_op->opcode() == IrOpcode::kNumberBitwiseAnd) {
speculative_op = simplified()->SpeculativeNumberBitwiseAnd(feedback);
} else if (int_op->opcode() == IrOpcode::kNumberBitwiseOr) {
speculative_op = simplified()->SpeculativeNumberBitwiseOr(feedback);
} else {
DCHECK_EQ(IrOpcode::kNumberBitwiseXor, int_op->opcode());
speculative_op = simplified()->SpeculativeNumberBitwiseXor(feedback);
}
return r.ChangeToSpeculativeOperator(speculative_op, Type::Signed32());
}
r.ConvertInputsToNumber();
r.ConvertInputsToUI32(kSigned, kSigned);
return r.ChangeToPureOperator(intOp, Type::Integral32());
return r.ChangeToPureOperator(int_op, Type::Signed32());
}
Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
......@@ -603,7 +616,7 @@ Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
speculative_op =
simplified()->SpeculativeNumberShiftRightLogical(feedback);
} else {
DCHECK(shift_op->opcode() == IrOpcode::kNumberShiftRight);
DCHECK_EQ(IrOpcode::kNumberShiftRight, shift_op->opcode());
speculative_op = simplified()->SpeculativeNumberShiftRight(feedback);
}
return r.ChangeToSpeculativeOperator(
......
......@@ -227,11 +227,14 @@
V(NumberBitwiseXor) \
V(NumberBitwiseAnd) \
V(NumberShiftLeft) \
V(NumberShiftRight) \
V(NumberShiftRightLogical) \
V(SpeculativeNumberBitwiseAnd) \
V(SpeculativeNumberBitwiseOr) \
V(SpeculativeNumberBitwiseXor) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical) \
V(NumberShiftRight) \
V(NumberShiftRightLogical) \
V(NumberImul) \
V(NumberAbs) \
V(NumberClz32) \
......
......@@ -457,7 +457,7 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
} else if (output_type->Is(Type::Signed32())) {
op = simplified()->ChangeTaggedToInt32();
} else if (use_info.truncation().IsUsedAsWord32()) {
if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
if (use_info.type_check() != TypeCheckKind::kNone) {
op = simplified()->CheckedTruncateTaggedToWord32();
} else {
op = simplified()->TruncateTaggedToWord32();
......@@ -568,10 +568,13 @@ const Operator* RepresentationChanger::Int32OperatorFor(
case IrOpcode::kSpeculativeNumberModulus:
case IrOpcode::kNumberModulus:
return machine()->Int32Mod();
case IrOpcode::kSpeculativeNumberBitwiseOr: // Fall through.
case IrOpcode::kNumberBitwiseOr:
return machine()->Word32Or();
case IrOpcode::kSpeculativeNumberBitwiseXor: // Fall through.
case IrOpcode::kNumberBitwiseXor:
return machine()->Word32Xor();
case IrOpcode::kSpeculativeNumberBitwiseAnd: // Fall through.
case IrOpcode::kNumberBitwiseAnd:
return machine()->Word32And();
case IrOpcode::kNumberEqual:
......
......@@ -776,6 +776,23 @@ class RepresentationSelector {
VisitBinop(node, input_use, input_use, output, restriction_type);
}
void VisitSpeculativeInt32Binop(Node* node) {
DCHECK_EQ(2, node->op()->ValueInputCount());
if (BothInputsAre(node, Type::NumberOrOddball())) {
return VisitBinop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
}
BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op());
if (hint == BinaryOperationHints::kSignedSmall ||
hint == BinaryOperationHints::kSigned32) {
return VisitBinop(node, UseInfo::CheckedSigned32AsWord32(),
MachineRepresentation::kWord32);
}
DCHECK_EQ(BinaryOperationHints::kNumberOrOddball, hint);
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsWord32(),
MachineRepresentation::kWord32, Type::Signed32());
}
// Helper for unops of the I -> O variety.
void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) {
DCHECK_EQ(1, node->op()->ValueInputCount());
......@@ -1666,6 +1683,14 @@ class RepresentationSelector {
if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
return;
}
case IrOpcode::kSpeculativeNumberBitwiseOr:
case IrOpcode::kSpeculativeNumberBitwiseXor:
case IrOpcode::kSpeculativeNumberBitwiseAnd:
VisitSpeculativeInt32Binop(node);
if (lower()) {
ChangeToPureOp(node, Int32Op(node));
}
return;
case IrOpcode::kNumberShiftLeft: {
Type* rhs_type = GetUpperBound(node->InputAt(1));
VisitBinop(node, UseInfo::TruncatingWord32(),
......
......@@ -275,7 +275,10 @@ BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) {
op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical);
op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor);
return OpParameter<BinaryOperationHints::Hint>(op);
}
......@@ -365,15 +368,18 @@ CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
V(StringLessThan, Operator::kNoProperties, 2, 0) \
V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0)
#define SPECULATIVE_BINOP_LIST(V) \
V(SpeculativeNumberAdd) \
V(SpeculativeNumberSubtract) \
V(SpeculativeNumberDivide) \
V(SpeculativeNumberMultiply) \
V(SpeculativeNumberModulus) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical)
#define SPECULATIVE_BINOP_LIST(V) \
V(SpeculativeNumberAdd) \
V(SpeculativeNumberSubtract) \
V(SpeculativeNumberDivide) \
V(SpeculativeNumberMultiply) \
V(SpeculativeNumberModulus) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical) \
V(SpeculativeNumberBitwiseAnd) \
V(SpeculativeNumberBitwiseOr) \
V(SpeculativeNumberBitwiseXor)
#define CHECKED_OP_LIST(V) \
V(CheckBounds, 2, 1) \
......
......@@ -245,6 +245,9 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* SpeculativeNumberShiftRight(BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberShiftRightLogical(
BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberBitwiseAnd(BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberBitwiseOr(BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberBitwiseXor(BinaryOperationHints::Hint hint);
const Operator* SpeculativeNumberLessThan(CompareOperationHints::Hint hint);
const Operator* SpeculativeNumberLessThanOrEqual(
......
......@@ -1705,6 +1705,18 @@ Type* Typer::Visitor::TypeSpeculativeNumberShiftRightLogical(Node* node) {
return Type::Unsigned32();
}
Type* Typer::Visitor::TypeSpeculativeNumberBitwiseOr(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeSpeculativeNumberBitwiseXor(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeSpeculativeNumberBitwiseAnd(Node* node) {
return Type::Signed32();
}
Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); }
Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); }
......
......@@ -712,6 +712,11 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 1, Type::Signed32());
CheckUpperIs(node, Type::Signed32());
break;
case IrOpcode::kSpeculativeNumberBitwiseOr:
case IrOpcode::kSpeculativeNumberBitwiseXor:
case IrOpcode::kSpeculativeNumberBitwiseAnd:
CheckUpperIs(node, Type::Signed32());
break;
case IrOpcode::kNumberShiftLeft:
case IrOpcode::kNumberShiftRight:
// (Signed32, Unsigned32) -> Signed32
......
......@@ -1006,6 +1006,72 @@ TEST_F(JSTypedLoweringTest, JSInstanceOfNoSpecialization) {
ASSERT_EQ(instanceOf, dummy->InputAt(0));
}
// -----------------------------------------------------------------------------
// JSBitwiseAnd
TEST_F(JSTypedLoweringTest, JSBitwiseAndWithTypeFeedback) {
BinaryOperationHints::Hint const feedback_types[] = {
BinaryOperationHints::kSignedSmall,
BinaryOperationHints::kNumberOrOddball};
for (BinaryOperationHints::Hint feedback : feedback_types) {
BinaryOperationHints const hints(feedback, feedback, feedback);
Node* lhs = Parameter(Type::Number(), 2);
Node* rhs = Parameter(Type::Number(), 3);
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->BitwiseAnd(hints), lhs, rhs, UndefinedConstant(),
EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseAnd(
feedback, lhs, rhs, effect, control));
}
}
// -----------------------------------------------------------------------------
// JSBitwiseOr
TEST_F(JSTypedLoweringTest, JSBitwiseOrWithTypeFeedback) {
BinaryOperationHints::Hint const feedback_types[] = {
BinaryOperationHints::kSignedSmall,
BinaryOperationHints::kNumberOrOddball};
for (BinaryOperationHints::Hint feedback : feedback_types) {
BinaryOperationHints const hints(feedback, feedback, feedback);
Node* lhs = Parameter(Type::Number(), 2);
Node* rhs = Parameter(Type::Number(), 3);
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->BitwiseOr(hints), lhs, rhs, UndefinedConstant(),
EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseOr(
feedback, lhs, rhs, effect, control));
}
}
// -----------------------------------------------------------------------------
// JSBitwiseXor
TEST_F(JSTypedLoweringTest, JSBitwiseXorWithTypeFeedback) {
BinaryOperationHints::Hint const feedback_types[] = {
BinaryOperationHints::kSignedSmall,
BinaryOperationHints::kNumberOrOddball};
for (BinaryOperationHints::Hint feedback : feedback_types) {
BinaryOperationHints const hints(feedback, feedback, feedback);
Node* lhs = Parameter(Type::Number(), 2);
Node* rhs = Parameter(Type::Number(), 3);
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->BitwiseXor(hints), lhs, rhs, UndefinedConstant(),
EmptyFrameState(), EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseXor(
feedback, lhs, rhs, effect, control));
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -2043,55 +2043,18 @@ Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher,
new IsReferenceEqualMatcher(type_matcher, lhs_matcher, rhs_matcher));
}
Matcher<Node*> IsSpeculativeNumberAdd(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsSpeculativeBinopMatcher(
IrOpcode::kSpeculativeNumberAdd, hint_matcher, lhs_matcher, rhs_matcher,
effect_matcher, control_matcher));
}
Matcher<Node*> IsSpeculativeNumberSubtract(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsSpeculativeBinopMatcher(
IrOpcode::kSpeculativeNumberSubtract, hint_matcher, lhs_matcher,
rhs_matcher, effect_matcher, control_matcher));
}
Matcher<Node*> IsSpeculativeNumberShiftLeft(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsSpeculativeBinopMatcher(
IrOpcode::kSpeculativeNumberShiftLeft, hint_matcher, lhs_matcher,
rhs_matcher, effect_matcher, control_matcher));
}
Matcher<Node*> IsSpeculativeNumberShiftRight(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsSpeculativeBinopMatcher(
IrOpcode::kSpeculativeNumberShiftRight, hint_matcher, lhs_matcher,
rhs_matcher, effect_matcher, control_matcher));
}
Matcher<Node*> IsSpeculativeNumberShiftRightLogical(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsSpeculativeBinopMatcher(
IrOpcode::kSpeculativeNumberShiftRightLogical, hint_matcher, lhs_matcher,
rhs_matcher, effect_matcher, control_matcher));
}
#define DEFINE_SPECULATIVE_BINOP_MATCHER(opcode) \
Matcher<Node*> Is##opcode( \
const Matcher<BinaryOperationHints::Hint>& hint_matcher, \
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, \
const Matcher<Node*>& effect_matcher, \
const Matcher<Node*>& control_matcher) { \
return MakeMatcher(new IsSpeculativeBinopMatcher( \
IrOpcode::k##opcode, hint_matcher, lhs_matcher, rhs_matcher, \
effect_matcher, control_matcher)); \
}
SPECULATIVE_BINOPS(DEFINE_SPECULATIVE_BINOP_MATCHER);
#undef DEFINE_SPECULATIVE_BINOP_MATCHER
Matcher<Node*> IsAllocate(const Matcher<Node*>& size_matcher,
const Matcher<Node*>& effect_matcher,
......
......@@ -34,6 +34,15 @@ class Node;
using ::testing::Matcher;
#define SPECULATIVE_BINOPS(V) \
V(SpeculativeNumberAdd) \
V(SpeculativeNumberSubtract) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical) \
V(SpeculativeNumberBitwiseAnd) \
V(SpeculativeNumberBitwiseOr) \
V(SpeculativeNumberBitwiseXor)
Matcher<Node*> IsDead();
Matcher<Node*> IsEnd(const Matcher<Node*>& control0_matcher);
......@@ -202,31 +211,16 @@ Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsSpeculativeNumberAdd(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsSpeculativeNumberSubtract(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsSpeculativeNumberShiftLeft(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsSpeculativeNumberShiftRight(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsSpeculativeNumberShiftRightLogical(
const Matcher<BinaryOperationHints::Hint>& hint_matcher,
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
#define DECLARE_SPECULATIVE_BINOP_MATCHER(opcode) \
Matcher<Node*> Is##opcode( \
const Matcher<BinaryOperationHints::Hint>& hint_matcher, \
const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher, \
const Matcher<Node*>& effect_matcher, \
const Matcher<Node*>& control_matcher);
SPECULATIVE_BINOPS(DECLARE_SPECULATIVE_BINOP_MATCHER);
#undef DECLARE_SPECULATIVE_BINOP_MATCHER
Matcher<Node*> IsNumberSubtract(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsNumberMultiply(const Matcher<Node*>& lhs_matcher,
......
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