// 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 "source/val/validate.h"

#include <cassert>

#include <algorithm>
#include <iostream>
#include <iterator>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "source/diagnostic.h"
#include "source/instruction.h"
#include "source/opcode.h"
#include "source/operand.h"
#include "source/spirv_validator_options.h"
#include "source/val/function.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() == SpvOpPhi) {
              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;
}

// 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 =
      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;

  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)) {
          const auto opcode = inst->opcode();
          if (spvOpcodeGeneratesType(def->opcode()) &&
              !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) &&
              !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) &&
              opcode != SpvOpFunction &&
              opcode != SpvOpCooperativeMatrixLengthNV &&
              !(opcode == SpvOpSpecConstantOp &&
                inst->word(3) == SpvOpCooperativeMatrixLengthNV)) {
            return _.diag(SPV_ERROR_INVALID_ID, inst)
                   << "Operand " << _.getIdName(operand_word)
                   << " cannot be a type";
          } else if (def->type_id() == 0 && !spvOpcodeGeneratesType(opcode) &&
                     !spvOpcodeIsDebug(opcode) && !inst->IsNonSemantic() &&
                     !spvOpcodeIsDecoration(opcode) &&
                     !spvOpcodeIsBranch(opcode) && opcode != SpvOpPhi &&
                     opcode != SpvOpExtInst && opcode != SpvOpExtInstImport &&
                     opcode != SpvOpSelectionMerge &&
                     opcode != SpvOpLoopMerge && opcode != SpvOpFunction &&
                     opcode != SpvOpCooperativeMatrixLengthNV &&
                     !(opcode == SpvOpSpecConstantOp &&
                       inst->word(3) == SpvOpCooperativeMatrixLengthNV)) {
            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)) {
          if (inst->opcode() == SpvOpTypeStruct &&
              !_.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;
      default:
        ret = SPV_SUCCESS;
        break;
    }
    if (SPV_SUCCESS != ret) return ret;
  }
  if (result_id) _.RemoveIfForwardDeclared(result_id);

  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
