Commit ddd84088 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[csa] Introduce TrySmi[Add/Sub](TNode<Smi>, TNode<Smi>, Label* if_overflow) helpers.

Bug: v8:7570
Change-Id: I2101a3fed996385b076352d20a2ca4d65c31a828
Reviewed-on: https://chromium-review.googlesource.com/1044374
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53110}
parent ae840508
......@@ -35,14 +35,18 @@ TF_BUILTIN(MathAbs, CodeStubAssembler) {
BIND(&if_xissmi);
{
Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
Node* pair = nullptr;
Label if_overflow(this, Label::kDeferred);
// check if support abs function
if (IsIntPtrAbsWithOverflowSupported()) {
pair = IntPtrAbsWithOverflow(x);
Node* pair = IntPtrAbsWithOverflow(x);
Node* overflow = Projection(1, pair);
Branch(overflow, &if_overflow, &if_notoverflow);
GotoIf(overflow, &if_overflow);
// There is a Smi representation for negated {x}.
Node* result = Projection(0, pair);
Return(BitcastWordToTagged(result));
} else {
// Check if {x} is already positive.
Label if_xispositive(this), if_xisnotpositive(this);
......@@ -58,20 +62,11 @@ TF_BUILTIN(MathAbs, CodeStubAssembler) {
BIND(&if_xisnotpositive);
{
// Try to negate the {x} value.
pair =
IntPtrSubWithOverflow(IntPtrConstant(0), BitcastTaggedToWord(x));
Node* overflow = Projection(1, pair);
Branch(overflow, &if_overflow, &if_notoverflow);
TNode<Smi> result = TrySmiSub(SmiConstant(0), CAST(x), &if_overflow);
Return(result);
}
}
BIND(&if_notoverflow);
{
// There is a Smi representation for negated {x}.
Node* result = Projection(0, pair);
Return(BitcastWordToTagged(result));
}
BIND(&if_overflow);
{ Return(NumberConstant(0.0 - Smi::kMinValue)); }
}
......
......@@ -444,13 +444,9 @@ TF_BUILTIN(Add, AddStubAssembler) {
BIND(&if_right_smi);
{
// Try fast Smi addition first, bail out if it overflows.
Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(left),
BitcastTaggedToWord(right));
Node* overflow = Projection(1, pair);
Label if_overflow(this);
GotoIf(overflow, &if_overflow);
Return(BitcastWordToTaggedSigned(Projection(0, pair)));
TNode<Smi> result = TrySmiAdd(CAST(left), CAST(right), &if_overflow);
Return(result);
BIND(&if_overflow);
{
......@@ -739,12 +735,10 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
BIND(&do_smi_sub);
{
// Try a fast Smi subtraction first, bail out if it overflows.
Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(var_left.value()),
BitcastTaggedToWord(var_right.value()));
Node* overflow = Projection(1, pair);
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
Label if_overflow(this);
TNode<Smi> result = TrySmiSub(CAST(var_left.value()),
CAST(var_right.value()), &if_overflow);
Return(result);
BIND(&if_overflow);
{
......@@ -752,9 +746,6 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
var_right_double.Bind(SmiToFloat64(var_right.value()));
Goto(&do_double_sub);
}
BIND(&if_notoverflow);
Return(BitcastWordToTaggedSigned(Projection(0, pair)));
}
BIND(&do_double_sub);
......
......@@ -565,6 +565,26 @@ TNode<Smi> CodeStubAssembler::SmiMin(SloppyTNode<Smi> a, SloppyTNode<Smi> b) {
return SelectConstant<Smi>(SmiLessThan(a, b), a, b);
}
TNode<Smi> CodeStubAssembler::TrySmiAdd(TNode<Smi> lhs, TNode<Smi> rhs,
Label* if_overflow) {
TNode<PairT<IntPtrT, BoolT>> pair =
IntPtrAddWithOverflow(BitcastTaggedToWord(lhs), BitcastTaggedToWord(rhs));
TNode<BoolT> overflow = Projection<1>(pair);
GotoIf(overflow, if_overflow);
TNode<IntPtrT> result = Projection<0>(pair);
return BitcastWordToTaggedSigned(result);
}
TNode<Smi> CodeStubAssembler::TrySmiSub(TNode<Smi> lhs, TNode<Smi> rhs,
Label* if_overflow) {
TNode<PairT<IntPtrT, BoolT>> pair =
IntPtrSubWithOverflow(BitcastTaggedToWord(lhs), BitcastTaggedToWord(rhs));
TNode<BoolT> overflow = Projection<1>(pair);
GotoIf(overflow, if_overflow);
TNode<IntPtrT> result = Projection<0>(pair);
return BitcastWordToTaggedSigned(result);
}
TNode<Object> CodeStubAssembler::NumberMax(SloppyTNode<Object> a,
SloppyTNode<Object> b) {
// TODO(danno): This could be optimized by specifically handling smi cases.
......@@ -10981,23 +11001,14 @@ TNode<Number> CodeStubAssembler::NumberInc(SloppyTNode<Number> value) {
BIND(&if_issmi);
{
// Try fast Smi addition first.
Label if_overflow(this);
TNode<Smi> smi_value = CAST(value);
TNode<Smi> one = SmiConstant(1);
TNode<PairT<IntPtrT, BoolT>> pair = IntPtrAddWithOverflow(
BitcastTaggedToWord(value), BitcastTaggedToWord(one));
TNode<BoolT> overflow = Projection<1>(pair);
// Check if the Smi addition overflowed.
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
BIND(&if_notoverflow);
var_result = BitcastWordToTaggedSigned(Projection<0>(pair));
var_result = TrySmiAdd(smi_value, one, &if_overflow);
Goto(&end);
BIND(&if_overflow);
{
TNode<Smi> smi_value = CAST(value);
var_finc_value = SmiToFloat64(smi_value);
Goto(&do_finc);
}
......@@ -11033,23 +11044,14 @@ TNode<Number> CodeStubAssembler::NumberDec(SloppyTNode<Number> value) {
BIND(&if_issmi);
{
// Try fast Smi subtraction first.
TNode<Smi> smi_value = CAST(value);
TNode<Smi> one = SmiConstant(1);
TNode<PairT<IntPtrT, BoolT>> pair = IntPtrSubWithOverflow(
BitcastTaggedToWord(value), BitcastTaggedToWord(one));
TNode<BoolT> overflow = Projection<1>(pair);
// Check if the Smi subtraction overflowed.
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
BIND(&if_notoverflow);
var_result = BitcastWordToTaggedSigned(Projection<0>(pair));
Label if_overflow(this);
var_result = TrySmiSub(smi_value, one, &if_overflow);
Goto(&end);
BIND(&if_overflow);
{
TNode<Smi> smi_value = CAST(value);
var_fdec_value = SmiToFloat64(smi_value);
Goto(&do_fdec);
}
......@@ -11085,15 +11087,7 @@ TNode<Number> CodeStubAssembler::NumberAdd(SloppyTNode<Number> a,
GotoIf(TaggedIsNotSmi(b), &float_add);
// Try fast Smi addition first.
TNode<PairT<IntPtrT, BoolT>> pair =
IntPtrAddWithOverflow(BitcastTaggedToWord(a), BitcastTaggedToWord(b));
TNode<BoolT> overflow = Projection<1>(pair);
// Check if the Smi addition overflowed.
Label if_overflow(this), if_notoverflow(this);
GotoIf(overflow, &float_add);
var_result = BitcastWordToTaggedSigned(Projection<0>(pair));
var_result = TrySmiAdd(CAST(a), CAST(b), &float_add);
Goto(&end);
BIND(&float_add);
......@@ -11115,15 +11109,7 @@ TNode<Number> CodeStubAssembler::NumberSub(SloppyTNode<Number> a,
GotoIf(TaggedIsNotSmi(b), &float_sub);
// Try fast Smi subtraction first.
TNode<PairT<IntPtrT, BoolT>> pair =
IntPtrSubWithOverflow(BitcastTaggedToWord(a), BitcastTaggedToWord(b));
TNode<BoolT> overflow = Projection<1>(pair);
// Check if the Smi subtraction overflowed.
Label if_overflow(this), if_notoverflow(this);
GotoIf(overflow, &float_sub);
var_result = BitcastWordToTaggedSigned(Projection<0>(pair));
var_result = TrySmiSub(CAST(a), CAST(b), &float_sub);
Goto(&end);
BIND(&float_sub);
......
......@@ -285,6 +285,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
SMI_ARITHMETIC_BINOP(SmiOr, WordOr)
#undef SMI_ARITHMETIC_BINOP
TNode<Smi> TrySmiAdd(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
TNode<Smi> TrySmiSub(TNode<Smi> a, TNode<Smi> b, Label* if_overflow);
Node* SmiShl(Node* a, int shift) {
return BitcastWordToTaggedSigned(WordShl(BitcastTaggedToWord(a), shift));
}
......
......@@ -58,20 +58,20 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs,
{
Comment("perform smi operation");
// Try fast Smi addition first.
Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(lhs),
BitcastTaggedToWord(rhs));
Node* overflow = Projection(1, pair);
// Check if the Smi additon overflowed.
// If rhs is known to be an Smi we want to fast path Smi operation. This
// is for AddSmi operation. For the normal Add operation, we want to fast
// path both Smi and Number operations, so this path should not be marked
// as Deferred.
Label if_overflow(this,
rhs_is_smi ? Label::kDeferred : Label::kNonDeferred),
if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
TNode<Smi> smi_result = TrySmiAdd(CAST(lhs), CAST(rhs), &if_overflow);
// Not overflowed.
{
var_type_feedback.Bind(
SmiConstant(BinaryOperationFeedback::kSignedSmall));
var_result.Bind(smi_result);
Goto(&end);
}
BIND(&if_overflow);
{
......@@ -79,14 +79,6 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs,
var_fadd_rhs.Bind(SmiToFloat64(rhs));
Goto(&do_fadd);
}
BIND(&if_notoverflow);
{
var_type_feedback.Bind(
SmiConstant(BinaryOperationFeedback::kSignedSmall));
var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
Goto(&end);
}
}
}
......@@ -416,34 +408,22 @@ Node* BinaryOpAssembler::Generate_SubtractWithFeedback(Node* context, Node* lhs,
Node* feedback_vector,
bool rhs_is_smi) {
auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) {
VARIABLE(var_result, MachineRepresentation::kTagged);
// Try a fast Smi subtraction first.
Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(lhs),
BitcastTaggedToWord(rhs));
Node* overflow = Projection(1, pair);
// Check if the Smi subtraction overflowed.
Label if_notoverflow(this), end(this);
Label end(this);
TVARIABLE(Number, var_result);
// If rhs is known to be an Smi (for SubSmi) we want to fast path Smi
// operation. For the normal Sub operation, we want to fast path both
// Smi and Number operations, so this path should not be marked as Deferred.
Label if_overflow(this,
rhs_is_smi ? Label::kDeferred : Label::kNonDeferred);
Branch(overflow, &if_overflow, &if_notoverflow);
BIND(&if_notoverflow);
{
var_type_feedback->Bind(
SmiConstant(BinaryOperationFeedback::kSignedSmall));
var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
Goto(&end);
}
var_result = TrySmiSub(CAST(lhs), CAST(rhs), &if_overflow);
var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
Goto(&end);
BIND(&if_overflow);
{
var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumber));
Node* value = Float64Sub(SmiToFloat64(lhs), SmiToFloat64(rhs));
var_result.Bind(AllocateHeapNumberWithValue(value));
var_result = AllocateHeapNumberWithValue(value);
Goto(&end);
}
......
......@@ -1322,17 +1322,13 @@ class IncDecAssembler : public UnaryNumericOpAssembler {
Node* SmiOp(Node* smi_value, Variable* var_feedback, Label* do_float_op,
Variable* var_float) override {
// Try fast Smi operation first.
Node* value = BitcastTaggedToWord(smi_value);
Node* one = BitcastTaggedToWord(SmiConstant(1));
Node* pair = op() == Operation::kIncrement
? IntPtrAddWithOverflow(value, one)
: IntPtrSubWithOverflow(value, one);
Node* overflow = Projection(1, pair);
// Check if the Smi operation overflowed.
TNode<Smi> value = CAST(smi_value);
TNode<Smi> one = SmiConstant(1);
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
TNode<Smi> result = op() == Operation::kIncrement
? TrySmiAdd(value, one, &if_overflow)
: TrySmiSub(value, one, &if_overflow);
Goto(&if_notoverflow);
BIND(&if_overflow);
{
......@@ -1342,7 +1338,7 @@ class IncDecAssembler : public UnaryNumericOpAssembler {
BIND(&if_notoverflow);
CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
return BitcastWordToTaggedSigned(Projection(0, pair));
return result;
}
Node* FloatOp(Node* float_value) override {
......
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