// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/factory.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-peephole-optimizer.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "test/unittests/test-utils.h"

namespace v8 {
namespace internal {
namespace interpreter {

class BytecodePeepholeOptimizerTest : public BytecodePipelineStage,
                                      public TestWithIsolateAndZone {
 public:
  BytecodePeepholeOptimizerTest()
      : peephole_optimizer_(this), last_written_(Bytecode::kIllegal) {}
  ~BytecodePeepholeOptimizerTest() override {}

  void Reset() {
    last_written_.set_bytecode(Bytecode::kIllegal);
    write_count_ = 0;
  }

  void Write(BytecodeNode* node) override {
    write_count_++;
    last_written_ = *node;
  }

  void WriteJump(BytecodeNode* node, BytecodeLabel* label) override {
    write_count_++;
    last_written_ = *node;
  }

  void BindLabel(BytecodeLabel* label) override {}
  void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) override {}
  Handle<BytecodeArray> ToBytecodeArray(
      Isolate* isolate, int fixed_register_count, int parameter_count,
      Handle<FixedArray> handle_table) override {
    return Handle<BytecodeArray>();
  }

  void Flush() {
    optimizer()->ToBytecodeArray(isolate(), 0, 0,
                                 factory()->empty_fixed_array());
  }

  BytecodePeepholeOptimizer* optimizer() { return &peephole_optimizer_; }

  int write_count() const { return write_count_; }
  const BytecodeNode& last_written() const { return last_written_; }

 private:
  BytecodePeepholeOptimizer peephole_optimizer_;

  int write_count_ = 0;
  BytecodeNode last_written_;
};

// Sanity tests.

TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) {
  CHECK_EQ(write_count(), 0);

  BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1);
  optimizer()->Write(&add);
  CHECK_EQ(write_count(), 0);

  BytecodeLabel target;
  BytecodeNode jump(Bytecode::kJump, 0);
  optimizer()->WriteJump(&jump, &target);
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(jump, last_written());
}

TEST_F(BytecodePeepholeOptimizerTest, FlushOnBind) {
  CHECK_EQ(write_count(), 0);

  BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1);
  optimizer()->Write(&add);
  CHECK_EQ(write_count(), 0);

  BytecodeLabel target;
  optimizer()->BindLabel(&target);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(add, last_written());
}

// Nop elimination tests.

TEST_F(BytecodePeepholeOptimizerTest, ElideEmptyNop) {
  BytecodeNode nop(Bytecode::kNop);
  optimizer()->Write(&nop);
  BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1);
  optimizer()->Write(&add);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(add, last_written());
}

TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) {
  BytecodeSourceInfo source_info(3, false);
  BytecodeNode nop(Bytecode::kNop, source_info);
  optimizer()->Write(&nop);
  BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1);
  optimizer()->Write(&add);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(add, last_written());
}

TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) {
  BytecodeSourceInfo source_info_statement(3, true);
  BytecodeNode nop(Bytecode::kNop, source_info_statement);
  optimizer()->Write(&nop);
  BytecodeSourceInfo source_info_expression(3, false);
  BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1,
                   source_info_expression);
  optimizer()->Write(&add);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(add, last_written());
}

// Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode().

TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) {
  BytecodeNode first(Bytecode::kLdaNull);
  BytecodeNode second(Bytecode::kJumpIfToBooleanTrue, 3);
  BytecodeLabel label;
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->WriteJump(&second, &label);
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, ElideJumpIfToBooleanTrue) {
  BytecodeNode first(Bytecode::kLdaTrue);
  BytecodeNode second(Bytecode::kJumpIfToBooleanTrue, 3);
  BytecodeLabel label;
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->WriteJump(&second, &label);
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, KeepToBooleanLogicalNot) {
  BytecodeNode first(Bytecode::kLdaNull);
  BytecodeNode second(Bytecode::kToBooleanLogicalNot);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, ElideToBooleanLogicalNot) {
  BytecodeNode first(Bytecode::kLdaTrue);
  BytecodeNode second(Bytecode::kToBooleanLogicalNot);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written().bytecode(), Bytecode::kLogicalNot);
}

// Tests covering BytecodePeepholeOptimizer::CanElideCurrent().

TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRy) {
  BytecodeNode first(Bytecode::kStar, Register(0).ToOperand());
  BytecodeNode second(Bytecode::kLdar, Register(1).ToOperand());
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRx) {
  BytecodeLabel label;
  BytecodeNode first(Bytecode::kStar, Register(0).ToOperand());
  BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand());
  optimizer()->Write(&first);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 0);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
}

TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) {
  BytecodeNode first(Bytecode::kStar, Register(0).ToOperand());
  BytecodeSourceInfo source_info(3, true);
  BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), source_info);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written().bytecode(), Bytecode::kNop);
  CHECK_EQ(last_written().source_info(), source_info);
}

TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) {
  BytecodeLabel label;
  BytecodeNode first(Bytecode::kStar, Register(0).ToOperand());
  BytecodeSourceInfo source_info(0, true);
  BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), source_info);
  BytecodeNode third(Bytecode::kStar, Register(3).ToOperand());
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  optimizer()->Write(&third);
  CHECK_EQ(write_count(), 1);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), third);
}

TEST_F(BytecodePeepholeOptimizerTest, LdarToName) {
  BytecodeNode first(Bytecode::kLdar, Register(0).ToOperand());
  BytecodeNode second(Bytecode::kToName, Register(0).ToOperand());
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, TypeOfToName) {
  BytecodeNode first(Bytecode::kTypeOf);
  BytecodeNode second(Bytecode::kToName, Register(0).ToOperand());
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), first);
  Flush();
  CHECK_EQ(write_count(), 2);
  CHECK_EQ(last_written(), second);
  CHECK_EQ(last_written().bytecode(), Bytecode::kStar);
}

// Tests covering BytecodePeepholeOptimizer::CanElideLast().

TEST_F(BytecodePeepholeOptimizerTest, LdaTrueLdaFalse) {
  BytecodeNode first(Bytecode::kLdaTrue);
  BytecodeNode second(Bytecode::kLdaFalse);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 0);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) {
  BytecodeSourceInfo source_info(3, true);
  BytecodeNode first(Bytecode::kLdaTrue, source_info);
  BytecodeNode second(Bytecode::kLdaFalse);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 0);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), second);
  CHECK(second.source_info().is_statement());
  CHECK_EQ(second.source_info().source_position(), 3);
}

TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) {
  BytecodeNode first(Bytecode::kNop);
  BytecodeNode second(Bytecode::kStackCheck);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 0);
  Flush();
  CHECK_EQ(write_count(), 1);
  CHECK_EQ(last_written(), second);
}

TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) {
  BytecodeSourceInfo source_info(3, true);
  BytecodeNode first(Bytecode::kNop, source_info);
  BytecodeNode second(Bytecode::kStackCheck);
  optimizer()->Write(&first);
  CHECK_EQ(write_count(), 0);
  optimizer()->Write(&second);
  CHECK_EQ(write_count(), 0);
  Flush();
  CHECK_EQ(write_count(), 1);
  BytecodeNode expected(Bytecode::kStackCheck, source_info);
  CHECK_EQ(last_written(), expected);
}

// 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();
  }
}

TEST_F(BytecodePeepholeOptimizerTest, MergeLdaNullOrUndefinedWithCompareOp) {
  Bytecode first_bytecodes[] = {Bytecode::kLdaUndefined, Bytecode::kLdaNull};

  for (auto first_bytecode : first_bytecodes) {
    uint32_t reg_operand = Register(0).ToOperand();
    uint32_t idx_operand = 1;
    BytecodeNode first(first_bytecode);
    BytecodeNode second(Bytecode::kTestEqual, reg_operand, idx_operand);
    optimizer()->Write(&first);
    optimizer()->Write(&second);
    Flush();
    CHECK_EQ(write_count(), 1);
    CHECK_EQ(last_written().bytecode(), Bytecode::kTestUndetectable);
    CHECK_EQ(last_written().operand_count(), 1);
    CHECK_EQ(last_written().operand(0), reg_operand);
    Reset();
  }
}

}  // namespace interpreter
}  // namespace internal
}  // namespace v8
