Commit 084471ce authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

Revert "[Interpreter] Move BinaryOp Smi transformation into BytecodeGenerator."

This reverts commit d3e9aade.

Reason for revert: Speculative for:
https://build.chromium.org/p/client.v8.ports/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20nosnap%20-%20debug/builds/4449

Bisect points to this CL.

Original change's description:
> [Interpreter] Move BinaryOp Smi transformation into BytecodeGenerator.
> 
> Perform the transformation to <BinaryOp>Smi for Binary ops which take Smi
> literals in the BytecodeGenerator. This enables us to perform the
> transformation for literals on either side for commutative operations, and
> Avoids having to do the check on every bytecode in the peephole optimizer.
> 
> In the process, adds Smi bytecode variants for all binary operations, adding
>  - MulSmi
>  - DivSmi
>  - ModSmi
>  - BitwiseXorSmi
>  - ShiftRightLogical
> 
> BUG=v8:6194
> 
> Change-Id: If1484252f5385c16957004b9cac8bfbb1f209219
> Reviewed-on: https://chromium-review.googlesource.com/466246
> Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#44477}

TBR=rmcilroy@chromium.org,yangguo@chromium.org,mstarzinger@chromium.org,mythria@chromium.org,ishell@chromium.org,v8-reviews@googlegroups.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:6194

Change-Id: If57dbdbe40be77804bf437463b855d3167e2d473
Reviewed-on: https://chromium-review.googlesource.com/471308Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44488}
parent 52a53da5
......@@ -884,30 +884,6 @@ void BinaryOperation::AssignFeedbackSlots(FeedbackVectorSpec* spec,
}
}
static bool IsCommutativeOperationWithSmiLiteral(Token::Value op) {
// Add is not commutative due to potential for string addition.
return op == Token::MUL || op == Token::BIT_AND || op == Token::BIT_OR ||
op == Token::BIT_XOR;
}
// Check for the pattern: x + 1.
static bool MatchSmiLiteralOperation(Expression* left, Expression* right,
Expression** expr, Smi** literal) {
if (right->IsSmiLiteral()) {
*expr = left;
*literal = right->AsLiteral()->AsSmiLiteral();
return true;
}
return false;
}
bool BinaryOperation::IsSmiLiteralOperation(Expression** subexpr,
Smi** literal) {
return MatchSmiLiteralOperation(left_, right_, subexpr, literal) ||
(IsCommutativeOperationWithSmiLiteral(op()) &&
MatchSmiLiteralOperation(right_, left_, subexpr, literal));
}
static bool IsTypeof(Expression* expr) {
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
......
......@@ -1201,11 +1201,6 @@ class Literal final : public Expression {
return value_->AsString();
}
Smi* AsSmiLiteral() {
DCHECK(IsSmiLiteral());
return raw_value()->AsSmi();
}
bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); }
bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); }
......@@ -2139,11 +2134,6 @@ class BinaryOperation final : public Expression {
TypeFeedbackId BinaryOperationFeedbackId() const {
return TypeFeedbackId(local_id(1));
}
// Returns true if one side is a Smi literal, returning the other side's
// sub-expression in |subexpr| and the literal Smi in |literal|.
bool IsSmiLiteralOperation(Expression** subexpr, Smi** literal);
Maybe<int> fixed_right_arg() const {
return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
}
......
......@@ -622,9 +622,6 @@ namespace internal {
TFS(StrictEqual, Compare, 1) \
TFS(AddWithFeedback, BinaryOpWithVector, 1) \
TFS(SubtractWithFeedback, BinaryOpWithVector, 1) \
TFS(MultiplyWithFeedback, BinaryOpWithVector, 1) \
TFS(DivideWithFeedback, BinaryOpWithVector, 1) \
TFS(ModulusWithFeedback, BinaryOpWithVector, 1) \
\
/* Object */ \
CPP(ObjectAssign) \
......
......@@ -1415,38 +1415,5 @@ TF_BUILTIN(SubtractWithFeedback, BinaryOpAssembler) {
ChangeUint32ToWord(slot), vector));
}
TF_BUILTIN(MultiplyWithFeedback, BinaryOpAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
Node* slot = Parameter(Descriptor::kSlot);
Node* vector = Parameter(Descriptor::kVector);
Return(Generate_MultiplyWithFeedback(context, left, right,
ChangeUint32ToWord(slot), vector));
}
TF_BUILTIN(DivideWithFeedback, BinaryOpAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
Node* slot = Parameter(Descriptor::kSlot);
Node* vector = Parameter(Descriptor::kVector);
Return(Generate_DivideWithFeedback(context, left, right,
ChangeUint32ToWord(slot), vector));
}
TF_BUILTIN(ModulusWithFeedback, BinaryOpAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* left = Parameter(Descriptor::kLeft);
Node* right = Parameter(Descriptor::kRight);
Node* slot = Parameter(Descriptor::kSlot);
Node* vector = Parameter(Descriptor::kVector);
Return(Generate_ModulusWithFeedback(context, left, right,
ChangeUint32ToWord(slot), vector));
}
} // namespace internal
} // namespace v8
......@@ -581,53 +581,6 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
return var_result.value();
}
Node* CodeStubAssembler::TrySmiDiv(Node* dividend, Node* divisor,
Label* bailout) {
// Both {a} and {b} are Smis. Bailout to floating point division if {divisor}
// is zero.
GotoIf(WordEqual(divisor, SmiConstant(0)), bailout);
// Do floating point division if {dividend} is zero and {divisor} is
// negative.
Label dividend_is_zero(this), dividend_is_not_zero(this);
Branch(WordEqual(dividend, SmiConstant(0)), &dividend_is_zero,
&dividend_is_not_zero);
Bind(&dividend_is_zero);
{
GotoIf(SmiLessThan(divisor, SmiConstant(0)), bailout);
Goto(&dividend_is_not_zero);
}
Bind(&dividend_is_not_zero);
Node* untagged_divisor = SmiToWord32(divisor);
Node* untagged_dividend = SmiToWord32(dividend);
// Do floating point division if {dividend} is kMinInt (or kMinInt - 1
// if the Smi size is 31) and {divisor} is -1.
Label divisor_is_minus_one(this), divisor_is_not_minus_one(this);
Branch(Word32Equal(untagged_divisor, Int32Constant(-1)),
&divisor_is_minus_one, &divisor_is_not_minus_one);
Bind(&divisor_is_minus_one);
{
GotoIf(Word32Equal(
untagged_dividend,
Int32Constant(kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))),
bailout);
Goto(&divisor_is_not_minus_one);
}
Bind(&divisor_is_not_minus_one);
Node* untagged_result = Int32Div(untagged_dividend, untagged_divisor);
Node* truncated = Int32Mul(untagged_result, untagged_divisor);
// Do floating point division if the remainder is not 0.
GotoIf(Word32NotEqual(untagged_dividend, truncated), bailout);
return SmiFromWord32(untagged_result);
}
Node* CodeStubAssembler::TruncateWordToWord32(Node* value) {
if (Is64()) {
return TruncateInt64ToInt32(value);
......
......@@ -237,9 +237,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* SmiMod(Node* a, Node* b);
// Computes a * b for Smi inputs a and b; result is not necessarily a Smi.
Node* SmiMul(Node* a, Node* b);
// Tries to computes dividend / divisor for Smi inputs; branching to bailout
// if the division needs to be performed as a floating point operation.
Node* TrySmiDiv(Node* dividend, Node* divisor, Label* bailout);
// Smi | HeapNumber operations.
Node* NumberInc(Node* value);
......
......@@ -1745,7 +1745,8 @@ void BytecodeGraphBuilder::VisitShiftRightLogical() {
void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
PrepareEagerCheckpoint();
Node* left = environment()->LookupAccumulator();
Node* left =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
Node* node = nullptr;
......@@ -1769,26 +1770,10 @@ void BytecodeGraphBuilder::VisitSubSmi() {
BuildBinaryOpWithImmediate(javascript()->Subtract());
}
void BytecodeGraphBuilder::VisitMulSmi() {
BuildBinaryOpWithImmediate(javascript()->Multiply());
}
void BytecodeGraphBuilder::VisitDivSmi() {
BuildBinaryOpWithImmediate(javascript()->Divide());
}
void BytecodeGraphBuilder::VisitModSmi() {
BuildBinaryOpWithImmediate(javascript()->Modulus());
}
void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
BuildBinaryOpWithImmediate(javascript()->BitwiseOr());
}
void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
BuildBinaryOpWithImmediate(javascript()->BitwiseXor());
}
void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
BuildBinaryOpWithImmediate(javascript()->BitwiseAnd());
}
......@@ -1801,10 +1786,6 @@ void BytecodeGraphBuilder::VisitShiftRightSmi() {
BuildBinaryOpWithImmediate(javascript()->ShiftRight());
}
void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical());
}
void BytecodeGraphBuilder::VisitInc() {
PrepareEagerCheckpoint();
// Note: Use subtract -1 here instead of add 1 to ensure we always convert to
......
......@@ -362,7 +362,7 @@ class BytecodeGraphBuilder {
static int const kBinaryOperationHintIndex = 1;
static int const kCountOperationHintIndex = 0;
static int const kBinaryOperationSmiHintIndex = 1;
static int const kBinaryOperationSmiHintIndex = 2;
DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilder);
};
......
......@@ -353,23 +353,18 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
case Bytecode::kSub:
case Bytecode::kSubSmi:
case Bytecode::kMul:
case Bytecode::kMulSmi:
case Bytecode::kDiv:
case Bytecode::kDivSmi:
case Bytecode::kMod:
case Bytecode::kModSmi:
case Bytecode::kBitwiseAnd:
case Bytecode::kBitwiseAndSmi:
case Bytecode::kBitwiseOr:
case Bytecode::kBitwiseOrSmi:
case Bytecode::kBitwiseXor:
case Bytecode::kBitwiseXorSmi:
case Bytecode::kShiftLeft:
case Bytecode::kShiftLeftSmi:
case Bytecode::kShiftRight:
case Bytecode::kShiftRightSmi:
case Bytecode::kShiftRightLogical:
case Bytecode::kShiftRightLogicalSmi:
case Bytecode::kInc:
case Bytecode::kDec:
case Bytecode::kLogicalNot:
......
......@@ -546,10 +546,48 @@ Node* BinaryOpAssembler::Generate_DivideWithFeedback(Node* context,
{
Label bailout(this);
// Try to perform Smi division if possible.
var_result.Bind(TrySmiDiv(dividend, divisor, &bailout));
// Do floating point division if {divisor} is zero.
GotoIf(WordEqual(divisor, SmiConstant(0)), &bailout);
// Do floating point division {dividend} is zero and {divisor} is
// negative.
Label dividend_is_zero(this), dividend_is_not_zero(this);
Branch(WordEqual(dividend, SmiConstant(0)), &dividend_is_zero,
&dividend_is_not_zero);
BIND(&dividend_is_zero);
{
GotoIf(SmiLessThan(divisor, SmiConstant(0)), &bailout);
Goto(&dividend_is_not_zero);
}
BIND(&dividend_is_not_zero);
Node* untagged_divisor = SmiToWord32(divisor);
Node* untagged_dividend = SmiToWord32(dividend);
// Do floating point division if {dividend} is kMinInt (or kMinInt - 1
// if the Smi size is 31) and {divisor} is -1.
Label divisor_is_minus_one(this), divisor_is_not_minus_one(this);
Branch(Word32Equal(untagged_divisor, Int32Constant(-1)),
&divisor_is_minus_one, &divisor_is_not_minus_one);
BIND(&divisor_is_minus_one);
{
GotoIf(Word32Equal(untagged_dividend,
Int32Constant(kSmiValueSize == 32 ? kMinInt
: (kMinInt >> 1))),
&bailout);
Goto(&divisor_is_not_minus_one);
}
BIND(&divisor_is_not_minus_one);
Node* untagged_result = Int32Div(untagged_dividend, untagged_divisor);
Node* truncated = Int32Mul(untagged_result, untagged_divisor);
// Do floating point division if the remainder is not 0.
GotoIf(Word32NotEqual(untagged_dividend, truncated), &bailout);
var_type_feedback.Bind(
SmiConstant(BinaryOperationFeedback::kSignedSmall));
var_result.Bind(SmiFromWord32(untagged_result));
Goto(&end);
// Bailout: convert {dividend} and {divisor} to double and do double
......
......@@ -389,48 +389,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperationSmiLiteral(
Token::Value op, Smi* literal, int feedback_slot) {
switch (op) {
case Token::Value::ADD:
OutputAddSmi(literal->value(), feedback_slot);
break;
case Token::Value::SUB:
OutputSubSmi(literal->value(), feedback_slot);
break;
case Token::Value::MUL:
OutputMulSmi(literal->value(), feedback_slot);
break;
case Token::Value::DIV:
OutputDivSmi(literal->value(), feedback_slot);
break;
case Token::Value::MOD:
OutputModSmi(literal->value(), feedback_slot);
break;
case Token::Value::BIT_OR:
OutputBitwiseOrSmi(literal->value(), feedback_slot);
break;
case Token::Value::BIT_XOR:
OutputBitwiseXorSmi(literal->value(), feedback_slot);
break;
case Token::Value::BIT_AND:
OutputBitwiseAndSmi(literal->value(), feedback_slot);
break;
case Token::Value::SHL:
OutputShiftLeftSmi(literal->value(), feedback_slot);
break;
case Token::Value::SAR:
OutputShiftRightSmi(literal->value(), feedback_slot);
break;
case Token::Value::SHR:
OutputShiftRightLogicalSmi(literal->value(), feedback_slot);
break;
default:
UNREACHABLE();
}
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
int feedback_slot) {
if (op == Token::Value::ADD) {
......
......@@ -292,9 +292,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
// Type feedback will be recorded in the |feedback_slot|
BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
int feedback_slot);
BytecodeArrayBuilder& BinaryOperationSmiLiteral(Token::Value binop,
Smi* literal,
int feedback_slot);
// Count Operators (value stored in accumulator).
// Type feedback will be recorded in the |feedback_slot|
......
......@@ -2299,48 +2299,50 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
// Evaluate the value and potentially handle compound assignments by loading
// the left-hand side value and performing a binary operation.
if (expr->is_compound()) {
Register old_value = register_allocator()->NewRegister();
switch (assign_type) {
case VARIABLE: {
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
proxy->hole_check_mode());
builder()->StoreAccumulatorInRegister(old_value);
break;
}
case NAMED_PROPERTY: {
FeedbackSlot slot = property->PropertyFeedbackSlot();
builder()->LoadNamedProperty(object, name, feedback_index(slot));
builder()
->LoadNamedProperty(object, name, feedback_index(slot))
.StoreAccumulatorInRegister(old_value);
break;
}
case KEYED_PROPERTY: {
// Key is already in accumulator at this point due to evaluating the
// LHS above.
FeedbackSlot slot = property->PropertyFeedbackSlot();
builder()->LoadKeyedProperty(object, feedback_index(slot));
builder()
->LoadKeyedProperty(object, feedback_index(slot))
.StoreAccumulatorInRegister(old_value);
break;
}
case NAMED_SUPER_PROPERTY: {
builder()->CallRuntime(Runtime::kLoadFromSuper,
super_property_args.Truncate(3));
builder()
->CallRuntime(Runtime::kLoadFromSuper,
super_property_args.Truncate(3))
.StoreAccumulatorInRegister(old_value);
break;
}
case KEYED_SUPER_PROPERTY: {
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
super_property_args.Truncate(3));
builder()
->CallRuntime(Runtime::kLoadKeyedFromSuper,
super_property_args.Truncate(3))
.StoreAccumulatorInRegister(old_value);
break;
}
}
VisitForAccumulatorValue(expr->value());
FeedbackSlot slot = expr->binary_operation()->BinaryOperationFeedbackSlot();
if (expr->value()->IsSmiLiteral()) {
builder()->BinaryOperationSmiLiteral(
expr->binary_op(), expr->value()->AsLiteral()->AsSmiLiteral(),
feedback_index(slot));
} else {
Register old_value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(old_value);
VisitForAccumulatorValue(expr->value());
builder()->BinaryOperation(expr->binary_op(), old_value,
feedback_index(slot));
}
builder()->BinaryOperation(expr->binary_op(), old_value,
feedback_index(slot));
} else {
VisitForAccumulatorValue(expr->value());
}
......@@ -3107,20 +3109,11 @@ void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
// TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for
// +x and -x by the parser.
Register lhs = VisitForRegisterValue(expr->left());
VisitForAccumulatorValue(expr->right());
FeedbackSlot slot = expr->BinaryOperationFeedbackSlot();
Expression* subexpr;
Smi* literal;
if (expr->IsSmiLiteralOperation(&subexpr, &literal)) {
VisitForAccumulatorValue(subexpr);
builder()->SetExpressionPosition(expr);
builder()->BinaryOperationSmiLiteral(expr->op(), literal,
feedback_index(slot));
} else {
Register lhs = VisitForRegisterValue(expr->left());
VisitForAccumulatorValue(expr->right());
builder()->SetExpressionPosition(expr);
builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
}
builder()->SetExpressionPosition(expr);
builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
}
void BytecodeGenerator::VisitSpread(Spread* expr) { Visit(expr->expression()); }
......
......@@ -117,6 +117,30 @@ bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition(
namespace {
BytecodeNode TransformLdaSmiBinaryOpToBinaryOpWithSmi(
Bytecode new_bytecode, BytecodeNode* const last,
BytecodeNode* const current) {
DCHECK_EQ(last->bytecode(), Bytecode::kLdaSmi);
BytecodeNode node(new_bytecode, last->operand(0), current->operand(0),
current->operand(1), current->source_info());
if (last->source_info().is_valid()) {
node.set_source_info(last->source_info());
}
return node;
}
BytecodeNode TransformLdaZeroBinaryOpToBinaryOpWithZero(
Bytecode new_bytecode, BytecodeNode* const last,
BytecodeNode* const current) {
DCHECK_EQ(last->bytecode(), Bytecode::kLdaZero);
BytecodeNode node(new_bytecode, 0, current->operand(0), current->operand(1),
current->source_info());
if (last->source_info().is_valid()) {
node.set_source_info(last->source_info());
}
return node;
}
} // namespace
void BytecodePeepholeOptimizer::DefaultAction(
......@@ -200,6 +224,36 @@ void BytecodePeepholeOptimizer::ChangeBytecodeAction(
DefaultAction(node);
}
void BytecodePeepholeOptimizer::TransformLdaSmiBinaryOpToBinaryOpWithSmiAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
DCHECK(!Bytecodes::IsJump(node->bytecode()));
if (!node->source_info().is_valid() || !last()->source_info().is_valid()) {
// Fused last and current into current.
BytecodeNode new_node(TransformLdaSmiBinaryOpToBinaryOpWithSmi(
action_data->bytecode, last(), node));
SetLast(&new_node);
} else {
DefaultAction(node);
}
}
void BytecodePeepholeOptimizer::
TransformLdaZeroBinaryOpToBinaryOpWithZeroAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
DCHECK(!Bytecodes::IsJump(node->bytecode()));
if (!node->source_info().is_valid() || !last()->source_info().is_valid()) {
// Fused last and current into current.
BytecodeNode new_node(TransformLdaZeroBinaryOpToBinaryOpWithZero(
action_data->bytecode, last(), node));
SetLast(&new_node);
} else {
DefaultAction(node);
}
}
void BytecodePeepholeOptimizer::DefaultJumpAction(
BytecodeNode* const node, const PeepholeActionAndData* action_data) {
DCHECK(LastIsValid());
......
......@@ -11,14 +11,16 @@ namespace v8 {
namespace internal {
namespace interpreter {
#define PEEPHOLE_NON_JUMP_ACTION_LIST(V) \
V(DefaultAction) \
V(UpdateLastAction) \
V(UpdateLastIfSourceInfoPresentAction) \
V(ElideCurrentAction) \
V(ElideCurrentIfOperand0MatchesAction) \
V(ElideLastAction) \
V(ChangeBytecodeAction)
#define PEEPHOLE_NON_JUMP_ACTION_LIST(V) \
V(DefaultAction) \
V(UpdateLastAction) \
V(UpdateLastIfSourceInfoPresentAction) \
V(ElideCurrentAction) \
V(ElideCurrentIfOperand0MatchesAction) \
V(ElideLastAction) \
V(ChangeBytecodeAction) \
V(TransformLdaSmiBinaryOpToBinaryOpWithSmiAction) \
V(TransformLdaZeroBinaryOpToBinaryOpWithZeroAction)
#define PEEPHOLE_JUMP_ACTION_LIST(V) \
V(DefaultJumpAction) \
......
......@@ -127,23 +127,18 @@ namespace interpreter {
OperandType::kIdx) \
\
/* Binary operators with immediate operands */ \
V(AddSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \
V(SubSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \
V(MulSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \
V(DivSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \
V(ModSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx) \
V(BitwiseOrSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
V(AddSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg, \
OperandType::kIdx) \
V(BitwiseXorSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
OperandType::kIdx) \
V(BitwiseAndSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
OperandType::kIdx) \
V(ShiftLeftSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
OperandType::kIdx) \
V(ShiftRightSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
OperandType::kIdx) \
V(ShiftRightLogicalSmi, AccumulatorUse::kReadWrite, OperandType::kImm, \
V(SubSmi, AccumulatorUse::kWrite, OperandType::kImm, OperandType::kReg, \
OperandType::kIdx) \
V(BitwiseOrSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg, OperandType::kIdx) \
V(BitwiseAndSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg, OperandType::kIdx) \
V(ShiftLeftSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg, OperandType::kIdx) \
V(ShiftRightSmi, AccumulatorUse::kWrite, OperandType::kImm, \
OperandType::kReg, OperandType::kIdx) \
\
/* Unary Operators */ \
V(Inc, AccumulatorUse::kReadWrite, OperandType::kIdx) \
......
This diff is collapsed.
......@@ -106,6 +106,66 @@ PeepholeActionAndData PeepholeActionTableWriter::LookupActionAndData(
// TODO(rmcilroy): Add elide for consecutive mov to and from the same
// register.
// Fuse LdaSmi followed by binary op to produce binary op with a
// immediate integer argument. This savaes on dispatches and size.
if (last == Bytecode::kLdaSmi) {
switch (current) {
case Bytecode::kAdd:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kAddSmi};
case Bytecode::kSub:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kSubSmi};
case Bytecode::kBitwiseAnd:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kBitwiseAndSmi};
case Bytecode::kBitwiseOr:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kBitwiseOrSmi};
case Bytecode::kShiftLeft:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kShiftLeftSmi};
case Bytecode::kShiftRight:
return {PeepholeAction::kTransformLdaSmiBinaryOpToBinaryOpWithSmiAction,
Bytecode::kShiftRightSmi};
default:
break;
}
}
// Fuse LdaZero followed by binary op to produce binary op with a
// zero immediate argument. This saves dispatches, but not size.
if (last == Bytecode::kLdaZero) {
switch (current) {
case Bytecode::kAdd:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kAddSmi};
case Bytecode::kSub:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kSubSmi};
case Bytecode::kBitwiseAnd:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kBitwiseAndSmi};
case Bytecode::kBitwiseOr:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kBitwiseOrSmi};
case Bytecode::kShiftLeft:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kShiftLeftSmi};
case Bytecode::kShiftRight:
return {
PeepholeAction::kTransformLdaZeroBinaryOpToBinaryOpWithZeroAction,
Bytecode::kShiftRightSmi};
default:
break;
}
}
// If there is no last bytecode to optimize against, store the incoming
// bytecode or for jumps emit incoming bytecode immediately.
if (last == Bytecode::kIllegal) {
......
......@@ -29,7 +29,7 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 36
bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
......@@ -42,8 +42,7 @@ bytecodes: [
/* 54 E> */ B(StaKeyedPropertySloppy), R(2), R(1), U8(4),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Ldar), R(0),
/* 59 E> */ B(AddSmi), I8(1), U8(2),
/* 59 E> */ B(AddSmi), I8(1), R(0), U8(2),
B(StaKeyedPropertySloppy), R(2), R(1), U8(4),
B(Ldar), R(2),
/* 66 S> */ B(Return),
......@@ -78,7 +77,7 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 66
bytecode array length: 65
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
......@@ -101,8 +100,7 @@ bytecodes: [
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(0),
/* 68 E> */ B(AddSmi), I8(2), U8(5),
/* 68 E> */ B(AddSmi), I8(2), R(0), U8(5),
B(StaKeyedPropertySloppy), R(4), R(3), U8(7),
B(Ldar), R(4),
B(StaKeyedPropertySloppy), R(2), R(1), U8(10),
......
......@@ -195,7 +195,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 73
bytecode array length: 72
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
......@@ -207,8 +207,7 @@ bytecodes: [
B(Star), R(0),
/* 63 E> */ B(Add), R(2), U8(2),
B(Star), R(2),
B(Ldar), R(0),
/* 78 E> */ B(AddSmi), I8(1), U8(3),
/* 78 E> */ B(AddSmi), I8(1), R(0), U8(3),
B(Star), R(3),
B(LdaSmi), I8(2),
B(Star), R(1),
......
......@@ -74,11 +74,11 @@ bytecodes: [
/* 65 E> */ B(TestLessThan), R(0), U8(2),
B(JumpIfFalse), U8(38),
/* 56 E> */ B(StackCheck),
/* 75 S> */ B(Ldar), R(1),
/* 81 E> */ B(MulSmi), I8(12), U8(3),
/* 75 S> */ B(LdaSmi), I8(12),
/* 81 E> */ B(Mul), R(1), U8(3),
B(Star), R(1),
/* 89 S> */ B(Ldar), R(0),
/* 95 E> */ B(AddSmi), I8(1), U8(4),
/* 89 S> */ B(LdaSmi), I8(1),
/* 95 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 102 S> */ B(LdaSmi), I8(3),
/* 108 E> */ B(TestEqual), R(0), U8(5),
......@@ -138,8 +138,8 @@ bytecodes: [
/* 158 E> */ B(TestEqual), R(0), U8(6),
B(JumpIfFalse), U8(4),
/* 164 S> */ B(Jump), U8(12),
/* 173 S> */ B(Ldar), R(0),
/* 179 E> */ B(AddSmi), I8(1), U8(7),
/* 173 S> */ B(LdaSmi), I8(1),
/* 179 E> */ B(Add), R(0), U8(7),
B(Star), R(0),
B(JumpLoop), U8(52), I8(0),
/* 186 S> */ B(Ldar), R(0),
......@@ -179,12 +179,12 @@ bytecodes: [
/* 88 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 94 S> */ B(Jump), U8(12),
/* 105 S> */ B(Ldar), R(0),
/* 111 E> */ B(AddSmi), I8(1), U8(4),
/* 105 S> */ B(LdaSmi), I8(1),
/* 111 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(24), I8(1),
/* 122 S> */ B(Ldar), R(0),
/* 128 E> */ B(AddSmi), I8(1), U8(5),
/* 122 S> */ B(LdaSmi), I8(1),
/* 128 E> */ B(Add), R(0), U8(5),
B(Star), R(0),
/* 135 S> */ B(Jump), U8(2),
/* 144 S> */ B(Ldar), R(0),
......@@ -217,11 +217,11 @@ bytecodes: [
/* 64 S> */ B(Ldar), R(0),
B(JumpIfToBooleanFalse), U8(20),
/* 57 E> */ B(StackCheck),
/* 71 S> */ B(Ldar), R(1),
/* 77 E> */ B(MulSmi), I8(12), U8(2),
/* 71 S> */ B(LdaSmi), I8(12),
/* 77 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 85 S> */ B(Ldar), R(0),
/* 91 E> */ B(SubSmi), I8(1), U8(3),
/* 85 S> */ B(LdaSmi), I8(1),
/* 91 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
B(JumpLoop), U8(19), I8(0),
/* 98 S> */ B(Ldar), R(1),
......@@ -253,8 +253,8 @@ bytecodes: [
/* 53 S> */ B(LdaSmi), I8(1),
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(Ldar), R(1),
/* 69 E> */ B(MulSmi), I8(10), U8(2),
/* 63 S> */ B(LdaSmi), I8(10),
/* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), I8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
......@@ -264,8 +264,8 @@ bytecodes: [
/* 104 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
/* 110 S> */ B(Jump), U8(9),
/* 122 S> */ B(Ldar), R(0),
/* 128 E> */ B(AddSmi), I8(1), U8(5),
/* 122 S> */ B(LdaSmi), I8(1),
/* 128 E> */ B(Add), R(0), U8(5),
B(Star), R(0),
/* 144 S> */ B(LdaSmi), I8(10),
/* 144 E> */ B(TestLessThan), R(0), U8(6),
......@@ -299,11 +299,11 @@ bytecodes: [
/* 54 S> */ B(LdaSmi), I8(1),
B(Star), R(1),
/* 57 E> */ B(StackCheck),
/* 64 S> */ B(Ldar), R(1),
/* 70 E> */ B(MulSmi), I8(12), U8(2),
/* 64 S> */ B(LdaSmi), I8(12),
/* 70 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 78 S> */ B(Ldar), R(0),
/* 84 E> */ B(SubSmi), I8(1), U8(3),
/* 78 S> */ B(LdaSmi), I8(1),
/* 84 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
/* 98 S> */ B(JumpIfToBooleanFalse), U8(5),
B(JumpLoop), U8(17), I8(0),
......@@ -328,7 +328,7 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 43
bytecode array length: 44
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
......@@ -336,15 +336,15 @@ bytecodes: [
/* 53 S> */ B(LdaSmi), I8(1),
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(Nop),
/* 69 E> */ B(MulSmi), I8(10), U8(2),
/* 63 S> */ B(LdaSmi), I8(10),
/* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), I8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(18),
/* 98 S> */ B(Ldar), R(0),
/* 104 E> */ B(AddSmi), I8(1), U8(4),
/* 98 S> */ B(LdaSmi), I8(1),
/* 104 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 111 S> */ B(LdaSmi), I8(6),
/* 117 E> */ B(TestEqual), R(0), U8(5),
......@@ -379,15 +379,15 @@ bytecodes: [
/* 53 S> */ B(LdaSmi), I8(1),
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(Ldar), R(1),
/* 69 E> */ B(MulSmi), I8(10), U8(2),
/* 63 S> */ B(LdaSmi), I8(10),
/* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), I8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(21),
/* 98 S> */ B(Ldar), R(0),
/* 104 E> */ B(AddSmi), I8(1), U8(4),
/* 98 S> */ B(LdaSmi), I8(1),
/* 104 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 111 S> */ B(LdaSmi), I8(6),
/* 117 E> */ B(TestEqual), R(0), U8(5),
......@@ -427,8 +427,8 @@ bytecodes: [
/* 85 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 91 S> */ B(Jump), U8(9),
/* 103 S> */ B(Ldar), R(0),
/* 109 E> */ B(AddSmi), I8(1), U8(4),
/* 103 S> */ B(LdaSmi), I8(1),
/* 109 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(26), I8(0),
B(LdaUndefined),
......@@ -463,8 +463,8 @@ bytecodes: [
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
/* 89 S> */ B(Jump), U8(9),
/* 101 S> */ B(Ldar), R(0),
/* 107 E> */ B(AddSmi), I8(1), U8(4),
/* 101 S> */ B(LdaSmi), I8(1),
/* 107 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
B(JumpLoop), U8(26), I8(0),
B(LdaUndefined),
......@@ -499,8 +499,8 @@ bytecodes: [
/* 95 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
/* 101 S> */ B(Jump), U8(2),
/* 55 S> */ B(Ldar), R(0),
/* 59 E> */ B(AddSmi), I8(1), U8(2),
/* 55 S> */ B(LdaSmi), I8(1),
/* 59 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
B(JumpLoop), U8(26), I8(0),
B(LdaUndefined),
......@@ -534,8 +534,8 @@ bytecodes: [
/* 93 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
/* 99 S> */ B(Jump), U8(2),
/* 53 S> */ B(Ldar), R(0),
/* 57 E> */ B(AddSmi), I8(1), U8(2),
/* 53 S> */ B(LdaSmi), I8(1),
/* 57 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
B(JumpLoop), U8(26), I8(0),
B(LdaUndefined),
......@@ -567,12 +567,12 @@ bytecodes: [
/* 63 E> */ B(TestLessThan), R(1), U8(2),
B(JumpIfFalse), U8(22),
/* 45 E> */ B(StackCheck),
/* 85 S> */ B(Ldar), R(0),
/* 91 E> */ B(AddSmi), I8(1), U8(4),
/* 85 S> */ B(LdaSmi), I8(1),
/* 91 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 98 S> */ B(Jump), U8(2),
/* 72 S> */ B(Ldar), R(1),
/* 76 E> */ B(AddSmi), I8(1), U8(3),
/* 72 S> */ B(LdaSmi), I8(1),
/* 76 E> */ B(Add), R(1), U8(3),
B(Star), R(1),
B(JumpLoop), U8(24), I8(0),
B(LdaUndefined),
......@@ -603,8 +603,8 @@ bytecodes: [
/* 62 S> */ B(Ldar), R(1),
B(JumpIfToBooleanFalse), U8(19),
/* 45 E> */ B(StackCheck),
/* 74 S> */ B(Ldar), R(0),
/* 80 E> */ B(MulSmi), I8(12), U8(3),
/* 74 S> */ B(LdaSmi), I8(12),
/* 80 E> */ B(Mul), R(0), U8(3),
B(Star), R(0),
/* 67 S> */ B(Ldar), R(1),
B(Dec), U8(2),
......@@ -662,8 +662,8 @@ bytecodes: [
/* 58 S> */ B(LdaZero),
B(Star), R(1),
/* 45 E> */ B(StackCheck),
/* 76 S> */ B(Ldar), R(0),
/* 82 E> */ B(AddSmi), I8(1), U8(3),
/* 76 S> */ B(LdaSmi), I8(1),
/* 82 E> */ B(Add), R(0), U8(3),
B(Star), R(0),
/* 89 S> */ B(LdaSmi), I8(20),
/* 95 E> */ B(TestEqual), R(0), U8(4),
......
......@@ -17,13 +17,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 15
bytecode array length: 16
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 56 S> */ B(Nop),
/* 62 E> */ B(AddSmi), I8(1), U8(2),
/* 56 S> */ B(LdaSmi), I8(1),
/* 62 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
/* 69 S> */ B(Jump), U8(2),
/* 97 S> */ B(Ldar), R(0),
......
......@@ -22,7 +22,7 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 33
bytecode array length: 36
bytecodes: [
B(Mov), R(closure), R(0),
/* 99 E> */ B(StackCheck),
......@@ -35,7 +35,8 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kLoadFromSuper), R(3), U8(3),
B(Star), R(1),
/* 117 E> */ B(Call0), R(1), R(this), U8(2),
/* 126 E> */ B(AddSmi), I8(1), U8(8),
B(Star), R(1),
/* 126 E> */ B(AddSmi), I8(1), R(1), U8(8),
/* 131 S> */ B(Return),
]
constant pool: [
......
......@@ -9,14 +9,15 @@ wrap: yes
snippet: "
var a = 1; a += 2;
"
frame size: 1
frame size: 2
parameter count: 1
bytecode array length: 12
bytecode array length: 16
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(AddSmi), I8(2), U8(2),
/* 45 S> */ B(AddSmi), I8(2), R(0), U8(2),
B(Mov), R(0), R(1),
B(Star), R(0),
B(LdaUndefined),
/* 53 S> */ B(Return),
......@@ -30,14 +31,16 @@ handlers: [
snippet: "
var a = 1; a /= 2;
"
frame size: 1
frame size: 2
parameter count: 1
bytecode array length: 12
bytecode array length: 17
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(DivSmi), I8(2), U8(2),
/* 45 S> */ B(LdaSmi), I8(2),
B(Div), R(0), U8(2),
B(Mov), R(0), R(1),
B(Star), R(0),
B(LdaUndefined),
/* 53 S> */ B(Return),
......@@ -51,15 +54,17 @@ handlers: [
snippet: "
var a = { val: 2 }; a.name *= 2;
"
frame size: 2
frame size: 3
parameter count: 1
bytecode array length: 22
bytecode array length: 26
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(2), U8(1), R(1),
B(Mov), R(1), R(0),
/* 54 S> */ B(LdaNamedProperty), R(0), U8(1), U8(3),
B(MulSmi), I8(2), U8(5),
B(Star), R(2),
B(LdaSmi), I8(2),
B(Mul), R(2), U8(5),
/* 61 E> */ B(StaNamedPropertySloppy), R(0), U8(1), U8(6),
B(LdaUndefined),
/* 67 S> */ B(Return),
......@@ -75,9 +80,9 @@ handlers: [
snippet: "
var a = { 1: 2 }; a[1] ^= 2;
"
frame size: 3
frame size: 4
parameter count: 1
bytecode array length: 25
bytecode array length: 29
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(2), U8(1), R(1),
......@@ -85,7 +90,9 @@ bytecodes: [
/* 52 S> */ B(LdaSmi), I8(1),
B(Star), R(2),
B(LdaKeyedProperty), R(0), U8(3),
B(BitwiseXorSmi), I8(2), U8(5),
B(Star), R(3),
B(LdaSmi), I8(2),
B(BitwiseXor), R(3), U8(5),
/* 57 E> */ B(StaKeyedPropertySloppy), R(0), R(2), U8(6),
B(LdaUndefined),
/* 63 S> */ B(Return),
......@@ -100,9 +107,9 @@ handlers: [
snippet: "
var a = 1; (function f() { return a; }); a |= 24;
"
frame size: 1
frame size: 2
parameter count: 1
bytecode array length: 22
bytecode array length: 25
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
......@@ -111,7 +118,8 @@ bytecodes: [
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
/* 45 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 75 S> */ B(LdaCurrentContextSlot), U8(4),
B(BitwiseOrSmi), I8(24), U8(3),
B(Star), R(1),
B(BitwiseOrSmi), I8(24), R(1), U8(3),
/* 77 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),
/* 84 S> */ B(Return),
......
......@@ -12,13 +12,14 @@ snippet: "
function f() { return global &= 1; }
f();
"
frame size: 0
frame size: 1
parameter count: 1
bytecode array length: 11
bytecode array length: 14
bytecodes: [
/* 26 E> */ B(StackCheck),
/* 31 S> */ B(LdaGlobal), U8(0), U8(2),
B(BitwiseAndSmi), I8(1), U8(4),
B(Star), R(0),
B(BitwiseAndSmi), I8(1), R(0), U8(4),
/* 45 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 51 S> */ B(Return),
]
......@@ -34,13 +35,14 @@ snippet: "
function f() { return unallocated += 1; }
f();
"
frame size: 0
frame size: 1
parameter count: 1
bytecode array length: 11
bytecode array length: 14
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdaGlobal), U8(0), U8(2),
B(AddSmi), I8(1), U8(4),
B(Star), R(0),
B(AddSmi), I8(1), R(0), U8(4),
/* 51 E> */ B(StaGlobalSloppy), U8(0), U8(5),
/* 57 S> */ B(Return),
]
......
......@@ -112,16 +112,16 @@ snippet: "
};
f();
"
frame size: 1
frame size: 2
parameter count: 1
bytecode array length: 21
bytecode array length: 23
bytecodes: [
/* 10 E> */ B(StackCheck),
/* 25 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 30 S> */ B(JumpIfToBooleanFalse), U8(11),
/* 43 S> */ B(Ldar), R(0),
B(AddSmi), I8(1), U8(2),
/* 30 S> */ B(JumpIfToBooleanFalse), U8(13),
/* 43 S> */ B(AddSmi), I8(1), R(0), U8(2),
B(Mov), R(0), R(1),
B(Star), R(0),
B(Jump), U8(5),
/* 66 S> */ B(LdaSmi), I8(2),
......
......@@ -72,13 +72,13 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 20
bytecode array length: 21
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(3), U8(1), R(1),
/* 69 E> */ B(AddSmi), I8(1), U8(2),
/* 69 E> */ B(AddSmi), I8(1), R(0), U8(2),
B(StaNamedOwnProperty), R(1), U8(1), U8(4),
B(Ldar), R(1),
/* 76 S> */ B(Return),
......
......@@ -30,35 +30,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(AddSmi), I8(3), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 0; return 3 + x;
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 54 E> */ B(Add), R(1), U8(2),
/* 54 E> */ B(Add), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -72,35 +50,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(SubSmi), I8(3), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 0; return 3 - x;
"
frame size: 2
parameter count: 1
bytecode array length: 14
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 54 E> */ B(Sub), R(1), U8(2),
/* 54 E> */ B(Sub), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -114,33 +70,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(MulSmi), I8(3), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 4; return 3 * x;
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(MulSmi), I8(3), U8(2),
/* 45 S> */ B(LdaSmi), I8(3),
/* 54 E> */ B(Mul), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -154,35 +90,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(DivSmi), I8(3), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 4; return 3 / x;
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 54 E> */ B(Div), R(1), U8(2),
/* 54 E> */ B(Div), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -196,35 +110,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(ModSmi), I8(3), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 4; return 3 % x;
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(4),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 54 E> */ B(Mod), R(1), U8(2),
/* 54 E> */ B(Mod), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -238,33 +130,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseOrSmi), I8(2), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 1; return 2 | x;
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseOrSmi), I8(2), U8(2),
/* 45 S> */ B(LdaSmi), I8(2),
/* 54 E> */ B(BitwiseOr), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -278,33 +150,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseXorSmi), I8(2), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 1; return 2 ^ x;
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseXorSmi), I8(2), U8(2),
/* 45 S> */ B(LdaSmi), I8(2),
/* 54 E> */ B(BitwiseXor), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -318,33 +170,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseAndSmi), I8(2), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 1; return 2 & x;
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(Nop),
/* 54 E> */ B(BitwiseAndSmi), I8(2), U8(2),
/* 45 S> */ B(LdaSmi), I8(2),
/* 54 E> */ B(BitwiseAnd), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
......@@ -358,35 +190,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 55 E> */ B(ShiftLeftSmi), I8(3), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 10; return 3 << x;
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 55 E> */ B(ShiftLeft), R(1), U8(2),
/* 55 E> */ B(ShiftLeft), R(0), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
......@@ -400,35 +210,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 55 E> */ B(ShiftRightSmi), I8(3), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 10; return 3 >> x;
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 55 E> */ B(ShiftRight), R(1), U8(2),
/* 55 E> */ B(ShiftRight), R(0), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
......@@ -442,35 +230,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 55 E> */ B(ShiftRightLogicalSmi), I8(3), U8(2),
/* 62 S> */ B(Return),
]
constant pool: [
]
handlers: [
]
---
snippet: "
var x = 10; return 3 >>> x;
"
frame size: 2
parameter count: 1
bytecode array length: 15
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(10),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), I8(3),
B(Star), R(1),
B(Ldar), R(0),
/* 55 E> */ B(ShiftRightLogical), R(1), U8(2),
/* 55 E> */ B(ShiftRightLogical), R(0), U8(2),
/* 62 S> */ B(Return),
]
constant pool: [
......
......@@ -479,7 +479,7 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 63
bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(1),
......@@ -491,10 +491,9 @@ bytecodes: [
B(JumpIfTrue), U8(11),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(3), U8(6),
B(JumpIfTrue), U8(35),
B(Jump), U8(37),
B(Ldar), R(0),
/* 79 E> */ B(AddSmi), I8(1), U8(2),
B(JumpIfTrue), U8(34),
B(Jump), U8(36),
/* 79 E> */ B(AddSmi), I8(1), R(0), U8(2),
B(Star), R(1),
/* 70 S> */ B(LdaSmi), I8(2),
B(TestEqualStrict), R(1), U8(3),
......
......@@ -24,8 +24,8 @@ bytecodes: [
/* 54 E> */ B(TestEqual), R(0), U8(2),
B(JumpIfTrue), U8(13),
/* 45 E> */ B(StackCheck),
/* 65 S> */ B(Ldar), R(0),
/* 71 E> */ B(AddSmi), I8(10), U8(3),
/* 65 S> */ B(LdaSmi), I8(10),
/* 71 E> */ B(Add), R(0), U8(3),
B(Star), R(0),
B(JumpLoop), U8(15), I8(0),
/* 79 S> */ B(Ldar), R(0),
......@@ -74,13 +74,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 11
bytecode array length: 12
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(101),
B(Star), R(0),
/* 47 S> */ B(Nop),
/* 61 E> */ B(MulSmi), I8(3), U8(2),
/* 47 S> */ B(LdaSmi), I8(3),
/* 61 E> */ B(Mul), R(0), U8(2),
B(LdaUndefined),
/* 67 S> */ B(Return),
]
......@@ -95,16 +95,17 @@ snippet: "
var y = void (x * x - 1);
return y;
"
frame size: 2
frame size: 3
parameter count: 1
bytecode array length: 19
bytecode array length: 22
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(Wide), B(LdaSmi), I16(1234),
B(Star), R(0),
/* 56 S> */ B(Nop),
/* 64 E> */ B(Mul), R(0), U8(2),
/* 68 E> */ B(SubSmi), I8(1), U8(3),
B(Star), R(2),
/* 68 E> */ B(SubSmi), I8(1), R(2), U8(3),
B(LdaUndefined),
B(Star), R(1),
/* 74 S> */ B(Nop),
......@@ -122,13 +123,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(13),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 53 E> */ B(BitwiseXorSmi), I8(-1), U8(2),
/* 46 S> */ B(LdaSmi), I8(-1),
/* 53 E> */ B(BitwiseXor), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
......@@ -143,13 +144,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(13),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 53 E> */ B(MulSmi), I8(1), U8(2),
/* 46 S> */ B(LdaSmi), I8(1),
/* 53 E> */ B(Mul), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
......@@ -164,13 +165,13 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 10
bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), I8(13),
B(Star), R(0),
/* 46 S> */ B(Nop),
/* 53 E> */ B(MulSmi), I8(-1), U8(2),
/* 46 S> */ B(LdaSmi), I8(-1),
/* 53 E> */ B(Mul), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
......
......@@ -190,48 +190,26 @@ TEST(PrimitiveExpressions) {
"var x = 0; return x + 3;\n",
"var x = 0; return 3 + x;\n",
"var x = 0; return x - 3;\n",
"var x = 0; return 3 - x;\n",
"var x = 4; return x * 3;\n",
"var x = 4; return 3 * x;\n",
"var x = 4; return x / 3;\n",
"var x = 4; return 3 / x;\n",
"var x = 4; return x % 3;\n",
"var x = 4; return 3 % x;\n",
"var x = 1; return x | 2;\n",
"var x = 1; return 2 | x;\n",
"var x = 1; return x ^ 2;\n",
"var x = 1; return 2 ^ x;\n",
"var x = 1; return x & 2;\n",
"var x = 1; return 2 & x;\n",
"var x = 10; return x << 3;\n",
"var x = 10; return 3 << x;\n",
"var x = 10; return x >> 3;\n",
"var x = 10; return 3 >> x;\n",
"var x = 10; return x >>> 3;\n",
"var x = 10; return 3 >>> x;\n",
"var x = 0; return (x, 3);\n",
};
......
......@@ -177,18 +177,19 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.BinaryOperation(Token::Value::SAR, reg, 10)
.BinaryOperation(Token::Value::SHR, reg, 11);
// Emit Smi binary operations.
builder.BinaryOperationSmiLiteral(Token::Value::ADD, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::SUB, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::MUL, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::DIV, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::MOD, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::BIT_OR, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::BIT_XOR, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::BIT_AND, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::SHL, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::SAR, Smi::FromInt(42), 2)
.BinaryOperationSmiLiteral(Token::Value::SHR, Smi::FromInt(42), 2);
// Emit peephole optimizations of LdaSmi followed by binary operation.
builder.LoadLiteral(Smi::FromInt(1))
.BinaryOperation(Token::Value::ADD, reg, 1)
.LoadLiteral(Smi::FromInt(2))
.BinaryOperation(Token::Value::SUB, reg, 2)
.LoadLiteral(Smi::FromInt(3))
.BinaryOperation(Token::Value::BIT_AND, reg, 3)
.LoadLiteral(Smi::FromInt(4))
.BinaryOperation(Token::Value::BIT_OR, reg, 4)
.LoadLiteral(Smi::FromInt(5))
.BinaryOperation(Token::Value::SHL, reg, 5)
.LoadLiteral(Smi::FromInt(6))
.BinaryOperation(Token::Value::SAR, reg, 6);
// Emit count operatior invocations
builder.CountOperation(Token::Value::ADD, 1)
......@@ -420,6 +421,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
if (!FLAG_ignition_peephole) {
// Insert entries for bytecodes only emitted by peephole optimizer.
scorecard[Bytecodes::ToByte(Bytecode::kAddSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kSubSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kBitwiseAndSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kBitwiseOrSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kShiftLeftSmi)] = 1;
scorecard[Bytecodes::ToByte(Bytecode::kShiftRightSmi)] = 1;
}
if (!FLAG_type_profile) {
......
......@@ -165,6 +165,88 @@ TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) {
// Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes().
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
uint32_t imm_operand = 17;
BytecodeSourceInfo source_info(3, true);
BytecodeNode first(Bytecode::kLdaSmi, imm_operand, source_info);
uint32_t reg_operand = Register(0).ToOperand();
uint32_t idx_operand = 1;
BytecodeNode second(operator_replacement[0], reg_operand, idx_operand);
optimizer()->Write(&first);
optimizer()->Write(&second);
Flush();
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), operator_replacement[1]);
CHECK_EQ(last_written().operand_count(), 3);
CHECK_EQ(last_written().operand(0), imm_operand);
CHECK_EQ(last_written().operand(1), reg_operand);
CHECK_EQ(last_written().operand(2), idx_operand);
CHECK_EQ(last_written().source_info(), source_info);
Reset();
}
}
TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
uint32_t imm_operand = 17;
BytecodeSourceInfo source_info(3, true);
BytecodeNode first(Bytecode::kLdaSmi, imm_operand, source_info);
uint32_t reg_operand = Register(0).ToOperand();
source_info.MakeStatementPosition(4);
BytecodeNode second(operator_replacement[0], reg_operand, 1, source_info);
optimizer()->Write(&first);
optimizer()->Write(&second);
CHECK_EQ(last_written(), first);
Flush();
CHECK_EQ(last_written(), second);
Reset();
}
}
TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) {
Bytecode operator_replacement_pairs[][2] = {
{Bytecode::kAdd, Bytecode::kAddSmi},
{Bytecode::kSub, Bytecode::kSubSmi},
{Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi},
{Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi},
{Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi},
{Bytecode::kShiftRight, Bytecode::kShiftRightSmi}};
for (auto operator_replacement : operator_replacement_pairs) {
BytecodeNode first(Bytecode::kLdaZero);
uint32_t reg_operand = Register(0).ToOperand();
uint32_t idx_operand = 1;
BytecodeNode second(operator_replacement[0], reg_operand, idx_operand);
optimizer()->Write(&first);
optimizer()->Write(&second);
Flush();
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written().bytecode(), operator_replacement[1]);
CHECK_EQ(last_written().operand_count(), 3);
CHECK_EQ(last_written().operand(0), 0u);
CHECK_EQ(last_written().operand(1), reg_operand);
CHECK_EQ(last_written().operand(2), idx_operand);
Reset();
}
}
} // namespace interpreter
} // namespace internal
} // namespace v8
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