// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "source/opt/desc_sroa.h"

#include "source/opt/desc_sroa_util.h"
#include "source/util/string_utils.h"

namespace spvtools {
namespace opt {
namespace {

bool IsDecorationBinding(Instruction* inst) {
  if (inst->opcode() != spv::Op::OpDecorate) return false;
  return spv::Decoration(inst->GetSingleWordInOperand(1u)) ==
         spv::Decoration::Binding;
}

}  // namespace

Pass::Status DescriptorScalarReplacement::Process() {
  bool modified = false;
  std::vector<Instruction*> vars_to_kill;

  for (Instruction& var : context()->types_values()) {
    bool is_candidate =
        flatten_arrays_ && descsroautil::IsDescriptorArray(context(), &var);
    is_candidate |= flatten_composites_ &&
                    descsroautil::IsDescriptorStruct(context(), &var);
    if (is_candidate) {
      modified = true;
      if (!ReplaceCandidate(&var)) {
        return Status::Failure;
      }
      vars_to_kill.push_back(&var);
    }
  }

  for (Instruction* var : vars_to_kill) {
    context()->KillInst(var);
  }

  return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
}

bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) {
  std::vector<Instruction*> access_chain_work_list;
  std::vector<Instruction*> load_work_list;
  std::vector<Instruction*> entry_point_work_list;
  bool failed = !get_def_use_mgr()->WhileEachUser(
      var->result_id(), [this, &access_chain_work_list, &load_work_list,
                         &entry_point_work_list](Instruction* use) {
        if (use->opcode() == spv::Op::OpName) {
          return true;
        }

        if (use->IsDecoration()) {
          return true;
        }

        switch (use->opcode()) {
          case spv::Op::OpAccessChain:
          case spv::Op::OpInBoundsAccessChain:
            access_chain_work_list.push_back(use);
            return true;
          case spv::Op::OpLoad:
            load_work_list.push_back(use);
            return true;
          case spv::Op::OpEntryPoint:
            entry_point_work_list.push_back(use);
            return true;
          default:
            context()->EmitErrorMessage(
                "Variable cannot be replaced: invalid instruction", use);
            return false;
        }
        return true;
      });

  if (failed) {
    return false;
  }

  for (Instruction* use : access_chain_work_list) {
    if (!ReplaceAccessChain(var, use)) {
      return false;
    }
  }
  for (Instruction* use : load_work_list) {
    if (!ReplaceLoadedValue(var, use)) {
      return false;
    }
  }
  for (Instruction* use : entry_point_work_list) {
    if (!ReplaceEntryPoint(var, use)) {
      return false;
    }
  }
  return true;
}

bool DescriptorScalarReplacement::ReplaceAccessChain(Instruction* var,
                                                     Instruction* use) {
  if (use->NumInOperands() <= 1) {
    context()->EmitErrorMessage(
        "Variable cannot be replaced: invalid instruction", use);
    return false;
  }

  const analysis::Constant* const_index =
      descsroautil::GetAccessChainIndexAsConst(context(), use);
  if (const_index == nullptr) {
    context()->EmitErrorMessage("Variable cannot be replaced: invalid index",
                                use);
    return false;
  }

  uint32_t idx = const_index->GetU32();
  uint32_t replacement_var = GetReplacementVariable(var, idx);

  if (use->NumInOperands() == 2) {
    // We are not indexing into the replacement variable.  We can replaces the
    // access chain with the replacement variable itself.
    context()->ReplaceAllUsesWith(use->result_id(), replacement_var);
    context()->KillInst(use);
    return true;
  }

  // We need to build a new access chain with the replacement variable as the
  // base address.
  Instruction::OperandList new_operands;

  // Same result id and result type.
  new_operands.emplace_back(use->GetOperand(0));
  new_operands.emplace_back(use->GetOperand(1));

  // Use the replacement variable as the base address.
  new_operands.push_back({SPV_OPERAND_TYPE_ID, {replacement_var}});

  // Drop the first index because it is consumed by the replacement, and copy
  // the rest.
  for (uint32_t i = 4; i < use->NumOperands(); i++) {
    new_operands.emplace_back(use->GetOperand(i));
  }

  use->ReplaceOperands(new_operands);
  context()->UpdateDefUse(use);
  return true;
}

bool DescriptorScalarReplacement::ReplaceEntryPoint(Instruction* var,
                                                    Instruction* use) {
  // Build a new |OperandList| for |use| that removes |var| and adds its
  // replacement variables.
  Instruction::OperandList new_operands;

  // Copy all operands except |var|.
  bool found = false;
  for (uint32_t idx = 0; idx < use->NumOperands(); idx++) {
    Operand& op = use->GetOperand(idx);
    if (op.type == SPV_OPERAND_TYPE_ID && op.words[0] == var->result_id()) {
      found = true;
    } else {
      new_operands.emplace_back(op);
    }
  }

  if (!found) {
    context()->EmitErrorMessage(
        "Variable cannot be replaced: invalid instruction", use);
    return false;
  }

  // Add all new replacement variables.
  uint32_t num_replacement_vars =
      descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var);
  for (uint32_t i = 0; i < num_replacement_vars; i++) {
    new_operands.push_back(
        {SPV_OPERAND_TYPE_ID, {GetReplacementVariable(var, i)}});
  }

  use->ReplaceOperands(new_operands);
  context()->UpdateDefUse(use);
  return true;
}

uint32_t DescriptorScalarReplacement::GetReplacementVariable(Instruction* var,
                                                             uint32_t idx) {
  auto replacement_vars = replacement_variables_.find(var);
  if (replacement_vars == replacement_variables_.end()) {
    uint32_t number_of_elements =
        descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var);
    replacement_vars =
        replacement_variables_
            .insert({var, std::vector<uint32_t>(number_of_elements, 0)})
            .first;
  }

  if (replacement_vars->second[idx] == 0) {
    replacement_vars->second[idx] = CreateReplacementVariable(var, idx);
  }

  return replacement_vars->second[idx];
}

void DescriptorScalarReplacement::CopyDecorationsForNewVariable(
    Instruction* old_var, uint32_t index, uint32_t new_var_id,
    uint32_t new_var_ptr_type_id, const bool is_old_var_array,
    const bool is_old_var_struct, Instruction* old_var_type) {
  // Handle OpDecorate and OpDecorateString instructions.
  for (auto old_decoration :
       get_decoration_mgr()->GetDecorationsFor(old_var->result_id(), true)) {
    uint32_t new_binding = 0;
    if (IsDecorationBinding(old_decoration)) {
      new_binding = GetNewBindingForElement(
          old_decoration->GetSingleWordInOperand(2), index, new_var_ptr_type_id,
          is_old_var_array, is_old_var_struct, old_var_type);
    }
    CreateNewDecorationForNewVariable(old_decoration, new_var_id, new_binding);
  }

  // Handle OpMemberDecorate instructions.
  for (auto old_decoration : get_decoration_mgr()->GetDecorationsFor(
           old_var_type->result_id(), true)) {
    assert(old_decoration->opcode() == spv::Op::OpMemberDecorate);
    if (old_decoration->GetSingleWordInOperand(1u) != index) continue;
    CreateNewDecorationForMemberDecorate(old_decoration, new_var_id);
  }
}

uint32_t DescriptorScalarReplacement::GetNewBindingForElement(
    uint32_t old_binding, uint32_t index, uint32_t new_var_ptr_type_id,
    const bool is_old_var_array, const bool is_old_var_struct,
    Instruction* old_var_type) {
  if (is_old_var_array) {
    return old_binding + index * GetNumBindingsUsedByType(new_var_ptr_type_id);
  }
  if (is_old_var_struct) {
    // The binding offset that should be added is the sum of binding
    // numbers used by previous members of the current struct.
    uint32_t new_binding = old_binding;
    for (uint32_t i = 0; i < index; ++i) {
      new_binding +=
          GetNumBindingsUsedByType(old_var_type->GetSingleWordInOperand(i));
    }
    return new_binding;
  }
  return old_binding;
}

void DescriptorScalarReplacement::CreateNewDecorationForNewVariable(
    Instruction* old_decoration, uint32_t new_var_id, uint32_t new_binding) {
  assert(old_decoration->opcode() == spv::Op::OpDecorate ||
         old_decoration->opcode() == spv::Op::OpDecorateString);
  std::unique_ptr<Instruction> new_decoration(old_decoration->Clone(context()));
  new_decoration->SetInOperand(0, {new_var_id});

  if (IsDecorationBinding(new_decoration.get())) {
    new_decoration->SetInOperand(2, {new_binding});
  }
  context()->AddAnnotationInst(std::move(new_decoration));
}

void DescriptorScalarReplacement::CreateNewDecorationForMemberDecorate(
    Instruction* old_member_decoration, uint32_t new_var_id) {
  std::vector<Operand> operands(
      {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {new_var_id}}});
  auto new_decorate_operand_begin = old_member_decoration->begin() + 2u;
  auto new_decorate_operand_end = old_member_decoration->end();
  operands.insert(operands.end(), new_decorate_operand_begin,
                  new_decorate_operand_end);
  get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, std::move(operands));
}

uint32_t DescriptorScalarReplacement::CreateReplacementVariable(
    Instruction* var, uint32_t idx) {
  // The storage class for the new variable is the same as the original.
  spv::StorageClass storage_class =
      static_cast<spv::StorageClass>(var->GetSingleWordInOperand(0));

  // The type for the new variable will be a pointer to type of the elements of
  // the array.
  uint32_t ptr_type_id = var->type_id();
  Instruction* ptr_type_inst = get_def_use_mgr()->GetDef(ptr_type_id);
  assert(ptr_type_inst->opcode() == spv::Op::OpTypePointer &&
         "Variable should be a pointer to an array or structure.");
  uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1);
  Instruction* pointee_type_inst = get_def_use_mgr()->GetDef(pointee_type_id);
  const bool is_array = pointee_type_inst->opcode() == spv::Op::OpTypeArray;
  const bool is_struct = pointee_type_inst->opcode() == spv::Op::OpTypeStruct;
  assert((is_array || is_struct) &&
         "Variable should be a pointer to an array or structure.");

  uint32_t element_type_id =
      is_array ? pointee_type_inst->GetSingleWordInOperand(0)
               : pointee_type_inst->GetSingleWordInOperand(idx);

  uint32_t ptr_element_type_id = context()->get_type_mgr()->FindPointerToType(
      element_type_id, storage_class);

  // Create the variable.
  uint32_t id = TakeNextId();
  std::unique_ptr<Instruction> variable(
      new Instruction(context(), spv::Op::OpVariable, ptr_element_type_id, id,
                      std::initializer_list<Operand>{
                          {SPV_OPERAND_TYPE_STORAGE_CLASS,
                           {static_cast<uint32_t>(storage_class)}}}));
  context()->AddGlobalValue(std::move(variable));

  CopyDecorationsForNewVariable(var, idx, id, ptr_element_type_id, is_array,
                                is_struct, pointee_type_inst);

  // Create a new OpName for the replacement variable.
  std::vector<std::unique_ptr<Instruction>> names_to_add;
  for (auto p : context()->GetNames(var->result_id())) {
    Instruction* name_inst = p.second;
    std::string name_str = utils::MakeString(name_inst->GetOperand(1).words);
    if (is_array) {
      name_str += "[" + utils::ToString(idx) + "]";
    }
    if (is_struct) {
      Instruction* member_name_inst =
          context()->GetMemberName(pointee_type_inst->result_id(), idx);
      name_str += ".";
      if (member_name_inst)
        name_str += utils::MakeString(member_name_inst->GetOperand(2).words);
      else
        // In case the member does not have a name assigned to it, use the
        // member index.
        name_str += utils::ToString(idx);
    }

    std::unique_ptr<Instruction> new_name(new Instruction(
        context(), spv::Op::OpName, 0, 0,
        std::initializer_list<Operand>{
            {SPV_OPERAND_TYPE_ID, {id}},
            {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}}));
    Instruction* new_name_inst = new_name.get();
    get_def_use_mgr()->AnalyzeInstDefUse(new_name_inst);
    names_to_add.push_back(std::move(new_name));
  }

  // We shouldn't add the new names when we are iterating over name ranges
  // above. We can add all the new names now.
  for (auto& new_name : names_to_add)
    context()->AddDebug2Inst(std::move(new_name));

  return id;
}

uint32_t DescriptorScalarReplacement::GetNumBindingsUsedByType(
    uint32_t type_id) {
  Instruction* type_inst = get_def_use_mgr()->GetDef(type_id);

  // If it's a pointer, look at the underlying type.
  if (type_inst->opcode() == spv::Op::OpTypePointer) {
    type_id = type_inst->GetSingleWordInOperand(1);
    type_inst = get_def_use_mgr()->GetDef(type_id);
  }

  // Arrays consume N*M binding numbers where N is the array length, and M is
  // the number of bindings used by each array element.
  if (type_inst->opcode() == spv::Op::OpTypeArray) {
    uint32_t element_type_id = type_inst->GetSingleWordInOperand(0);
    uint32_t length_id = type_inst->GetSingleWordInOperand(1);
    const analysis::Constant* length_const =
        context()->get_constant_mgr()->FindDeclaredConstant(length_id);
    // OpTypeArray's length must always be a constant
    assert(length_const != nullptr);
    uint32_t num_elems = length_const->GetU32();
    return num_elems * GetNumBindingsUsedByType(element_type_id);
  }

  // The number of bindings consumed by a structure is the sum of the bindings
  // used by its members.
  if (type_inst->opcode() == spv::Op::OpTypeStruct &&
      !descsroautil::IsTypeOfStructuredBuffer(context(), type_inst)) {
    uint32_t sum = 0;
    for (uint32_t i = 0; i < type_inst->NumInOperands(); i++)
      sum += GetNumBindingsUsedByType(type_inst->GetSingleWordInOperand(i));
    return sum;
  }

  // All other types are considered to take up 1 binding number.
  return 1;
}

bool DescriptorScalarReplacement::ReplaceLoadedValue(Instruction* var,
                                                     Instruction* value) {
  // |var| is the global variable that has to be eliminated (OpVariable).
  // |value| is the OpLoad instruction that has loaded |var|.
  // The function expects all users of |value| to be OpCompositeExtract
  // instructions. Otherwise the function returns false with an error message.
  assert(value->opcode() == spv::Op::OpLoad);
  assert(value->GetSingleWordInOperand(0) == var->result_id());
  std::vector<Instruction*> work_list;
  bool failed = !get_def_use_mgr()->WhileEachUser(
      value->result_id(), [this, &work_list](Instruction* use) {
        if (use->opcode() != spv::Op::OpCompositeExtract) {
          context()->EmitErrorMessage(
              "Variable cannot be replaced: invalid instruction", use);
          return false;
        }
        work_list.push_back(use);
        return true;
      });

  if (failed) {
    return false;
  }

  for (Instruction* use : work_list) {
    if (!ReplaceCompositeExtract(var, use)) {
      return false;
    }
  }

  // All usages of the loaded value have been killed. We can kill the OpLoad.
  context()->KillInst(value);
  return true;
}

bool DescriptorScalarReplacement::ReplaceCompositeExtract(
    Instruction* var, Instruction* extract) {
  assert(extract->opcode() == spv::Op::OpCompositeExtract);
  // We're currently only supporting extractions of one index at a time. If we
  // need to, we can handle cases with multiple indexes in the future.
  if (extract->NumInOperands() != 2) {
    context()->EmitErrorMessage(
        "Variable cannot be replaced: invalid instruction", extract);
    return false;
  }

  uint32_t replacement_var =
      GetReplacementVariable(var, extract->GetSingleWordInOperand(1));

  // The result type of the OpLoad is the same as the result type of the
  // OpCompositeExtract.
  uint32_t load_id = TakeNextId();
  std::unique_ptr<Instruction> load(
      new Instruction(context(), spv::Op::OpLoad, extract->type_id(), load_id,
                      std::initializer_list<Operand>{
                          {SPV_OPERAND_TYPE_ID, {replacement_var}}}));
  Instruction* load_instr = load.get();
  get_def_use_mgr()->AnalyzeInstDefUse(load_instr);
  context()->set_instr_block(load_instr, context()->get_instr_block(extract));
  extract->InsertBefore(std::move(load));
  context()->ReplaceAllUsesWith(extract->result_id(), load_id);
  context()->KillInst(extract);
  return true;
}

}  // namespace opt
}  // namespace spvtools
