// Copyright (c) 2015-2016 The Khronos Group 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 <unordered_set>
#include <vector>

#include "source/instruction.h"
#include "source/opcode.h"
#include "source/operand.h"
#include "source/val/function.h"
#include "source/val/validate.h"
#include "source/val/validation_state.h"
#include "spirv-tools/libspirv.h"

namespace spvtools {
namespace val {

spv_result_t UpdateIdUse(ValidationState_t& _, const Instruction* inst) {
  for (auto& operand : inst->operands()) {
    const spv_operand_type_t& type = operand.type;
    const uint32_t operand_id = inst->word(operand.offset);
    if (spvIsIdType(type) && type != SPV_OPERAND_TYPE_RESULT_ID) {
      if (auto def = _.FindDef(operand_id))
        def->RegisterUse(inst, operand.offset);
    }
  }

  return SPV_SUCCESS;
}

/// This function checks all ID definitions dominate their use in the CFG.
///
/// This function will iterate over all ID definitions that are defined in the
/// functions of a module and make sure that the definitions appear in a
/// block that dominates their use.
///
/// NOTE: This function does NOT check module scoped functions which are
/// checked during the initial binary parse in the IdPass below
spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) {
  std::vector<const Instruction*> phi_instructions;
  std::unordered_set<uint32_t> phi_ids;
  for (const auto& inst : _.ordered_instructions()) {
    if (inst.id() == 0) continue;
    if (const Function* func = inst.function()) {
      if (const BasicBlock* block = inst.block()) {
        // If the Id is defined within a block then make sure all references to
        // that Id appear in a blocks that are dominated by the defining block
        for (auto& use_index_pair : inst.uses()) {
          const Instruction* use = use_index_pair.first;
          if (const BasicBlock* use_block = use->block()) {
            if (use_block->reachable() == false) continue;
            if (use->opcode() == spv::Op::OpPhi) {
              if (phi_ids.insert(use->id()).second) {
                phi_instructions.push_back(use);
              }
            } else if (!block->dominates(*use->block())) {
              return _.diag(SPV_ERROR_INVALID_ID, use_block->label())
                     << "ID " << _.getIdName(inst.id()) << " defined in block "
                     << _.getIdName(block->id())
                     << " does not dominate its use in block "
                     << _.getIdName(use_block->id());
            }
          }
        }
      } else {
        // If the Ids defined within a function but not in a block(i.e. function
        // parameters, block ids), then make sure all references to that Id
        // appear within the same function
        for (auto use : inst.uses()) {
          const Instruction* user = use.first;
          if (user->function() && user->function() != func) {
            return _.diag(SPV_ERROR_INVALID_ID, _.FindDef(func->id()))
                   << "ID " << _.getIdName(inst.id()) << " used in function "
                   << _.getIdName(user->function()->id())
                   << " is used outside of it's defining function "
                   << _.getIdName(func->id());
          }
        }
      }
    }
    // NOTE: Ids defined outside of functions must appear before they are used
    // This check is being performed in the IdPass function
  }

  // Check all OpPhi parent blocks are dominated by the variable's defining
  // blocks
  for (const Instruction* phi : phi_instructions) {
    if (phi->block()->reachable() == false) continue;
    for (size_t i = 3; i < phi->operands().size(); i += 2) {
      const Instruction* variable = _.FindDef(phi->word(i));
      const BasicBlock* parent =
          phi->function()->GetBlock(phi->word(i + 1)).first;
      if (variable->block() && parent->reachable() &&
          !variable->block()->dominates(*parent)) {
        return _.diag(SPV_ERROR_INVALID_ID, phi)
               << "In OpPhi instruction " << _.getIdName(phi->id()) << ", ID "
               << _.getIdName(variable->id())
               << " definition does not dominate its parent "
               << _.getIdName(parent->id());
      }
    }
  }

  return SPV_SUCCESS;
}

bool InstructionCanHaveTypeOperand(const Instruction* inst) {
  static std::unordered_set<spv::Op> instruction_allow_set{
      spv::Op::OpSizeOf,
      spv::Op::OpCooperativeMatrixLengthNV,
      spv::Op::OpCooperativeMatrixLengthKHR,
      spv::Op::OpUntypedArrayLengthKHR,
      spv::Op::OpFunction,
      spv::Op::OpAsmINTEL,
      spv::Op::OpConstantSizeOfEXT,
      spv::Op::OpBufferPointerEXT,
      spv::Op::OpUntypedImageTexelPointerEXT,
  };
  const auto opcode = inst->opcode();
  bool type_instruction = spvOpcodeGeneratesType(opcode);
  bool debug_instruction = spvOpcodeIsDebug(opcode) || inst->IsDebugInfo();
  bool coop_matrix_spec_constant_op_length =
      (opcode == spv::Op::OpSpecConstantOp) &&
      (spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthNV ||
       spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthKHR);
  return type_instruction || debug_instruction || inst->IsNonSemantic() ||
         spvOpcodeIsDecoration(opcode) || instruction_allow_set.count(opcode) ||
         spvOpcodeGeneratesUntypedPointer(opcode) ||
         coop_matrix_spec_constant_op_length;
}

bool InstructionRequiresTypeOperand(const Instruction* inst) {
  static std::unordered_set<spv::Op> instruction_deny_set{
      spv::Op::OpExtInst,
      spv::Op::OpExtInstWithForwardRefsKHR,
      spv::Op::OpExtInstImport,
      spv::Op::OpSelectionMerge,
      spv::Op::OpLoopMerge,
      spv::Op::OpFunction,
      spv::Op::OpSizeOf,
      spv::Op::OpCooperativeMatrixLengthNV,
      spv::Op::OpCooperativeMatrixLengthKHR,
      spv::Op::OpPhi,
      spv::Op::OpUntypedArrayLengthKHR,
      spv::Op::OpAsmINTEL,
  };
  const auto opcode = inst->opcode();
  bool debug_instruction = spvOpcodeIsDebug(opcode) || inst->IsDebugInfo();
  bool coop_matrix_spec_constant_op_length =
      opcode == spv::Op::OpSpecConstantOp &&
      (spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthNV ||
       spv::Op(inst->word(3)) == spv::Op::OpCooperativeMatrixLengthKHR);

  return !debug_instruction && !inst->IsNonSemantic() &&
         !spvOpcodeIsDecoration(opcode) && !spvOpcodeIsBranch(opcode) &&
         !instruction_deny_set.count(opcode) &&
         !spvOpcodeGeneratesUntypedPointer(opcode) &&
         !coop_matrix_spec_constant_op_length;
}

// Performs SSA validation on the IDs of an instruction. The
// can_have_forward_declared_ids  functor should return true if the
// instruction operand's ID can be forward referenced.
spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
  auto can_have_forward_declared_ids =
      spvIsExtendedInstruction(inst->opcode()) &&
              spvExtInstIsDebugInfo(inst->ext_inst_type())
          ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
                inst->opcode(), inst->ext_inst_type(), inst->word(4))
          : spvOperandCanBeForwardDeclaredFunction(inst->opcode());

  // Keep track of a result id defined by this instruction.  0 means it
  // does not define an id.
  uint32_t result_id = 0;
  bool has_forward_declared_ids = false;

  for (unsigned i = 0; i < inst->operands().size(); i++) {
    const spv_parsed_operand_t& operand = inst->operand(i);
    const spv_operand_type_t& type = operand.type;
    // We only care about Id operands, which are a single word.
    const uint32_t operand_word = inst->word(operand.offset);

    auto ret = SPV_ERROR_INTERNAL;
    switch (type) {
      case SPV_OPERAND_TYPE_RESULT_ID:
        // NOTE: Multiple Id definitions are being checked by the binary parser.
        //
        // Defer undefined-forward-reference removal until after we've analyzed
        // the remaining operands to this instruction.  Deferral only matters
        // for OpPhi since it's the only case where it defines its own forward
        // reference.  Other instructions that can have forward references
        // either don't define a value or the forward reference is to a function
        // Id (and hence defined outside of a function body).
        result_id = operand_word;
        // NOTE: The result Id is added (in RegisterInstruction) *after* all of
        // the other Ids have been checked to avoid premature use in the same
        // instruction.
        ret = SPV_SUCCESS;
        break;
      case SPV_OPERAND_TYPE_ID:
      case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
      case SPV_OPERAND_TYPE_SCOPE_ID:
        if (const auto def = _.FindDef(operand_word)) {
          if (spvOpcodeGeneratesType(def->opcode()) &&
              !InstructionCanHaveTypeOperand(inst)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Operand " << _.getIdName(operand_word)
                   << " cannot be a type";
          } else if (def->type_id() == 0 &&
                     !spvOpcodeGeneratesType(def->opcode()) &&
                     InstructionRequiresTypeOperand(inst)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Operand " << _.getIdName(operand_word)
                   << " requires a type";
          } else if (def->IsNonSemantic() && !inst->IsNonSemantic()) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Operand " << _.getIdName(operand_word)
                   << " in semantic instruction cannot be a non-semantic "
                      "instruction";
          } else {
            ret = SPV_SUCCESS;
          }
        } else if (can_have_forward_declared_ids(i)) {
          has_forward_declared_ids = true;
          if (spvOpcodeGeneratesType(inst->opcode()) &&
              !_.IsForwardPointer(operand_word)) {
            ret = _.diag(SPV_ERROR_INVALID_ID, inst)
                  << "Operand " << _.getIdName(operand_word)
                  << " requires a previous definition";
          } else {
            ret = _.ForwardDeclareId(operand_word);
          }
        } else {
          ret = _.diag(SPV_ERROR_INVALID_ID, inst)
                << "ID " << _.getIdName(operand_word)
                << " has not been defined";
        }
        break;
      case SPV_OPERAND_TYPE_TYPE_ID:
        if (_.IsDefinedId(operand_word)) {
          auto* def = _.FindDef(operand_word);
          if (!spvOpcodeGeneratesType(def->opcode())) {
            ret = _.diag(SPV_ERROR_INVALID_ID, inst)
                  << "ID " << _.getIdName(operand_word) << " is not a type id";
          } else {
            ret = SPV_SUCCESS;
          }
        } else {
          ret = _.diag(SPV_ERROR_INVALID_ID, inst)
                << "ID " << _.getIdName(operand_word)
                << " has not been defined";
        }
        break;
      case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
        // Ideally, this check would live in validate_extensions.cpp. But since
        // forward references are only allowed on non-semantic instructions, and
        // ID validation is done first, we would fail with a "ID had not been
        // defined" error before we could give a more helpful message. For this
        // reason, this test is done here, so we can be more helpful to the
        // user.
        if (inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR &&
            !inst->IsNonSemantic())
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "OpExtInstWithForwardRefsKHR is only allowed with "
                    "non-semantic instructions.";
        ret = SPV_SUCCESS;
        break;
      default:
        ret = SPV_SUCCESS;
        break;
    }
    if (SPV_SUCCESS != ret) return ret;
  }
  const bool must_have_forward_declared_ids =
      inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR;
  if (must_have_forward_declared_ids && !has_forward_declared_ids) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "Opcode OpExtInstWithForwardRefsKHR must have at least one "
              "forward "
              "declared ID.";
  }

  if (result_id) _.RemoveIfForwardDeclared(result_id);

  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
