Commit aa4e381b authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[nci] Add feedback vector as input to binary ops

Following up on previous changes for unary ops:
https://crrev.com/c/2246576

Bug: v8:8888
Change-Id: Ie4dd9a307fb0415e93babf412e3d8d9e86791761
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2257227
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68479}
parent 1052dfb3
......@@ -209,6 +209,7 @@ class BytecodeGraphBuilder {
void BuildUnaryOp(const Operator* op);
void BuildBinaryOp(const Operator* op);
void BuildBinaryOpWithImmediate(const Operator* op);
void BuildInstanceOf(const Operator* op);
void BuildCompareOp(const Operator* op);
void BuildDelete(LanguageMode language_mode);
void BuildCastOperator(const Operator* op);
......@@ -2759,6 +2760,7 @@ void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
}
void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()));
PrepareEagerCheckpoint();
Node* operand = environment()->LookupAccumulator();
......@@ -2780,6 +2782,7 @@ void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
}
void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
PrepareEagerCheckpoint();
Node* left =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
......@@ -2796,7 +2799,7 @@ void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
node = lowering.value();
} else {
DCHECK(!lowering.Changed());
node = NewNode(op, left, right);
node = NewNode(op, left, right, feedback_vector_node());
}
environment()->BindAccumulator(node, Environment::kAttachFrameState);
......@@ -2937,6 +2940,7 @@ void BytecodeGraphBuilder::VisitShiftRightLogical() {
}
void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
PrepareEagerCheckpoint();
Node* left = environment()->LookupAccumulator();
Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
......@@ -2952,7 +2956,7 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
node = lowering.value();
} else {
DCHECK(!lowering.Changed());
node = NewNode(op, left, right);
node = NewNode(op, left, right, feedback_vector_node());
}
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
......@@ -3073,7 +3077,9 @@ void BytecodeGraphBuilder::VisitGetSuperConstructor() {
Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
void BytecodeGraphBuilder::BuildInstanceOf(const Operator* op) {
// TODO(jgruber, v8:8888): Treat InstanceOf like other compare ops.
DCHECK_EQ(op->opcode(), IrOpcode::kJSInstanceOf);
PrepareEagerCheckpoint();
Node* left =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
......@@ -3094,6 +3100,28 @@ void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()));
PrepareEagerCheckpoint();
Node* left =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* right = environment()->LookupAccumulator();
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
JSTypeHintLowering::LoweringResult lowering =
TryBuildSimplifiedBinaryOp(op, left, right, slot);
if (lowering.IsExit()) return;
Node* node = nullptr;
if (lowering.IsSideEffectFree()) {
node = lowering.value();
} else {
DCHECK(!lowering.Changed());
node = NewNode(op, left, right, feedback_vector_node());
}
environment()->BindAccumulator(node, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitTestEqual() {
FeedbackSource feedback = CreateFeedbackSource(
bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
......@@ -3151,7 +3179,7 @@ void BytecodeGraphBuilder::VisitTestIn() {
void BytecodeGraphBuilder::VisitTestInstanceOf() {
int const slot_index = bytecode_iterator().GetIndexOperand(1);
BuildCompareOp(javascript()->InstanceOf(CreateFeedbackSource(slot_index)));
BuildInstanceOf(javascript()->InstanceOf(CreateFeedbackSource(slot_index)));
}
void BytecodeGraphBuilder::VisitTestUndetectable() {
......
......@@ -157,65 +157,71 @@ DEF_UNARY_LOWERING(Increment)
DEF_UNARY_LOWERING(Negate)
#undef DEF_UNARY_LOWERING
void JSGenericLowering::ReplaceBinaryOrCompareOpWithBuiltinCall(
void JSGenericLowering::ReplaceBinaryOpWithBuiltinCall(
Node* node, Builtins::Name builtin_without_feedback,
Builtins::Name builtin_with_feedback) {
DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode()));
Builtins::Name builtin_id;
const FeedbackParameter& p = FeedbackParameterOf(node->op());
if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
Node* feedback_vector = jsgraph()->HeapConstant(p.feedback().vector);
Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt());
STATIC_ASSERT(JSBinaryOpNode::LeftIndex() == 0);
STATIC_ASSERT(JSBinaryOpNode::RightIndex() == 1);
STATIC_ASSERT(JSBinaryOpNode::FeedbackVectorIndex() == 2);
DCHECK_EQ(node->op()->ValueInputCount(), 3);
node->InsertInput(zone(), 2, slot);
node->InsertInput(zone(), 3, feedback_vector);
builtin_id = builtin_with_feedback;
} else {
node->RemoveInput(JSBinaryOpNode::FeedbackVectorIndex());
builtin_id = builtin_without_feedback;
}
ReplaceWithBuiltinCall(node, builtin_id);
}
#define DEF_BINARY_OR_COMPARE_LOWERING(Name) \
void JSGenericLowering::LowerJS##Name(Node* node) { \
ReplaceBinaryOrCompareOpWithBuiltinCall(node, Builtins::k##Name, \
Builtins::k##Name##_WithFeedback); \
#define DEF_BINARY_LOWERING(Name) \
void JSGenericLowering::LowerJS##Name(Node* node) { \
ReplaceBinaryOpWithBuiltinCall(node, Builtins::k##Name, \
Builtins::k##Name##_WithFeedback); \
}
// Binary ops.
DEF_BINARY_OR_COMPARE_LOWERING(Add)
DEF_BINARY_OR_COMPARE_LOWERING(BitwiseAnd)
DEF_BINARY_OR_COMPARE_LOWERING(BitwiseOr)
DEF_BINARY_OR_COMPARE_LOWERING(BitwiseXor)
DEF_BINARY_OR_COMPARE_LOWERING(Divide)
DEF_BINARY_OR_COMPARE_LOWERING(Exponentiate)
DEF_BINARY_OR_COMPARE_LOWERING(Modulus)
DEF_BINARY_OR_COMPARE_LOWERING(Multiply)
DEF_BINARY_OR_COMPARE_LOWERING(ShiftLeft)
DEF_BINARY_OR_COMPARE_LOWERING(ShiftRight)
DEF_BINARY_OR_COMPARE_LOWERING(ShiftRightLogical)
DEF_BINARY_OR_COMPARE_LOWERING(Subtract)
DEF_BINARY_LOWERING(Add)
DEF_BINARY_LOWERING(BitwiseAnd)
DEF_BINARY_LOWERING(BitwiseOr)
DEF_BINARY_LOWERING(BitwiseXor)
DEF_BINARY_LOWERING(Divide)
DEF_BINARY_LOWERING(Exponentiate)
DEF_BINARY_LOWERING(Modulus)
DEF_BINARY_LOWERING(Multiply)
DEF_BINARY_LOWERING(ShiftLeft)
DEF_BINARY_LOWERING(ShiftRight)
DEF_BINARY_LOWERING(ShiftRightLogical)
DEF_BINARY_LOWERING(Subtract)
// Compare ops.
DEF_BINARY_OR_COMPARE_LOWERING(Equal)
DEF_BINARY_OR_COMPARE_LOWERING(GreaterThan)
DEF_BINARY_OR_COMPARE_LOWERING(GreaterThanOrEqual)
DEF_BINARY_OR_COMPARE_LOWERING(LessThan)
DEF_BINARY_OR_COMPARE_LOWERING(LessThanOrEqual)
#undef DEF_BINARY_OR_COMPARE_LOWERING
DEF_BINARY_LOWERING(Equal)
DEF_BINARY_LOWERING(GreaterThan)
DEF_BINARY_LOWERING(GreaterThanOrEqual)
DEF_BINARY_LOWERING(LessThan)
DEF_BINARY_LOWERING(LessThanOrEqual)
#undef DEF_BINARY_LOWERING
void JSGenericLowering::LowerJSStrictEqual(Node* node) {
// The === operator doesn't need the current context.
NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
node->RemoveInput(4); // control
node->RemoveInput(NodeProperties::FirstControlIndex(node));
Builtins::Name builtin_id;
const FeedbackParameter& p = FeedbackParameterOf(node->op());
if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
Node* feedback_vector = jsgraph()->HeapConstant(p.feedback().vector);
Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt());
STATIC_ASSERT(JSStrictEqualNode::LeftIndex() == 0);
STATIC_ASSERT(JSStrictEqualNode::RightIndex() == 1);
STATIC_ASSERT(JSStrictEqualNode::FeedbackVectorIndex() == 2);
DCHECK_EQ(node->op()->ValueInputCount(), 3);
node->InsertInput(zone(), 2, slot);
node->InsertInput(zone(), 3, feedback_vector);
builtin_id = Builtins::kStrictEqual_WithFeedback;
} else {
node->RemoveInput(JSStrictEqualNode::FeedbackVectorIndex());
builtin_id = Builtins::kStrictEqual;
}
......@@ -432,6 +438,7 @@ void JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) {
}
void JSGenericLowering::LowerJSInstanceOf(Node* node) {
// TODO(jgruber, v8:8888): Collect feedback.
ReplaceWithBuiltinCall(node, Builtins::kInstanceOf);
}
......
......@@ -48,9 +48,9 @@ class JSGenericLowering final : public AdvancedReducer {
void ReplaceUnaryOpWithBuiltinCall(Node* node,
Builtins::Name builtin_without_feedback,
Builtins::Name builtin_with_feedback);
void ReplaceBinaryOrCompareOpWithBuiltinCall(
Node* node, Builtins::Name builtin_without_feedback,
Builtins::Name builtin_with_feedback);
void ReplaceBinaryOpWithBuiltinCall(Node* node,
Builtins::Name builtin_without_feedback,
Builtins::Name builtin_with_feedback);
Zone* zone() const;
Isolate* isolate() const;
......
......@@ -725,7 +725,7 @@ JS_UNOP_WITH_FEEDBACK(UNARY_OP)
static constexpr auto kProperties = BinopProperties(IrOpcode::k##JSName); \
FeedbackParameter parameters(feedback); \
return new (zone()) Operator1<FeedbackParameter>( \
IrOpcode::k##JSName, kProperties, #JSName, 2, 1, 1, 1, 1, \
IrOpcode::k##JSName, kProperties, #JSName, 3, 1, 1, 1, 1, \
Operator::ZeroIfNoThrow(kProperties), parameters); \
}
JS_BINOP_WITH_FEEDBACK(BINARY_OP)
......
......@@ -81,10 +81,24 @@ class JSUnaryOpNode final : public NodeWrapper {
static constexpr int FeedbackVectorIndex() { return 1; }
};
using JSBitwiseNotNode = JSUnaryOpNode;
using JSDecrementNode = JSUnaryOpNode;
using JSIncrementNode = JSUnaryOpNode;
using JSNegateNode = JSUnaryOpNode;
#define V(JSName, ...) using JSName##Node = JSUnaryOpNode;
JS_UNOP_WITH_FEEDBACK(V)
#undef V
class JSBinaryOpNode final : public NodeWrapper {
public:
explicit constexpr JSBinaryOpNode(Node* node) : NodeWrapper(node) {
CONSTEXPR_DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode()));
}
static constexpr int LeftIndex() { return 0; }
static constexpr int RightIndex() { return 1; }
static constexpr int FeedbackVectorIndex() { return 2; }
};
#define V(JSName, ...) using JSName##Node = JSBinaryOpNode;
JS_BINOP_WITH_FEEDBACK(V)
#undef V
// Defines the frequency a given Call/Construct site was executed. For some
// call sites the frequency is not known.
......
......@@ -270,6 +270,10 @@ class JSBinopReduction final {
}
// Remove the inputs corresponding to context, effect, and control.
NodeProperties::RemoveNonValueInputs(node_);
// Remove the feedback vector input, if applicable.
if (JSOperator::IsBinaryWithFeedback(node_->opcode())) {
node_->RemoveInput(JSBinaryOpNode::FeedbackVectorIndex());
}
// Finally, update the operator to the new one.
NodeProperties::ChangeOp(node_, op);
......@@ -293,7 +297,6 @@ class JSBinopReduction final {
DCHECK_EQ(1, node_->op()->EffectInputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, node_->op()->ControlInputCount());
DCHECK_EQ(2, node_->op()->ValueInputCount());
// Reconnect the control output to bypass the IfSuccess node and
// possibly disconnect from the IfException node.
......@@ -305,6 +308,11 @@ class JSBinopReduction final {
}
node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
// Remove the feedback vector input, if applicable.
if (JSOperator::IsBinaryWithFeedback(node_->opcode())) {
node_->RemoveInput(JSBinaryOpNode::FeedbackVectorIndex());
}
// Finally, update the operator to the new one.
NodeProperties::ChangeOp(node_, op);
// Update the type to number.
......@@ -455,7 +463,6 @@ Reduction JSTypedLowering::ReduceJSBitwiseNot(Node* node) {
if (input_type.Is(Type::PlainPrimitive())) {
// JSBitwiseNot(x) => NumberBitwiseXor(ToInt32(x), -1)
const FeedbackParameter& p = FeedbackParameterOf(node->op());
node->RemoveInput(JSBitwiseNotNode::FeedbackVectorIndex());
node->InsertInput(graph()->zone(), 1, jsgraph()->SmiConstant(-1));
NodeProperties::ChangeOp(node, javascript()->BitwiseXor(p.feedback()));
JSBinopReduction r(this, node);
......@@ -472,7 +479,6 @@ Reduction JSTypedLowering::ReduceJSDecrement(Node* node) {
if (input_type.Is(Type::PlainPrimitive())) {
// JSDecrement(x) => NumberSubtract(ToNumber(x), 1)
const FeedbackParameter& p = FeedbackParameterOf(node->op());
node->RemoveInput(JSDecrementNode::FeedbackVectorIndex());
node->InsertInput(graph()->zone(), 1, jsgraph()->OneConstant());
NodeProperties::ChangeOp(node, javascript()->Subtract(p.feedback()));
JSBinopReduction r(this, node);
......@@ -489,7 +495,6 @@ Reduction JSTypedLowering::ReduceJSIncrement(Node* node) {
if (input_type.Is(Type::PlainPrimitive())) {
// JSIncrement(x) => NumberAdd(ToNumber(x), 1)
const FeedbackParameter& p = FeedbackParameterOf(node->op());
node->RemoveInput(JSIncrementNode::FeedbackVectorIndex());
node->InsertInput(graph()->zone(), 1, jsgraph()->OneConstant());
NodeProperties::ChangeOp(node, javascript()->Add(p.feedback()));
JSBinopReduction r(this, node);
......@@ -506,7 +511,6 @@ Reduction JSTypedLowering::ReduceJSNegate(Node* node) {
if (input_type.Is(Type::PlainPrimitive())) {
// JSNegate(x) => NumberMultiply(ToNumber(x), -1)
const FeedbackParameter& p = FeedbackParameterOf(node->op());
node->RemoveInput(JSNegateNode::FeedbackVectorIndex());
node->InsertInput(graph()->zone(), 1, jsgraph()->SmiConstant(-1));
NodeProperties::ChangeOp(node, javascript()->Multiply(p.feedback()));
JSBinopReduction r(this, node);
......@@ -672,6 +676,7 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
callable.descriptor().GetStackParameterCount(),
CallDescriptor::kNeedsFrameState, properties);
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
node->RemoveInput(JSAddNode::FeedbackVectorIndex());
node->InsertInput(graph()->zone(), 0,
jsgraph()->HeapConstant(callable.code()));
NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
......
......@@ -133,6 +133,9 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
std::vector<Node*> inputs;
inputs.push_back(left);
inputs.push_back(right);
if (JSOperator::IsBinaryWithFeedback(op->opcode())) {
inputs.push_back(UndefinedConstant()); // Feedback vector.
}
if (OperatorProperties::HasContextInput(op)) {
inputs.push_back(context());
}
......@@ -150,6 +153,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
}
Node* Unop(const Operator* op, Node* input) {
DCHECK(!JSOperator::IsUnaryWithFeedback(op->opcode()));
// JS unops also require context, effect, and control
if (OperatorProperties::GetFrameStateInputCount(op) > 0) {
CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(op));
......@@ -703,6 +707,7 @@ TEST(RemoveToNumberEffects) {
JSTypedLoweringTester R;
FeedbackSource feedback_source = FeedbackSourceWithOneBinarySlot(&R);
Node* feedback = R.UndefinedConstant();
Node* effect_use = nullptr;
Node* zero = R.graph.NewNode(R.common.NumberConstant(0));
for (int i = 0; i < 10; i++) {
......@@ -730,11 +735,12 @@ TEST(RemoveToNumberEffects) {
case 3:
effect_use =
R.graph.NewNode(R.javascript.Add(feedback_source), ton, ton,
R.context(), frame_state, ton, R.start());
feedback, R.context(), frame_state, ton, R.start());
break;
case 4:
effect_use = R.graph.NewNode(R.javascript.Add(feedback_source), p0, p0,
R.context(), frame_state, ton, R.start());
effect_use =
R.graph.NewNode(R.javascript.Add(feedback_source), p0, p0, feedback,
R.context(), frame_state, ton, R.start());
break;
case 5:
effect_use =
......
......@@ -186,6 +186,7 @@ FeedbackSource FeedbackSourceWithOneCompareSlot(JSTypedLoweringTest* R) {
TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
Node* const the_hole = HeapConstant(factory()->the_hole_value());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
......@@ -193,7 +194,7 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
Node* const lhs = Parameter(type);
Reduction r = Reduce(graph()->NewNode(
javascript()->StrictEqual(FeedbackSourceWithOneCompareSlot(this)), lhs,
the_hole, context, effect, control));
the_hole, feedback, context, effect, control));
ASSERT_FALSE(r.Changed());
}
}
......@@ -202,12 +203,13 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
Node* const lhs = Parameter(Type::Unique(), 0);
Node* const rhs = Parameter(Type::Unique(), 1);
Node* const feedback = UndefinedConstant();
Node* const context = Parameter(Type::Any(), 2);
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->StrictEqual(FeedbackSourceWithOneCompareSlot(this)), lhs,
rhs, context, effect, control));
rhs, feedback, context, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsReferenceEqual(lhs, rhs));
}
......@@ -218,13 +220,15 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
Node* const lhs = Parameter(Type::Signed32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftLeft(FeedbackSourceWithOneBinarySlot(this)), lhs,
NumberConstant(rhs), context, EmptyFrameState(), effect, control));
NumberConstant(rhs), feedback, context, EmptyFrameState(), effect,
control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsNumberShiftLeft(lhs, IsNumberConstant(BitEq(rhs))));
......@@ -234,12 +238,13 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
Node* const lhs = Parameter(Type::Signed32());
Node* const rhs = Parameter(Type::Unsigned32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftLeft(FeedbackSourceWithOneBinarySlot(this)), lhs, rhs,
context, EmptyFrameState(), effect, control));
feedback, context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberShiftLeft(lhs, rhs));
}
......@@ -251,13 +256,15 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
Node* const lhs = Parameter(Type::Signed32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftRight(FeedbackSourceWithOneBinarySlot(this)), lhs,
NumberConstant(rhs), context, EmptyFrameState(), effect, control));
NumberConstant(rhs), feedback, context, EmptyFrameState(), effect,
control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsNumberShiftRight(lhs, IsNumberConstant(BitEq(rhs))));
......@@ -268,12 +275,13 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
Node* const lhs = Parameter(Type::Signed32());
Node* const rhs = Parameter(Type::Unsigned32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftRight(FeedbackSourceWithOneBinarySlot(this)), lhs, rhs,
context, EmptyFrameState(), effect, control));
feedback, context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberShiftRight(lhs, rhs));
}
......@@ -286,13 +294,15 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
TEST_F(JSTypedLoweringTest,
JSShiftRightLogicalWithUnsigned32AndConstant) {
Node* const lhs = Parameter(Type::Unsigned32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftRightLogical(FeedbackSourceWithOneBinarySlot(this)),
lhs, NumberConstant(rhs), context, EmptyFrameState(), effect, control));
lhs, NumberConstant(rhs), feedback, context, EmptyFrameState(), effect,
control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsNumberShiftRightLogical(lhs, IsNumberConstant(BitEq(rhs))));
......@@ -303,12 +313,13 @@ TEST_F(JSTypedLoweringTest,
TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) {
Node* const lhs = Parameter(Type::Unsigned32());
Node* const rhs = Parameter(Type::Unsigned32());
Node* const feedback = UndefinedConstant();
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
Reduction r = Reduce(graph()->NewNode(
javascript()->ShiftRightLogical(FeedbackSourceWithOneBinarySlot(this)),
lhs, rhs, context, EmptyFrameState(), effect, control));
lhs, rhs, feedback, context, EmptyFrameState(), effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsNumberShiftRightLogical(lhs, rhs));
}
......@@ -408,13 +419,14 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) {
TEST_F(JSTypedLoweringTest, JSAddWithString) {
Node* lhs = Parameter(Type::String(), 0);
Node* rhs = Parameter(Type::String(), 1);
Node* const feedback = UndefinedConstant();
Node* context = Parameter(Type::Any(), 2);
Node* frame_state = EmptyFrameState();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(
graph()->NewNode(javascript()->Add(FeedbackSourceWithOneBinarySlot(this)),
lhs, rhs, context, frame_state, effect, control));
Reduction r = Reduce(graph()->NewNode(
javascript()->Add(FeedbackSourceWithOneBinarySlot(this)), lhs, rhs,
feedback, context, frame_state, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsStringConcat(_, lhs, rhs));
}
......
......@@ -88,6 +88,11 @@ class TyperTest : public TypedGraphTest {
return NodeProperties::GetType(n);
}
Node* UndefinedConstant() {
Handle<HeapObject> value = isolate()->factory()->undefined_value();
return graph()->NewNode(common()->HeapConstant(value));
}
Type TypeBinaryOp(const Operator* op, Type lhs, Type rhs) {
Node* p0 = Parameter(0);
Node* p1 = Parameter(1);
......@@ -96,6 +101,9 @@ class TyperTest : public TypedGraphTest {
std::vector<Node*> inputs;
inputs.push_back(p0);
inputs.push_back(p1);
if (JSOperator::IsBinaryWithFeedback(op->opcode())) {
inputs.push_back(UndefinedConstant()); // Feedback vector.
}
if (OperatorProperties::HasContextInput(op)) {
inputs.push_back(context_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