[maglev] Add Int32 Negate, Increment and Decrement
Drive-by: delete repeated DEF_OPERATION_NODE macro. Bug: v8:7700 Change-Id: Ie98e7166c9dafe802049b10c57831fae3e652e40 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4051244 Auto-Submit: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#84446}
This commit is contained in:
parent
b8f0d2d351
commit
9476523b59
@ -384,8 +384,12 @@ constexpr bool BinaryOperationHasInt32FastPath() {
|
||||
case Operation::kLessThanOrEqual:
|
||||
case Operation::kGreaterThan:
|
||||
case Operation::kGreaterThanOrEqual:
|
||||
case Operation::kDecrement:
|
||||
case Operation::kIncrement:
|
||||
case Operation::kNegate:
|
||||
return true;
|
||||
case Operation::kExponentiate:
|
||||
case Operation::kBitwiseNot:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -409,19 +413,24 @@ constexpr bool BinaryOperationHasFloat64FastPath() {
|
||||
// - Int32 operation node,
|
||||
// - Identity of int32 operation (e.g, 0 for add/sub and 1 for mul/div), if it
|
||||
// exists, or otherwise {}.
|
||||
#define MAP_OPERATION_TO_INT32_NODE(V) \
|
||||
V(Add, Int32AddWithOverflow, 0) \
|
||||
V(Subtract, Int32SubtractWithOverflow, 0) \
|
||||
V(Multiply, Int32MultiplyWithOverflow, 1) \
|
||||
V(Divide, Int32DivideWithOverflow, 1) \
|
||||
V(Modulus, Int32ModulusWithOverflow, {}) \
|
||||
V(BitwiseAnd, Int32BitwiseAnd, ~0) \
|
||||
V(BitwiseOr, Int32BitwiseOr, 0) \
|
||||
V(BitwiseXor, Int32BitwiseXor, 0) \
|
||||
V(ShiftLeft, Int32ShiftLeft, 0) \
|
||||
V(ShiftRight, Int32ShiftRight, 0) \
|
||||
#define MAP_BINARY_OPERATION_TO_INT32_NODE(V) \
|
||||
V(Add, Int32AddWithOverflow, 0) \
|
||||
V(Subtract, Int32SubtractWithOverflow, 0) \
|
||||
V(Multiply, Int32MultiplyWithOverflow, 1) \
|
||||
V(Divide, Int32DivideWithOverflow, 1) \
|
||||
V(Modulus, Int32ModulusWithOverflow, {}) \
|
||||
V(BitwiseAnd, Int32BitwiseAnd, ~0) \
|
||||
V(BitwiseOr, Int32BitwiseOr, 0) \
|
||||
V(BitwiseXor, Int32BitwiseXor, 0) \
|
||||
V(ShiftLeft, Int32ShiftLeft, 0) \
|
||||
V(ShiftRight, Int32ShiftRight, 0) \
|
||||
V(ShiftRightLogical, Int32ShiftRightLogical, {})
|
||||
|
||||
#define MAP_UNARY_OPERATION_TO_INT32_NODE(V) \
|
||||
V(Increment, Int32IncrementWithOverflow) \
|
||||
V(Decrement, Int32DecrementWithOverflow) \
|
||||
V(Negate, Int32NegateWithOverflow)
|
||||
|
||||
#define MAP_COMPARE_OPERATION_TO_INT32_NODE(V) \
|
||||
V(Equal, Int32Equal) \
|
||||
V(StrictEqual, Int32StrictEqual) \
|
||||
@ -444,7 +453,7 @@ static constexpr base::Optional<int> Int32Identity() {
|
||||
#define CASE(op, _, identity) \
|
||||
case Operation::k##op: \
|
||||
return identity;
|
||||
MAP_OPERATION_TO_INT32_NODE(CASE)
|
||||
MAP_BINARY_OPERATION_TO_INT32_NODE(CASE)
|
||||
#undef CASE
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -459,7 +468,8 @@ struct Int32NodeForHelper;
|
||||
struct Int32NodeForHelper<Operation::k##op> { \
|
||||
using type = OpNode; \
|
||||
};
|
||||
MAP_OPERATION_TO_INT32_NODE(SPECIALIZATION)
|
||||
MAP_UNARY_OPERATION_TO_INT32_NODE(SPECIALIZATION)
|
||||
MAP_BINARY_OPERATION_TO_INT32_NODE(SPECIALIZATION)
|
||||
MAP_COMPARE_OPERATION_TO_INT32_NODE(SPECIALIZATION)
|
||||
#undef SPECIALIZATION
|
||||
|
||||
@ -507,6 +517,21 @@ void MaglevGraphBuilder::BuildGenericBinarySmiOperationNode() {
|
||||
{left, right}, compiler::FeedbackSource{feedback(), slot_index}));
|
||||
}
|
||||
|
||||
template <Operation kOperation>
|
||||
void MaglevGraphBuilder::BuildInt32UnaryOperationNode() {
|
||||
// TODO(victorgomes): Get the TruncatedInt32 version when we support
|
||||
// BitwiseNot.
|
||||
ValueNode* value = GetAccumulatorInt32();
|
||||
using OpNodeT = Int32NodeFor<kOperation>;
|
||||
OpNodeT* result = AddNewNode<OpNodeT>({value});
|
||||
NodeInfo* node_info = known_node_aspects().GetOrCreateInfoFor(result);
|
||||
node_info->type = NodeType::kSmi;
|
||||
static_assert(OpNodeT::kProperties.value_representation() ==
|
||||
ValueRepresentation::kInt32);
|
||||
node_info->tagged_alternative = AddNewNode<CheckedSmiTagInt32>({result});
|
||||
SetAccumulator(result);
|
||||
}
|
||||
|
||||
template <Operation kOperation>
|
||||
ValueNode* MaglevGraphBuilder::TryFoldInt32BinaryOperation(ValueNode* left,
|
||||
ValueNode* right) {
|
||||
@ -688,7 +713,20 @@ void MaglevGraphBuilder::BuildFloat64BinaryOperationNode() {
|
||||
|
||||
template <Operation kOperation>
|
||||
void MaglevGraphBuilder::VisitUnaryOperation() {
|
||||
// TODO(victorgomes): Use feedback info and create optimized versions.
|
||||
FeedbackNexus nexus = FeedbackNexusForOperand(0);
|
||||
switch (nexus.GetBinaryOperationFeedback()) {
|
||||
case BinaryOperationHint::kNone:
|
||||
return EmitUnconditionalDeopt(
|
||||
DeoptimizeReason::kInsufficientTypeFeedbackForBinaryOperation);
|
||||
case BinaryOperationHint::kSignedSmall:
|
||||
if constexpr (BinaryOperationHasInt32FastPath<kOperation>()) {
|
||||
return BuildInt32UnaryOperationNode<kOperation>();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Fallback to generic node.
|
||||
break;
|
||||
}
|
||||
BuildGenericUnaryOperationNode<kOperation>();
|
||||
}
|
||||
|
||||
|
@ -1306,6 +1306,8 @@ class MaglevGraphBuilder {
|
||||
template <Operation kOperation>
|
||||
ValueNode* TryFoldInt32BinaryOperation(ValueNode* left, int right);
|
||||
|
||||
template <Operation kOperation>
|
||||
void BuildInt32UnaryOperationNode();
|
||||
template <Operation kOperation>
|
||||
void BuildInt32BinaryOperationNode();
|
||||
template <Operation kOperation>
|
||||
|
@ -180,6 +180,9 @@ class MaglevGraphVerifier {
|
||||
case Opcode::kChangeInt32ToFloat64:
|
||||
case Opcode::kInt32ToNumber:
|
||||
case Opcode::kBuiltinStringFromCharCode:
|
||||
case Opcode::kInt32IncrementWithOverflow:
|
||||
case Opcode::kInt32DecrementWithOverflow:
|
||||
case Opcode::kInt32NegateWithOverflow:
|
||||
DCHECK_EQ(node->input_count(), 1);
|
||||
CheckValueInputIs(node, 0, ValueRepresentation::kInt32);
|
||||
break;
|
||||
|
@ -3042,6 +3042,45 @@ void Int32ShiftRightLogical::GenerateCode(MaglevAssembler* masm,
|
||||
__ shrl_cl(left);
|
||||
}
|
||||
|
||||
void Int32IncrementWithOverflow::AllocateVreg(
|
||||
MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(value_input());
|
||||
DefineSameAsFirst(vreg_state, this);
|
||||
}
|
||||
|
||||
void Int32IncrementWithOverflow::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(value_input());
|
||||
__ incl(value);
|
||||
__ EmitEagerDeoptIf(overflow, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
void Int32DecrementWithOverflow::AllocateVreg(
|
||||
MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(value_input());
|
||||
DefineSameAsFirst(vreg_state, this);
|
||||
}
|
||||
|
||||
void Int32DecrementWithOverflow::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(value_input());
|
||||
__ decl(value);
|
||||
__ EmitEagerDeoptIf(overflow, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
void Int32NegateWithOverflow::AllocateVreg(
|
||||
MaglevVregAllocationState* vreg_state) {
|
||||
UseRegister(value_input());
|
||||
DefineSameAsFirst(vreg_state, this);
|
||||
}
|
||||
|
||||
void Int32NegateWithOverflow::GenerateCode(MaglevAssembler* masm,
|
||||
const ProcessingState& state) {
|
||||
Register value = ToRegister(value_input());
|
||||
__ negl(value);
|
||||
__ EmitEagerDeoptIf(overflow, DeoptimizeReason::kOverflow, this);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr Condition ConditionFor(Operation operation) {
|
||||
|
@ -86,9 +86,9 @@ class CompactInterpreterFrameState;
|
||||
V(Int32ShiftRight) \
|
||||
V(Int32ShiftRightLogical) \
|
||||
/*V(Int32BitwiseNot) */ \
|
||||
/*V(Int32NegateWithOverflow) */ \
|
||||
/*V(Int32IncrementWithOverflow)*/ \
|
||||
/*V(Int32DecrementWithOverflow)*/ \
|
||||
V(Int32NegateWithOverflow) \
|
||||
V(Int32IncrementWithOverflow) \
|
||||
V(Int32DecrementWithOverflow) \
|
||||
V(Int32Equal) \
|
||||
V(Int32StrictEqual) \
|
||||
V(Int32LessThan) \
|
||||
@ -1642,7 +1642,7 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> {
|
||||
const compiler::FeedbackSource feedback_;
|
||||
};
|
||||
|
||||
#define DEF_OPERATION_NODE(Name, Super, OpName) \
|
||||
#define DEF_OPERATION_WITH_FEEDBACK_NODE(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
@ -1655,16 +1655,15 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> {
|
||||
};
|
||||
|
||||
#define DEF_UNARY_WITH_FEEDBACK_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Generic##Name, UnaryWithFeedbackNode, Name)
|
||||
DEF_OPERATION_WITH_FEEDBACK_NODE(Generic##Name, UnaryWithFeedbackNode, Name)
|
||||
#define DEF_BINARY_WITH_FEEDBACK_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Generic##Name, BinaryWithFeedbackNode, Name)
|
||||
DEF_OPERATION_WITH_FEEDBACK_NODE(Generic##Name, BinaryWithFeedbackNode, Name)
|
||||
UNARY_OPERATION_LIST(DEF_UNARY_WITH_FEEDBACK_NODE)
|
||||
ARITHMETIC_OPERATION_LIST(DEF_BINARY_WITH_FEEDBACK_NODE)
|
||||
COMPARISON_OPERATION_LIST(DEF_BINARY_WITH_FEEDBACK_NODE)
|
||||
#undef DEF_UNARY_WITH_FEEDBACK_NODE
|
||||
#undef DEF_BINARY_WITH_FEEDBACK_NODE
|
||||
|
||||
#undef DEF_OPERATION_NODE
|
||||
#undef DEF_OPERATION_WITH_FEEDBACK_NODE
|
||||
|
||||
template <class Derived, Operation kOperation>
|
||||
class Int32BinaryWithOverflowNode : public FixedInputValueNodeT<2, Derived> {
|
||||
@ -1723,17 +1722,6 @@ class Int32BinaryNode : public FixedInputValueNodeT<2, Derived> {
|
||||
explicit Int32BinaryNode(uint64_t bitfield) : Base(bitfield) {}
|
||||
};
|
||||
|
||||
#define DEF_OPERATION_NODE(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
public: \
|
||||
explicit Name(uint64_t bitfield) : Base(bitfield) {} \
|
||||
void AllocateVreg(MaglevVregAllocationState*); \
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||
};
|
||||
|
||||
#define DEF_INT32_BINARY_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Int32##Name, Int32BinaryNode, Name)
|
||||
DEF_INT32_BINARY_NODE(BitwiseAnd)
|
||||
@ -1742,9 +1730,29 @@ DEF_INT32_BINARY_NODE(BitwiseXor)
|
||||
DEF_INT32_BINARY_NODE(ShiftLeft)
|
||||
DEF_INT32_BINARY_NODE(ShiftRight)
|
||||
#undef DEF_INT32_BINARY_NODE
|
||||
// DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Negate)
|
||||
// DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Increment)
|
||||
// DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Decrement)
|
||||
|
||||
template <class Derived, Operation kOperation>
|
||||
class Int32UnaryWithOverflowNode : public FixedInputValueNodeT<1, Derived> {
|
||||
using Base = FixedInputValueNodeT<1, Derived>;
|
||||
|
||||
public:
|
||||
static constexpr OpProperties kProperties =
|
||||
OpProperties::EagerDeopt() | OpProperties::Int32();
|
||||
|
||||
static constexpr int kValueIndex = 0;
|
||||
Input& value_input() { return Node::input(kValueIndex); }
|
||||
|
||||
protected:
|
||||
explicit Int32UnaryWithOverflowNode(uint64_t bitfield) : Base(bitfield) {}
|
||||
};
|
||||
|
||||
#define DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Int32##Name##WithOverflow, Int32UnaryWithOverflowNode, \
|
||||
Name)
|
||||
DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Negate)
|
||||
DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Increment)
|
||||
DEF_INT32_UNARY_WITH_OVERFLOW_NODE(Decrement)
|
||||
#undef DEF_INT32_UNARY_WITH_OVERFLOW_NODE
|
||||
|
||||
class Int32ShiftRightLogical
|
||||
: public FixedInputValueNodeT<2, Int32ShiftRightLogical> {
|
||||
@ -1784,17 +1792,6 @@ class Int32CompareNode : public FixedInputValueNodeT<2, Derived> {
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
||||
};
|
||||
|
||||
#define DEF_OPERATION_NODE(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
public: \
|
||||
explicit Name(uint64_t bitfield) : Base(bitfield) {} \
|
||||
void AllocateVreg(MaglevVregAllocationState*); \
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||
};
|
||||
|
||||
#define DEF_INT32_COMPARE_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Int32##Name, Int32CompareNode, Name)
|
||||
DEF_INT32_COMPARE_NODE(Equal)
|
||||
@ -1805,8 +1802,6 @@ DEF_INT32_COMPARE_NODE(GreaterThan)
|
||||
DEF_INT32_COMPARE_NODE(GreaterThanOrEqual)
|
||||
#undef DEF_INT32_COMPARE_NODE
|
||||
|
||||
#undef DEF_OPERATION_NODE
|
||||
|
||||
template <class Derived, Operation kOperation>
|
||||
class Float64BinaryNode : public FixedInputValueNodeT<2, Derived> {
|
||||
using Base = FixedInputValueNodeT<2, Derived>;
|
||||
@ -1825,17 +1820,6 @@ class Float64BinaryNode : public FixedInputValueNodeT<2, Derived> {
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
||||
};
|
||||
|
||||
#define DEF_OPERATION_NODE(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
public: \
|
||||
explicit Name(uint64_t bitfield) : Base(bitfield) {} \
|
||||
void AllocateVreg(MaglevVregAllocationState*); \
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||
};
|
||||
|
||||
#define DEF_FLOAT64_BINARY_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Float64##Name, Float64BinaryNode, Name)
|
||||
DEF_FLOAT64_BINARY_NODE(Add)
|
||||
@ -1870,17 +1854,6 @@ class Float64CompareNode : public FixedInputValueNodeT<2, Derived> {
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
|
||||
};
|
||||
|
||||
#define DEF_OPERATION_NODE(Name, Super, OpName) \
|
||||
class Name : public Super<Name, Operation::k##OpName> { \
|
||||
using Base = Super<Name, Operation::k##OpName>; \
|
||||
\
|
||||
public: \
|
||||
explicit Name(uint64_t bitfield) : Base(bitfield) {} \
|
||||
void AllocateVreg(MaglevVregAllocationState*); \
|
||||
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
|
||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||
};
|
||||
|
||||
#define DEF_FLOAT64_COMPARE_NODE(Name) \
|
||||
DEF_OPERATION_NODE(Float64##Name, Float64CompareNode, Name)
|
||||
DEF_FLOAT64_COMPARE_NODE(Equal)
|
||||
|
Loading…
Reference in New Issue
Block a user