// 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/fuzz/fuzzer_pass.h"

#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_add_constant_boolean.h"
#include "source/fuzz/transformation_add_constant_composite.h"
#include "source/fuzz/transformation_add_constant_scalar.h"
#include "source/fuzz/transformation_add_global_undef.h"
#include "source/fuzz/transformation_add_type_boolean.h"
#include "source/fuzz/transformation_add_type_float.h"
#include "source/fuzz/transformation_add_type_int.h"
#include "source/fuzz/transformation_add_type_matrix.h"
#include "source/fuzz/transformation_add_type_pointer.h"
#include "source/fuzz/transformation_add_type_vector.h"

namespace spvtools {
namespace fuzz {

FuzzerPass::FuzzerPass(opt::IRContext* ir_context, FactManager* fact_manager,
                       FuzzerContext* fuzzer_context,
                       protobufs::TransformationSequence* transformations)
    : ir_context_(ir_context),
      fact_manager_(fact_manager),
      fuzzer_context_(fuzzer_context),
      transformations_(transformations) {}

FuzzerPass::~FuzzerPass() = default;

std::vector<opt::Instruction*> FuzzerPass::FindAvailableInstructions(
    opt::Function* function, opt::BasicBlock* block,
    const opt::BasicBlock::iterator& inst_it,
    std::function<bool(opt::IRContext*, opt::Instruction*)>
        instruction_is_relevant) const {
  // TODO(afd) The following is (relatively) simple, but may end up being
  //  prohibitively inefficient, as it walks the whole dominator tree for
  //  every instruction that is considered.

  std::vector<opt::Instruction*> result;
  // Consider all global declarations
  for (auto& global : GetIRContext()->module()->types_values()) {
    if (instruction_is_relevant(GetIRContext(), &global)) {
      result.push_back(&global);
    }
  }

  // Consider all function parameters
  function->ForEachParam(
      [this, &instruction_is_relevant, &result](opt::Instruction* param) {
        if (instruction_is_relevant(GetIRContext(), param)) {
          result.push_back(param);
        }
      });

  // Consider all previous instructions in this block
  for (auto prev_inst_it = block->begin(); prev_inst_it != inst_it;
       ++prev_inst_it) {
    if (instruction_is_relevant(GetIRContext(), &*prev_inst_it)) {
      result.push_back(&*prev_inst_it);
    }
  }

  // Walk the dominator tree to consider all instructions from dominating
  // blocks
  auto dominator_analysis = GetIRContext()->GetDominatorAnalysis(function);
  for (auto next_dominator = dominator_analysis->ImmediateDominator(block);
       next_dominator != nullptr;
       next_dominator =
           dominator_analysis->ImmediateDominator(next_dominator)) {
    for (auto& dominating_inst : *next_dominator) {
      if (instruction_is_relevant(GetIRContext(), &dominating_inst)) {
        result.push_back(&dominating_inst);
      }
    }
  }
  return result;
}

void FuzzerPass::MaybeAddTransformationBeforeEachInstruction(
    std::function<
        void(opt::Function* function, opt::BasicBlock* block,
             opt::BasicBlock::iterator inst_it,
             const protobufs::InstructionDescriptor& instruction_descriptor)>
        maybe_apply_transformation) {
  // Consider every block in every function.
  for (auto& function : *GetIRContext()->module()) {
    for (auto& block : function) {
      // We now consider every instruction in the block, randomly deciding
      // whether to apply a transformation before it.

      // In order for transformations to insert new instructions, they need to
      // be able to identify the instruction to insert before.  We describe an
      // instruction via its opcode, 'opc', a base instruction 'base' that has a
      // result id, and the number of instructions with opcode 'opc' that we
      // should skip when searching from 'base' for the desired instruction.
      // (An instruction that has a result id is represented by its own opcode,
      // itself as 'base', and a skip-count of 0.)
      std::vector<std::tuple<uint32_t, SpvOp, uint32_t>>
          base_opcode_skip_triples;

      // The initial base instruction is the block label.
      uint32_t base = block.id();

      // Counts the number of times we have seen each opcode since we reset the
      // base instruction.
      std::map<SpvOp, uint32_t> skip_count;

      // Consider every instruction in the block.  The label is excluded: it is
      // only necessary to consider it as a base in case the first instruction
      // in the block does not have a result id.
      for (auto inst_it = block.begin(); inst_it != block.end(); ++inst_it) {
        if (inst_it->HasResultId()) {
          // In the case that the instruction has a result id, we use the
          // instruction as its own base, and clear the skip counts we have
          // collected.
          base = inst_it->result_id();
          skip_count.clear();
        }
        const SpvOp opcode = inst_it->opcode();

        // Invoke the provided function, which might apply a transformation.
        maybe_apply_transformation(
            &function, &block, inst_it,
            MakeInstructionDescriptor(
                base, opcode,
                skip_count.count(opcode) ? skip_count.at(opcode) : 0));

        if (!inst_it->HasResultId()) {
          skip_count[opcode] =
              skip_count.count(opcode) ? skip_count.at(opcode) + 1 : 1;
        }
      }
    }
  }
}

uint32_t FuzzerPass::FindOrCreateBoolType() {
  opt::analysis::Bool bool_type;
  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&bool_type);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddTypeBoolean(result));
  return result;
}

uint32_t FuzzerPass::FindOrCreate32BitIntegerType(bool is_signed) {
  opt::analysis::Integer int_type(32, is_signed);
  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&int_type);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddTypeInt(result, 32, is_signed));
  return result;
}

uint32_t FuzzerPass::FindOrCreate32BitFloatType() {
  opt::analysis::Float float_type(32);
  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&float_type);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddTypeFloat(result, 32));
  return result;
}

uint32_t FuzzerPass::FindOrCreateVectorType(uint32_t component_type_id,
                                            uint32_t component_count) {
  assert(component_count >= 2 && component_count <= 4 &&
         "Precondition: component count must be in range [2, 4].");
  opt::analysis::Type* component_type =
      GetIRContext()->get_type_mgr()->GetType(component_type_id);
  assert(component_type && "Precondition: the component type must exist.");
  opt::analysis::Vector vector_type(component_type, component_count);
  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&vector_type);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(
      TransformationAddTypeVector(result, component_type_id, component_count));
  return result;
}

uint32_t FuzzerPass::FindOrCreateMatrixType(uint32_t column_count,
                                            uint32_t row_count) {
  assert(column_count >= 2 && column_count <= 4 &&
         "Precondition: column count must be in range [2, 4].");
  assert(row_count >= 2 && row_count <= 4 &&
         "Precondition: row count must be in range [2, 4].");
  uint32_t column_type_id =
      FindOrCreateVectorType(FindOrCreate32BitFloatType(), row_count);
  opt::analysis::Type* column_type =
      GetIRContext()->get_type_mgr()->GetType(column_type_id);
  opt::analysis::Matrix matrix_type(column_type, column_count);
  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&matrix_type);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(
      TransformationAddTypeMatrix(result, column_type_id, column_count));
  return result;
}

uint32_t FuzzerPass::FindOrCreatePointerType(uint32_t base_type_id,
                                             SpvStorageClass storage_class) {
  // We do not use the type manager here, due to problems related to isomorphic
  // but distinct structs not being regarded as different.
  auto existing_id = fuzzerutil::MaybeGetPointerType(
      GetIRContext(), base_type_id, storage_class);
  if (existing_id) {
    return existing_id;
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(
      TransformationAddTypePointer(result, storage_class, base_type_id));
  return result;
}

uint32_t FuzzerPass::FindOrCreatePointerTo32BitIntegerType(
    bool is_signed, SpvStorageClass storage_class) {
  return FindOrCreatePointerType(FindOrCreate32BitIntegerType(is_signed),
                                 storage_class);
}

uint32_t FuzzerPass::FindOrCreate32BitIntegerConstant(uint32_t word,
                                                      bool is_signed) {
  auto uint32_type_id = FindOrCreate32BitIntegerType(is_signed);
  opt::analysis::IntConstant int_constant(
      GetIRContext()->get_type_mgr()->GetType(uint32_type_id)->AsInteger(),
      {word});
  auto existing_constant =
      GetIRContext()->get_constant_mgr()->FindConstant(&int_constant);
  if (existing_constant) {
    return GetIRContext()
        ->get_constant_mgr()
        ->GetDefiningInstruction(existing_constant)
        ->result_id();
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(
      TransformationAddConstantScalar(result, uint32_type_id, {word}));
  return result;
}

uint32_t FuzzerPass::FindOrCreate32BitFloatConstant(uint32_t word) {
  auto float_type_id = FindOrCreate32BitFloatType();
  opt::analysis::FloatConstant float_constant(
      GetIRContext()->get_type_mgr()->GetType(float_type_id)->AsFloat(),
      {word});
  auto existing_constant =
      GetIRContext()->get_constant_mgr()->FindConstant(&float_constant);
  if (existing_constant) {
    return GetIRContext()
        ->get_constant_mgr()
        ->GetDefiningInstruction(existing_constant)
        ->result_id();
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(
      TransformationAddConstantScalar(result, float_type_id, {word}));
  return result;
}

uint32_t FuzzerPass::FindOrCreateBoolConstant(bool value) {
  auto bool_type_id = FindOrCreateBoolType();
  opt::analysis::BoolConstant bool_constant(
      GetIRContext()->get_type_mgr()->GetType(bool_type_id)->AsBool(), value);
  auto existing_constant =
      GetIRContext()->get_constant_mgr()->FindConstant(&bool_constant);
  if (existing_constant) {
    return GetIRContext()
        ->get_constant_mgr()
        ->GetDefiningInstruction(existing_constant)
        ->result_id();
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddConstantBoolean(result, value));
  return result;
}

uint32_t FuzzerPass::FindOrCreateGlobalUndef(uint32_t type_id) {
  for (auto& inst : GetIRContext()->types_values()) {
    if (inst.opcode() == SpvOpUndef && inst.type_id() == type_id) {
      return inst.result_id();
    }
  }
  auto result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddGlobalUndef(result, type_id));
  return result;
}

std::pair<std::vector<uint32_t>, std::map<uint32_t, std::vector<uint32_t>>>
FuzzerPass::GetAvailableBaseTypesAndPointers(
    SpvStorageClass storage_class) const {
  // Records all of the base types available in the module.
  std::vector<uint32_t> base_types;

  // For each base type, records all the associated pointer types that target
  // that base type and that have |storage_class| as their storage class.
  std::map<uint32_t, std::vector<uint32_t>> base_type_to_pointers;

  for (auto& inst : GetIRContext()->types_values()) {
    switch (inst.opcode()) {
      case SpvOpTypeArray:
      case SpvOpTypeBool:
      case SpvOpTypeFloat:
      case SpvOpTypeInt:
      case SpvOpTypeMatrix:
      case SpvOpTypeStruct:
      case SpvOpTypeVector:
        // These types are suitable as pointer base types.  Record the type,
        // and the fact that we cannot yet have seen any pointers that use this
        // as its base type.
        base_types.push_back(inst.result_id());
        base_type_to_pointers.insert({inst.result_id(), {}});
        break;
      case SpvOpTypePointer:
        if (inst.GetSingleWordInOperand(0) == storage_class) {
          // The pointer has the desired storage class, so we are interested in
          // it.  Associate it with its base type.
          base_type_to_pointers.at(inst.GetSingleWordInOperand(1))
              .push_back(inst.result_id());
        }
        break;
      default:
        break;
    }
  }
  return {base_types, base_type_to_pointers};
}

uint32_t FuzzerPass::FindOrCreateZeroConstant(
    uint32_t scalar_or_composite_type_id) {
  auto type_instruction =
      GetIRContext()->get_def_use_mgr()->GetDef(scalar_or_composite_type_id);
  assert(type_instruction && "The type instruction must exist.");
  switch (type_instruction->opcode()) {
    case SpvOpTypeBool:
      return FindOrCreateBoolConstant(false);
    case SpvOpTypeFloat:
      return FindOrCreate32BitFloatConstant(0);
    case SpvOpTypeInt:
      return FindOrCreate32BitIntegerConstant(
          0, type_instruction->GetSingleWordInOperand(1) != 0);
    case SpvOpTypeArray: {
      return GetZeroConstantForHomogeneousComposite(
          *type_instruction, type_instruction->GetSingleWordInOperand(0),
          fuzzerutil::GetArraySize(*type_instruction, GetIRContext()));
    }
    case SpvOpTypeMatrix:
    case SpvOpTypeVector: {
      return GetZeroConstantForHomogeneousComposite(
          *type_instruction, type_instruction->GetSingleWordInOperand(0),
          type_instruction->GetSingleWordInOperand(1));
    }
    case SpvOpTypeStruct: {
      std::vector<const opt::analysis::Constant*> field_zero_constants;
      std::vector<uint32_t> field_zero_ids;
      for (uint32_t index = 0; index < type_instruction->NumInOperands();
           index++) {
        uint32_t field_constant_id = FindOrCreateZeroConstant(
            type_instruction->GetSingleWordInOperand(index));
        field_zero_ids.push_back(field_constant_id);
        field_zero_constants.push_back(
            GetIRContext()->get_constant_mgr()->FindDeclaredConstant(
                field_constant_id));
      }
      return FindOrCreateCompositeConstant(
          *type_instruction, field_zero_constants, field_zero_ids);
    }
    default:
      assert(false && "Unknown type.");
      return 0;
  }
}

uint32_t FuzzerPass::FindOrCreateCompositeConstant(
    const opt::Instruction& composite_type_instruction,
    const std::vector<const opt::analysis::Constant*>& constants,
    const std::vector<uint32_t>& constant_ids) {
  assert(constants.size() == constant_ids.size() &&
         "Precondition: |constants| and |constant_ids| must be in "
         "correspondence.");

  opt::analysis::Type* composite_type = GetIRContext()->get_type_mgr()->GetType(
      composite_type_instruction.result_id());
  std::unique_ptr<opt::analysis::Constant> composite_constant;
  if (composite_type->AsArray()) {
    composite_constant = MakeUnique<opt::analysis::ArrayConstant>(
        composite_type->AsArray(), constants);
  } else if (composite_type->AsMatrix()) {
    composite_constant = MakeUnique<opt::analysis::MatrixConstant>(
        composite_type->AsMatrix(), constants);
  } else if (composite_type->AsStruct()) {
    composite_constant = MakeUnique<opt::analysis::StructConstant>(
        composite_type->AsStruct(), constants);
  } else if (composite_type->AsVector()) {
    composite_constant = MakeUnique<opt::analysis::VectorConstant>(
        composite_type->AsVector(), constants);
  } else {
    assert(false &&
           "Precondition: |composite_type| must declare a composite type.");
    return 0;
  }

  uint32_t existing_constant =
      GetIRContext()->get_constant_mgr()->FindDeclaredConstant(
          composite_constant.get(), composite_type_instruction.result_id());
  if (existing_constant) {
    return existing_constant;
  }
  uint32_t result = GetFuzzerContext()->GetFreshId();
  ApplyTransformation(TransformationAddConstantComposite(
      result, composite_type_instruction.result_id(), constant_ids));
  return result;
}

uint32_t FuzzerPass::GetZeroConstantForHomogeneousComposite(
    const opt::Instruction& composite_type_instruction,
    uint32_t component_type_id, uint32_t num_components) {
  std::vector<const opt::analysis::Constant*> zero_constants;
  std::vector<uint32_t> zero_ids;
  uint32_t zero_component = FindOrCreateZeroConstant(component_type_id);
  const opt::analysis::Constant* registered_zero_component =
      GetIRContext()->get_constant_mgr()->FindDeclaredConstant(zero_component);
  for (uint32_t i = 0; i < num_components; i++) {
    zero_constants.push_back(registered_zero_component);
    zero_ids.push_back(zero_component);
  }
  return FindOrCreateCompositeConstant(composite_type_instruction,
                                       zero_constants, zero_ids);
}

}  // namespace fuzz
}  // namespace spvtools
