Commit 712f800e authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

[baseline] Improve BitwiseBinaryOp with Smi rhs

Baseline compiler generates calls to builtin Bitwise_Baseline for
bitwise bytecodes with Smi rhs. The builtin still performs type check
for rhs even though it is known to be Smi.

This CL implements new builtins for bitwise operations which does not do
speculation for rhs.

Bug: v8:12442
Change-Id: Ia6e1b25a74d00db8c39600b4f81f6e9aa5d59253
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3310520Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Cr-Commit-Position: refs/heads/main@{#78206}
parent c1e3a5db
......@@ -1073,32 +1073,32 @@ void BaselineCompiler::VisitExpSmi() {
}
void BaselineCompiler::VisitBitwiseOrSmi() {
CallBuiltin<Builtin::kBitwiseOr_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
CallBuiltin<Builtin::kBitwiseOrSmi_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
}
void BaselineCompiler::VisitBitwiseXorSmi() {
CallBuiltin<Builtin::kBitwiseXor_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
CallBuiltin<Builtin::kBitwiseXorSmi_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
}
void BaselineCompiler::VisitBitwiseAndSmi() {
CallBuiltin<Builtin::kBitwiseAnd_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
CallBuiltin<Builtin::kBitwiseAndSmi_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
}
void BaselineCompiler::VisitShiftLeftSmi() {
CallBuiltin<Builtin::kShiftLeft_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
CallBuiltin<Builtin::kShiftLeftSmi_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
}
void BaselineCompiler::VisitShiftRightSmi() {
CallBuiltin<Builtin::kShiftRight_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
CallBuiltin<Builtin::kShiftRightSmi_Baseline>(kInterpreterAccumulatorRegister,
IntAsSmi(0), Index(1));
}
void BaselineCompiler::VisitShiftRightLogicalSmi() {
CallBuiltin<Builtin::kShiftRightLogical_Baseline>(
CallBuiltin<Builtin::kShiftRightLogicalSmi_Baseline>(
kInterpreterAccumulatorRegister, IntAsSmi(0), Index(1));
}
......
......@@ -716,11 +716,17 @@ namespace internal {
TFC(Exponentiate_Baseline, BinaryOp_Baseline) \
TFC(ExponentiateSmi_Baseline, BinaryOp_Baseline) \
TFC(BitwiseAnd_Baseline, BinaryOp_Baseline) \
TFC(BitwiseAndSmi_Baseline, BinaryOp_Baseline) \
TFC(BitwiseOr_Baseline, BinaryOp_Baseline) \
TFC(BitwiseOrSmi_Baseline, BinaryOp_Baseline) \
TFC(BitwiseXor_Baseline, BinaryOp_Baseline) \
TFC(BitwiseXorSmi_Baseline, BinaryOp_Baseline) \
TFC(ShiftLeft_Baseline, BinaryOp_Baseline) \
TFC(ShiftLeftSmi_Baseline, BinaryOp_Baseline) \
TFC(ShiftRight_Baseline, BinaryOp_Baseline) \
TFC(ShiftRightSmi_Baseline, BinaryOp_Baseline) \
TFC(ShiftRightLogical_Baseline, BinaryOp_Baseline) \
TFC(ShiftRightLogicalSmi_Baseline, BinaryOp_Baseline) \
\
TFC(Add_WithFeedback, BinaryOp_WithFeedback) \
TFC(Subtract_WithFeedback, BinaryOp_WithFeedback) \
......
......@@ -94,6 +94,13 @@ DEF_BINOP_RHS_SMI(MultiplySmi_Baseline, Generate_MultiplyWithFeedback)
DEF_BINOP_RHS_SMI(DivideSmi_Baseline, Generate_DivideWithFeedback)
DEF_BINOP_RHS_SMI(ModulusSmi_Baseline, Generate_ModulusWithFeedback)
DEF_BINOP_RHS_SMI(ExponentiateSmi_Baseline, Generate_ExponentiateWithFeedback)
DEF_BINOP_RHS_SMI(BitwiseOrSmi_Baseline, Generate_BitwiseOrWithFeedback)
DEF_BINOP_RHS_SMI(BitwiseXorSmi_Baseline, Generate_BitwiseXorWithFeedback)
DEF_BINOP_RHS_SMI(BitwiseAndSmi_Baseline, Generate_BitwiseAndWithFeedback)
DEF_BINOP_RHS_SMI(ShiftLeftSmi_Baseline, Generate_ShiftLeftWithFeedback)
DEF_BINOP_RHS_SMI(ShiftRightSmi_Baseline, Generate_ShiftRightWithFeedback)
DEF_BINOP_RHS_SMI(ShiftRightLogicalSmi_Baseline,
Generate_ShiftRightLogicalWithFeedback)
#undef DEF_BINOP_RHS_SMI
#define DEF_UNOP(Name, Generator) \
......
......@@ -674,5 +674,40 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
return result.value();
}
TNode<Object>
BinaryOpAssembler::Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
const LazyNode<Context>& context, TVariable<Smi>* feedback) {
TNode<Smi> right_smi = CAST(right);
TVARIABLE(Object, result);
TVARIABLE(Smi, var_left_feedback);
TVARIABLE(Word32T, var_left_word32);
TVARIABLE(BigInt, var_left_bigint);
Label do_smi_op(this), if_bigint_mix(this, Label::kDeferred), done(this);
TaggedToWord32OrBigIntWithFeedback(context(), left, &do_smi_op,
&var_left_word32, &if_bigint_mix,
&var_left_bigint, &var_left_feedback);
BIND(&do_smi_op);
result =
BitwiseOp(var_left_word32.value(), SmiToInt32(right_smi), bitwise_op);
if (feedback) {
TNode<Smi> result_type = SelectSmiConstant(
TaggedIsSmi(result.value()), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber);
*feedback = SmiOr(result_type, var_left_feedback.value());
}
Goto(&done);
BIND(&if_bigint_mix);
if (feedback) {
*feedback = var_left_feedback.value();
}
ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
BIND(&done);
return result.value();
}
} // namespace internal
} // namespace v8
......@@ -56,10 +56,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_BitwiseOrWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseOr, left, right, context, &feedback);
Operation::kBitwiseOr, left, right, context, &feedback, rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -68,10 +68,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_BitwiseXorWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseXor, left, right, context, &feedback);
Operation::kBitwiseXor, left, right, context, &feedback, rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -80,10 +80,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_BitwiseAndWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseAnd, left, right, context, &feedback);
Operation::kBitwiseAnd, left, right, context, &feedback, rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -92,10 +92,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_ShiftLeftWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftLeft, left, right, context, &feedback);
Operation::kShiftLeft, left, right, context, &feedback, rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -104,10 +104,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_ShiftRightWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftRight, left, right, context, &feedback);
Operation::kShiftRight, left, right, context, &feedback, rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -116,10 +116,11 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_ShiftRightLogicalWithFeedback(
const LazyNode<Context>& context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, const LazyNode<HeapObject>& maybe_feedback_vector,
UpdateFeedbackMode update_feedback_mode, bool /* unused */) {
UpdateFeedbackMode update_feedback_mode, bool rhs_known_smi) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftRightLogical, left, right, context, &feedback);
Operation::kShiftRightLogical, left, right, context, &feedback,
rhs_known_smi);
UpdateFeedback(feedback.value(), maybe_feedback_vector(), slot,
update_feedback_mode);
return result;
......@@ -127,9 +128,13 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_BitwiseBinaryOpWithFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
const LazyNode<Context>& context, TVariable<Smi>* feedback) {
return Generate_BitwiseBinaryOpWithOptionalFeedback(bitwise_op, left, right,
context, feedback);
const LazyNode<Context>& context, TVariable<Smi>* feedback,
bool rhs_known_smi) {
return rhs_known_smi
? Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
bitwise_op, left, right, context, feedback)
: Generate_BitwiseBinaryOpWithOptionalFeedback(
bitwise_op, left, right, context, feedback);
}
TNode<Object> Generate_BitwiseBinaryOp(Operation bitwise_op,
......@@ -156,6 +161,10 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<Object> Generate_BitwiseBinaryOpWithOptionalFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
const LazyNode<Context>& context, TVariable<Smi>* feedback);
TNode<Object> Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
Operation bitwise_op, TNode<Object> left, TNode<Object> right,
const LazyNode<Context>& context, TVariable<Smi>* feedback);
};
} // namespace internal
......
......@@ -999,7 +999,7 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
BinaryOpAssembler binop_asm(state());
TNode<Object> result = binop_asm.Generate_BitwiseBinaryOpWithFeedback(
bitwise_op, left, right, [=] { return context; }, &feedback);
bitwise_op, left, right, [=] { return context; }, &feedback, false);
MaybeUpdateFeedback(feedback.value(), maybe_feedback_vector, slot_index);
SetAccumulator(result);
......@@ -1013,29 +1013,15 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler {
TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector();
TNode<Context> context = GetContext();
TVARIABLE(Smi, var_left_feedback);
TVARIABLE(Word32T, var_left_word32);
TVARIABLE(BigInt, var_left_bigint);
Label do_smi_op(this), if_bigint_mix(this);
TaggedToWord32OrBigIntWithFeedback(context, left, &do_smi_op,
&var_left_word32, &if_bigint_mix,
&var_left_bigint, &var_left_feedback);
BIND(&do_smi_op);
TNode<Number> result =
BitwiseOp(var_left_word32.value(), SmiToInt32(right), bitwise_op);
TNode<Smi> result_type = SelectSmiConstant(
TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber);
MaybeUpdateFeedback(SmiOr(result_type, var_left_feedback.value()),
maybe_feedback_vector, slot_index);
TVARIABLE(Smi, feedback);
BinaryOpAssembler binop_asm(state());
TNode<Object> result = binop_asm.Generate_BitwiseBinaryOpWithFeedback(
bitwise_op, left, right, [=] { return context; }, &feedback, true);
MaybeUpdateFeedback(feedback.value(), maybe_feedback_vector, slot_index);
SetAccumulator(result);
Dispatch();
BIND(&if_bigint_mix);
MaybeUpdateFeedback(var_left_feedback.value(), maybe_feedback_vector,
slot_index);
ThrowTypeError(context, MessageTemplate::kBigIntMixedTypes);
}
};
......
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