// Copyright 2014 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 "test/unittests/compiler/backend/instruction-sequence-unittest.h"
#include "src/base/utils/random-number-generator.h"
#include "src/compiler/pipeline.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace v8 {
namespace internal {
namespace compiler {

namespace {
constexpr int kMaxNumAllocatable =
    Max(Register::kNumRegisters, DoubleRegister::kNumRegisters);
static std::array<int, kMaxNumAllocatable> kAllocatableCodes =
    base::make_array<kMaxNumAllocatable>(
        [](size_t i) { return static_cast<int>(i); });
}

InstructionSequenceTest::InstructionSequenceTest()
    : sequence_(nullptr),
      num_general_registers_(Register::kNumRegisters),
      num_double_registers_(DoubleRegister::kNumRegisters),
      instruction_blocks_(zone()),
      current_block_(nullptr),
      block_returns_(false) {}

void InstructionSequenceTest::SetNumRegs(int num_general_registers,
                                         int num_double_registers) {
  CHECK(!config_);
  CHECK(instructions_.empty());
  CHECK(instruction_blocks_.empty());
  CHECK_GE(Register::kNumRegisters, num_general_registers);
  CHECK_GE(DoubleRegister::kNumRegisters, num_double_registers);
  num_general_registers_ = num_general_registers;
  num_double_registers_ = num_double_registers;
}

int InstructionSequenceTest::GetNumRegs(MachineRepresentation rep) {
  switch (rep) {
    case MachineRepresentation::kFloat32:
      return config()->num_float_registers();
    case MachineRepresentation::kFloat64:
      return config()->num_double_registers();
    case MachineRepresentation::kSimd128:
      return config()->num_simd128_registers();
    default:
      return config()->num_general_registers();
  }
}

int InstructionSequenceTest::GetAllocatableCode(int index,
                                                MachineRepresentation rep) {
  switch (rep) {
    case MachineRepresentation::kFloat32:
      return config()->GetAllocatableFloatCode(index);
    case MachineRepresentation::kFloat64:
      return config()->GetAllocatableDoubleCode(index);
    case MachineRepresentation::kSimd128:
      return config()->GetAllocatableSimd128Code(index);
    default:
      return config()->GetAllocatableGeneralCode(index);
  }
}

const RegisterConfiguration* InstructionSequenceTest::config() {
  if (!config_) {
    config_.reset(new RegisterConfiguration(
        num_general_registers_, num_double_registers_, num_general_registers_,
        num_double_registers_, kAllocatableCodes.data(),
        kAllocatableCodes.data(),
        kSimpleFPAliasing ? RegisterConfiguration::OVERLAP
                          : RegisterConfiguration::COMBINE));
  }
  return config_.get();
}

InstructionSequence* InstructionSequenceTest::sequence() {
  if (sequence_ == nullptr) {
    sequence_ = new (zone())
        InstructionSequence(isolate(), zone(), &instruction_blocks_);
    sequence_->SetRegisterConfigurationForTesting(
        InstructionSequenceTest::config());
  }
  return sequence_;
}

void InstructionSequenceTest::StartLoop(int loop_blocks) {
  CHECK_NULL(current_block_);
  if (!loop_blocks_.empty()) {
    CHECK(!loop_blocks_.back().loop_header_.IsValid());
  }
  LoopData loop_data = {Rpo::Invalid(), loop_blocks};
  loop_blocks_.push_back(loop_data);
}

void InstructionSequenceTest::EndLoop() {
  CHECK_NULL(current_block_);
  CHECK(!loop_blocks_.empty());
  CHECK_EQ(0, loop_blocks_.back().expected_blocks_);
  loop_blocks_.pop_back();
}

void InstructionSequenceTest::StartBlock(bool deferred) {
  block_returns_ = false;
  NewBlock(deferred);
}

Instruction* InstructionSequenceTest::EndBlock(BlockCompletion completion) {
  Instruction* result = nullptr;
  if (block_returns_) {
    CHECK(completion.type_ == kBlockEnd || completion.type_ == kFallThrough);
    completion.type_ = kBlockEnd;
  }
  switch (completion.type_) {
    case kBlockEnd:
      break;
    case kFallThrough:
      result = EmitJump();
      break;
    case kJump:
      CHECK(!block_returns_);
      result = EmitJump();
      break;
    case kBranch:
      CHECK(!block_returns_);
      result = EmitBranch(completion.op_);
      break;
  }
  completions_.push_back(completion);
  CHECK_NOT_NULL(current_block_);
  int end = static_cast<int>(sequence()->instructions().size());
  if (current_block_->code_start() == end) {  // Empty block.  Insert a nop.
    sequence()->AddInstruction(Instruction::New(zone(), kArchNop));
  }
  sequence()->EndBlock(current_block_->rpo_number());
  current_block_ = nullptr;
  return result;
}

InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) {
  return TestOperand(kImmediate, imm);
}

InstructionSequenceTest::VReg InstructionSequenceTest::Define(
    TestOperand output_op) {
  VReg vreg = NewReg(output_op);
  InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)};
  Emit(kArchNop, 1, outputs);
  return vreg;
}

Instruction* InstructionSequenceTest::Return(TestOperand input_op_0) {
  block_returns_ = true;
  InstructionOperand inputs[1]{ConvertInputOp(input_op_0)};
  return Emit(kArchRet, 0, nullptr, 1, inputs);
}

PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
                                             VReg incoming_vreg_1,
                                             VReg incoming_vreg_2,
                                             VReg incoming_vreg_3) {
  VReg inputs[] = {incoming_vreg_0, incoming_vreg_1, incoming_vreg_2,
                   incoming_vreg_3};
  size_t input_count = 0;
  for (; input_count < arraysize(inputs); ++input_count) {
    if (inputs[input_count].value_ == kNoValue) break;
  }
  CHECK_LT(0, input_count);
  auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, input_count);
  for (size_t i = 0; i < input_count; ++i) {
    SetInput(phi, i, inputs[i]);
  }
  current_block_->AddPhi(phi);
  return phi;
}

PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
                                             size_t input_count) {
  auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, input_count);
  SetInput(phi, 0, incoming_vreg_0);
  current_block_->AddPhi(phi);
  return phi;
}

void InstructionSequenceTest::SetInput(PhiInstruction* phi, size_t input,
                                       VReg vreg) {
  CHECK_NE(kNoValue, vreg.value_);
  phi->SetInput(input, vreg.value_);
}

InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant(
    int32_t imm) {
  VReg vreg = NewReg();
  sequence()->AddConstant(vreg.value_, Constant(imm));
  InstructionOperand outputs[1]{ConstantOperand(vreg.value_)};
  Emit(kArchNop, 1, outputs);
  return vreg;
}

Instruction* InstructionSequenceTest::EmitNop() { return Emit(kArchNop); }

static size_t CountInputs(size_t size,
                          InstructionSequenceTest::TestOperand* inputs) {
  size_t i = 0;
  for (; i < size; ++i) {
    if (inputs[i].type_ == InstructionSequenceTest::kInvalid) break;
  }
  return i;
}

Instruction* InstructionSequenceTest::EmitI(size_t input_size,
                                            TestOperand* inputs) {
  InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
  return Emit(kArchNop, 0, nullptr, input_size, mapped_inputs);
}

Instruction* InstructionSequenceTest::EmitI(TestOperand input_op_0,
                                            TestOperand input_op_1,
                                            TestOperand input_op_2,
                                            TestOperand input_op_3) {
  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
  return EmitI(CountInputs(arraysize(inputs), inputs), inputs);
}

InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
    TestOperand output_op, size_t input_size, TestOperand* inputs) {
  VReg output_vreg = NewReg(output_op);
  InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
  InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
  Emit(kArchNop, 1, outputs, input_size, mapped_inputs);
  return output_vreg;
}

InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
    TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1,
    TestOperand input_op_2, TestOperand input_op_3) {
  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
  return EmitOI(output_op, CountInputs(arraysize(inputs), inputs), inputs);
}

InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI(
    TestOperand output_op_0, TestOperand output_op_1, size_t input_size,
    TestOperand* inputs) {
  VRegPair output_vregs =
      std::make_pair(NewReg(output_op_0), NewReg(output_op_1));
  InstructionOperand outputs[2]{
      ConvertOutputOp(output_vregs.first, output_op_0),
      ConvertOutputOp(output_vregs.second, output_op_1)};
  InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
  Emit(kArchNop, 2, outputs, input_size, mapped_inputs);
  return output_vregs;
}

InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI(
    TestOperand output_op_0, TestOperand output_op_1, TestOperand input_op_0,
    TestOperand input_op_1, TestOperand input_op_2, TestOperand input_op_3) {
  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
  return EmitOOI(output_op_0, output_op_1,
                 CountInputs(arraysize(inputs), inputs), inputs);
}

InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
    TestOperand output_op, size_t input_size, TestOperand* inputs) {
  VReg output_vreg = NewReg(output_op);
  InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)};
  CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy());
  InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs);
  Emit(kArchCallCodeObject, 1, outputs, input_size, mapped_inputs, 0, nullptr,
       true);
  return output_vreg;
}

InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
    TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1,
    TestOperand input_op_2, TestOperand input_op_3) {
  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
  return EmitCall(output_op, CountInputs(arraysize(inputs), inputs), inputs);
}

Instruction* InstructionSequenceTest::EmitBranch(TestOperand input_op) {
  InstructionOperand inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
                               ConvertInputOp(Imm()), ConvertInputOp(Imm())};
  InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) |
                           FlagsConditionField::encode(kEqual);
  auto instruction = NewInstruction(opcode, 0, nullptr, 4, inputs);
  return AddInstruction(instruction);
}

Instruction* InstructionSequenceTest::EmitFallThrough() {
  auto instruction = NewInstruction(kArchNop, 0, nullptr);
  return AddInstruction(instruction);
}

Instruction* InstructionSequenceTest::EmitJump() {
  InstructionOperand inputs[1]{ConvertInputOp(Imm())};
  auto instruction = NewInstruction(kArchJmp, 0, nullptr, 1, inputs);
  return AddInstruction(instruction);
}

Instruction* InstructionSequenceTest::NewInstruction(
    InstructionCode code, size_t outputs_size, InstructionOperand* outputs,
    size_t inputs_size, InstructionOperand* inputs, size_t temps_size,
    InstructionOperand* temps) {
  CHECK(current_block_);
  return Instruction::New(zone(), code, outputs_size, outputs, inputs_size,
                          inputs, temps_size, temps);
}

InstructionOperand InstructionSequenceTest::Unallocated(
    TestOperand op, UnallocatedOperand::ExtendedPolicy policy) {
  return UnallocatedOperand(policy, op.vreg_.value_);
}

InstructionOperand InstructionSequenceTest::Unallocated(
    TestOperand op, UnallocatedOperand::ExtendedPolicy policy,
    UnallocatedOperand::Lifetime lifetime) {
  return UnallocatedOperand(policy, lifetime, op.vreg_.value_);
}

InstructionOperand InstructionSequenceTest::Unallocated(
    TestOperand op, UnallocatedOperand::ExtendedPolicy policy, int index) {
  return UnallocatedOperand(policy, index, op.vreg_.value_);
}

InstructionOperand InstructionSequenceTest::Unallocated(
    TestOperand op, UnallocatedOperand::BasicPolicy policy, int index) {
  return UnallocatedOperand(policy, index, op.vreg_.value_);
}

InstructionOperand* InstructionSequenceTest::ConvertInputs(
    size_t input_size, TestOperand* inputs) {
  InstructionOperand* mapped_inputs =
      zone()->NewArray<InstructionOperand>(static_cast<int>(input_size));
  for (size_t i = 0; i < input_size; ++i) {
    mapped_inputs[i] = ConvertInputOp(inputs[i]);
  }
  return mapped_inputs;
}

InstructionOperand InstructionSequenceTest::ConvertInputOp(TestOperand op) {
  if (op.type_ == kImmediate) {
    CHECK_EQ(op.vreg_.value_, kNoValue);
    return ImmediateOperand(ImmediateOperand::INLINE, op.value_);
  }
  CHECK_NE(op.vreg_.value_, kNoValue);
  switch (op.type_) {
    case kNone:
      return Unallocated(op, UnallocatedOperand::NONE,
                         UnallocatedOperand::USED_AT_START);
    case kUnique:
      return Unallocated(op, UnallocatedOperand::NONE);
    case kUniqueRegister:
      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER);
    case kRegister:
      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER,
                         UnallocatedOperand::USED_AT_START);
    case kSlot:
      return Unallocated(op, UnallocatedOperand::MUST_HAVE_SLOT,
                         UnallocatedOperand::USED_AT_START);
    case kFixedRegister: {
      MachineRepresentation rep = GetCanonicalRep(op);
      CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep));
      if (DoesRegisterAllocation()) {
        auto extended_policy = IsFloatingPoint(rep)
                                   ? UnallocatedOperand::FIXED_FP_REGISTER
                                   : UnallocatedOperand::FIXED_REGISTER;
        return Unallocated(op, extended_policy, op.value_);
      } else {
        return AllocatedOperand(LocationOperand::REGISTER, rep, op.value_);
      }
    }
    case kFixedSlot:
      if (DoesRegisterAllocation()) {
        return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_);
      } else {
        return AllocatedOperand(LocationOperand::STACK_SLOT,
                                GetCanonicalRep(op), op.value_);
      }
    default:
      break;
  }
  UNREACHABLE();
}

InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg,
                                                            TestOperand op) {
  CHECK_EQ(op.vreg_.value_, kNoValue);
  op.vreg_ = vreg;
  switch (op.type_) {
    case kSameAsFirst:
      return Unallocated(op, UnallocatedOperand::SAME_AS_FIRST_INPUT);
    case kRegister:
      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER);
    case kFixedSlot:
      if (DoesRegisterAllocation()) {
        return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_);
      } else {
        return AllocatedOperand(LocationOperand::STACK_SLOT,
                                GetCanonicalRep(op), op.value_);
      }
    case kFixedRegister: {
      MachineRepresentation rep = GetCanonicalRep(op);
      CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep));
      if (DoesRegisterAllocation()) {
        auto extended_policy = IsFloatingPoint(rep)
                                   ? UnallocatedOperand::FIXED_FP_REGISTER
                                   : UnallocatedOperand::FIXED_REGISTER;
        return Unallocated(op, extended_policy, op.value_);
      } else {
        return AllocatedOperand(LocationOperand::REGISTER, rep, op.value_);
      }
    }
    default:
      break;
  }
  UNREACHABLE();
}

InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) {
  CHECK_NULL(current_block_);
  Rpo rpo = Rpo::FromInt(static_cast<int>(instruction_blocks_.size()));
  Rpo loop_header = Rpo::Invalid();
  Rpo loop_end = Rpo::Invalid();
  if (!loop_blocks_.empty()) {
    auto& loop_data = loop_blocks_.back();
    // This is a loop header.
    if (!loop_data.loop_header_.IsValid()) {
      loop_end = Rpo::FromInt(rpo.ToInt() + loop_data.expected_blocks_);
      loop_data.expected_blocks_--;
      loop_data.loop_header_ = rpo;
    } else {
      // This is a loop body.
      CHECK_NE(0, loop_data.expected_blocks_);
      // TODO(dcarney): handle nested loops.
      loop_data.expected_blocks_--;
      loop_header = loop_data.loop_header_;
    }
  }
  // Construct instruction block.
  auto instruction_block = new (zone())
      InstructionBlock(zone(), rpo, loop_header, loop_end, deferred, false);
  instruction_blocks_.push_back(instruction_block);
  current_block_ = instruction_block;
  sequence()->StartBlock(rpo);
  return instruction_block;
}

void InstructionSequenceTest::WireBlocks() {
  CHECK(!current_block());
  CHECK(instruction_blocks_.size() == completions_.size());
  CHECK(loop_blocks_.empty());
  // Wire in end block to look like a scheduler produced cfg.
  auto end_block = NewBlock();
  Emit(kArchNop);
  current_block_ = nullptr;
  sequence()->EndBlock(end_block->rpo_number());
  size_t offset = 0;
  for (const auto& completion : completions_) {
    switch (completion.type_) {
      case kBlockEnd: {
        auto block = instruction_blocks_[offset];
        block->successors().push_back(end_block->rpo_number());
        end_block->predecessors().push_back(block->rpo_number());
        break;
      }
      case kFallThrough:  // Fallthrough.
      case kJump:
        WireBlock(offset, completion.offset_0_);
        break;
      case kBranch:
        WireBlock(offset, completion.offset_0_);
        WireBlock(offset, completion.offset_1_);
        break;
    }
    ++offset;
  }
}

void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
  size_t target_block_offset = block_offset + static_cast<size_t>(jump_offset);
  CHECK(block_offset < instruction_blocks_.size());
  CHECK(target_block_offset < instruction_blocks_.size());
  auto block = instruction_blocks_[block_offset];
  auto target = instruction_blocks_[target_block_offset];
  block->successors().push_back(target->rpo_number());
  target->predecessors().push_back(block->rpo_number());
}

Instruction* InstructionSequenceTest::Emit(
    InstructionCode code, size_t outputs_size, InstructionOperand* outputs,
    size_t inputs_size, InstructionOperand* inputs, size_t temps_size,
    InstructionOperand* temps, bool is_call) {
  auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size,
                                    inputs, temps_size, temps);
  if (is_call) instruction->MarkAsCall();
  return AddInstruction(instruction);
}

Instruction* InstructionSequenceTest::AddInstruction(Instruction* instruction) {
  sequence()->AddInstruction(instruction);
  return instruction;
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
