// Copyright (c) 2016 Google Inc.
//
// 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/module.h"

#include <algorithm>
#include <cstring>
#include <ostream>

#include "source/operand.h"
#include "source/opt/ir_context.h"
#include "source/opt/reflect.h"

namespace spvtools {
namespace opt {

uint32_t Module::TakeNextIdBound() {
  if (context()) {
    if (id_bound() >= context()->max_id_bound()) {
      return 0;
    }
  } else if (id_bound() >= kDefaultMaxIdBound) {
    return 0;
  }

  return header_.bound++;
}

std::vector<Instruction*> Module::GetTypes() {
  std::vector<Instruction*> type_insts;
  for (auto& inst : types_values_) {
    if (IsTypeInst(inst.opcode())) type_insts.push_back(&inst);
  }
  return type_insts;
}

std::vector<const Instruction*> Module::GetTypes() const {
  std::vector<const Instruction*> type_insts;
  for (auto& inst : types_values_) {
    if (IsTypeInst(inst.opcode())) type_insts.push_back(&inst);
  }
  return type_insts;
}

std::vector<Instruction*> Module::GetConstants() {
  std::vector<Instruction*> const_insts;
  for (auto& inst : types_values_) {
    if (IsConstantInst(inst.opcode())) const_insts.push_back(&inst);
  }
  return const_insts;
}

std::vector<const Instruction*> Module::GetConstants() const {
  std::vector<const Instruction*> const_insts;
  for (auto& inst : types_values_) {
    if (IsConstantInst(inst.opcode())) const_insts.push_back(&inst);
  }
  return const_insts;
}

uint32_t Module::GetGlobalValue(SpvOp opcode) const {
  for (auto& inst : types_values_) {
    if (inst.opcode() == opcode) return inst.result_id();
  }
  return 0;
}

void Module::AddGlobalValue(SpvOp opcode, uint32_t result_id,
                            uint32_t type_id) {
  std::unique_ptr<Instruction> newGlobal(
      new Instruction(context(), opcode, type_id, result_id, {}));
  AddGlobalValue(std::move(newGlobal));
}

void Module::ForEachInst(const std::function<void(Instruction*)>& f,
                         bool run_on_debug_line_insts) {
#define DELEGATE(list) list.ForEachInst(f, run_on_debug_line_insts)
  DELEGATE(capabilities_);
  DELEGATE(extensions_);
  DELEGATE(ext_inst_imports_);
  if (memory_model_) memory_model_->ForEachInst(f, run_on_debug_line_insts);
  if (sampled_image_address_mode_)
    sampled_image_address_mode_->ForEachInst(f, run_on_debug_line_insts);
  DELEGATE(entry_points_);
  DELEGATE(execution_modes_);
  DELEGATE(debugs1_);
  DELEGATE(debugs2_);
  DELEGATE(debugs3_);
  DELEGATE(ext_inst_debuginfo_);
  DELEGATE(annotations_);
  DELEGATE(types_values_);
  for (auto& i : functions_) {
    i->ForEachInst(f, run_on_debug_line_insts,
                   /* run_on_non_semantic_insts = */ true);
  }
#undef DELEGATE
}

void Module::ForEachInst(const std::function<void(const Instruction*)>& f,
                         bool run_on_debug_line_insts) const {
#define DELEGATE(i) i.ForEachInst(f, run_on_debug_line_insts)
  for (auto& i : capabilities_) DELEGATE(i);
  for (auto& i : extensions_) DELEGATE(i);
  for (auto& i : ext_inst_imports_) DELEGATE(i);
  if (memory_model_)
    static_cast<const Instruction*>(memory_model_.get())
        ->ForEachInst(f, run_on_debug_line_insts);
  if (sampled_image_address_mode_)
    static_cast<const Instruction*>(sampled_image_address_mode_.get())
        ->ForEachInst(f, run_on_debug_line_insts);
  for (auto& i : entry_points_) DELEGATE(i);
  for (auto& i : execution_modes_) DELEGATE(i);
  for (auto& i : debugs1_) DELEGATE(i);
  for (auto& i : debugs2_) DELEGATE(i);
  for (auto& i : debugs3_) DELEGATE(i);
  for (auto& i : annotations_) DELEGATE(i);
  for (auto& i : types_values_) DELEGATE(i);
  for (auto& i : ext_inst_debuginfo_) DELEGATE(i);
  for (auto& i : functions_) {
    static_cast<const Function*>(i.get())->ForEachInst(
        f, run_on_debug_line_insts,
        /* run_on_non_semantic_insts = */ true);
  }
  if (run_on_debug_line_insts) {
    for (auto& i : trailing_dbg_line_info_) DELEGATE(i);
  }
#undef DELEGATE
}

void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
  binary->push_back(header_.magic_number);
  binary->push_back(header_.version);
  // TODO(antiagainst): should we change the generator number?
  binary->push_back(header_.generator);
  binary->push_back(header_.bound);
  binary->push_back(header_.schema);

  size_t bound_idx = binary->size() - 2;
  DebugScope last_scope(kNoDebugScope, kNoInlinedAt);
  const Instruction* last_line_inst = nullptr;
  bool between_merge_and_branch = false;
  bool between_label_and_phi_var = false;
  auto write_inst = [binary, skip_nop, &last_scope, &last_line_inst,
                     &between_merge_and_branch, &between_label_and_phi_var,
                     this](const Instruction* i) {
    // Skip emitting line instructions between merge and branch instructions.
    auto opcode = i->opcode();
    if (between_merge_and_branch && i->IsLineInst()) {
      return;
    }
    between_merge_and_branch = false;
    if (last_line_inst != nullptr) {
      // If the current instruction is OpLine or DebugLine and it is the same
      // as the last line instruction that is still effective (can be applied
      // to the next instruction), we skip writing the current instruction.
      if (i->IsLine()) {
        uint32_t operand_index = 0;
        if (last_line_inst->WhileEachInOperand(
                [&operand_index, i](const uint32_t* word) {
                  assert(i->NumInOperandWords() > operand_index);
                  return *word == i->GetSingleWordInOperand(operand_index++);
                })) {
          return;
        }
      } else if (!i->IsNoLine() && i->dbg_line_insts().empty()) {
        // If the current instruction does not have the line information,
        // the last line information is not effective any more. Emit OpNoLine
        // or DebugNoLine to specify it.
        uint32_t shader_set_id = context()
                                     ->get_feature_mgr()
                                     ->GetExtInstImportId_Shader100DebugInfo();
        if (shader_set_id != 0) {
          binary->push_back((5 << 16) | static_cast<uint16_t>(SpvOpExtInst));
          binary->push_back(context()->get_type_mgr()->GetVoidTypeId());
          binary->push_back(context()->TakeNextId());
          binary->push_back(shader_set_id);
          binary->push_back(NonSemanticShaderDebugInfo100DebugNoLine);
        } else {
          binary->push_back((1 << 16) | static_cast<uint16_t>(SpvOpNoLine));
        }
        last_line_inst = nullptr;
      }
    }

    if (opcode == SpvOpLabel) {
      between_label_and_phi_var = true;
    } else if (opcode != SpvOpVariable && opcode != SpvOpPhi &&
               !spvtools::opt::IsOpLineInst(opcode)) {
      between_label_and_phi_var = false;
    }

    if (!(skip_nop && i->IsNop())) {
      const auto& scope = i->GetDebugScope();
      if (scope != last_scope) {
        // Can only emit nonsemantic instructions after all phi instructions
        // in a block so don't emit scope instructions before phi instructions
        // for NonSemantic.Shader.DebugInfo.100.
        if (!between_label_and_phi_var ||
            context()
                ->get_feature_mgr()
                ->GetExtInstImportId_OpenCL100DebugInfo()) {
          // Emit DebugScope |scope| to |binary|.
          auto dbg_inst = ext_inst_debuginfo_.begin();
          scope.ToBinary(dbg_inst->type_id(), context()->TakeNextId(),
                         dbg_inst->GetSingleWordOperand(2), binary);
        }
        last_scope = scope;
      }

      i->ToBinaryWithoutAttachedDebugInsts(binary);
    }
    // Update the last line instruction.
    if (spvOpcodeIsBlockTerminator(opcode) || i->IsNoLine()) {
      last_line_inst = nullptr;
    } else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
      between_merge_and_branch = true;
      last_line_inst = nullptr;
    } else if (i->IsLine()) {
      last_line_inst = i;
    }
  };
  ForEachInst(write_inst, true);

  // We create new instructions for DebugScope and DebugNoLine. The bound must
  // be updated.
  binary->data()[bound_idx] = header_.bound;
}

uint32_t Module::ComputeIdBound() const {
  uint32_t highest = 0;

  ForEachInst(
      [&highest](const Instruction* inst) {
        for (const auto& operand : *inst) {
          if (spvIsIdType(operand.type)) {
            highest = std::max(highest, operand.words[0]);
          }
        }
      },
      true /* scan debug line insts as well */);

  return highest + 1;
}

bool Module::HasExplicitCapability(uint32_t cap) {
  for (auto& ci : capabilities_) {
    uint32_t tcap = ci.GetSingleWordOperand(0);
    if (tcap == cap) {
      return true;
    }
  }
  return false;
}

uint32_t Module::GetExtInstImportId(const char* extstr) {
  for (auto& ei : ext_inst_imports_)
    if (!ei.GetInOperand(0).AsString().compare(extstr)) return ei.result_id();
  return 0;
}

std::ostream& operator<<(std::ostream& str, const Module& module) {
  module.ForEachInst([&str](const Instruction* inst) {
    str << *inst;
    if (inst->opcode() != SpvOpFunctionEnd) {
      str << std::endl;
    }
  });
  return str;
}

}  // namespace opt
}  // namespace spvtools
