// Copyright (c) 2020 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_add_loops_to_create_int_constant_synonyms.h"

#include "source/fuzz/call_graph.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/transformation_add_loop_to_create_int_constant_synonym.h"

namespace spvtools {
namespace fuzz {
namespace {
uint32_t kMaxNestingDepth = 4;
}  // namespace

FuzzerPassAddLoopsToCreateIntConstantSynonyms::
    FuzzerPassAddLoopsToCreateIntConstantSynonyms(
        opt::IRContext* ir_context,
        TransformationContext* transformation_context,
        FuzzerContext* fuzzer_context,
        protobufs::TransformationSequence* transformations)
    : FuzzerPass(ir_context, transformation_context, fuzzer_context,
                 transformations) {}

FuzzerPassAddLoopsToCreateIntConstantSynonyms::
    ~FuzzerPassAddLoopsToCreateIntConstantSynonyms() = default;

void FuzzerPassAddLoopsToCreateIntConstantSynonyms::Apply() {
  std::vector<uint32_t> constants;

  // Choose the constants for which to create synonyms.
  for (auto constant_def : GetIRContext()->GetConstants()) {
    // Randomly decide whether to consider this constant.
    if (!GetFuzzerContext()->ChoosePercentage(
            GetFuzzerContext()->GetChanceOfCreatingIntSynonymsUsingLoops())) {
      continue;
    }

    auto constant = GetIRContext()->get_constant_mgr()->FindDeclaredConstant(
        constant_def->result_id());

    // We do not consider irrelevant constants
    if (GetTransformationContext()->GetFactManager()->IdIsIrrelevant(
            constant_def->result_id())) {
      continue;
    }

    // We only consider integer constants (scalar or vector).
    if (!constant->AsIntConstant() &&
        !(constant->AsVectorConstant() &&
          constant->AsVectorConstant()->component_type()->AsInteger())) {
      continue;
    }

    constants.push_back(constant_def->result_id());
  }

  std::vector<uint32_t> blocks;

  // Get a list of all the blocks before which we can add a loop creating a new
  // synonym. We cannot apply the transformation while iterating over the
  // module, because we are going to add new blocks.
  for (auto& function : *GetIRContext()->module()) {
    // Consider all blocks reachable from the first block of the function.
    GetIRContext()->cfg()->ForEachBlockInPostOrder(
        &*function.begin(),
        [&blocks](opt::BasicBlock* block) { blocks.push_back(block->id()); });
  }

  // Make sure that the module has an OpTypeBool instruction, and 32-bit signed
  // integer constants 0 and 1, adding them if necessary.
  FindOrCreateBoolType();
  FindOrCreateIntegerConstant({0}, 32, true, false);
  FindOrCreateIntegerConstant({1}, 32, true, false);

  // Compute the call graph. We can use this for any further computation, since
  // we are not adding or removing functions or function calls.
  auto call_graph = CallGraph(GetIRContext());

  // Consider each constant and each block.
  for (uint32_t constant_id : constants) {
    // Choose one of the blocks.
    uint32_t block_id = blocks[GetFuzzerContext()->RandomIndex(blocks)];

    // Adjust the block so that the transformation can be applied.
    auto block = GetIRContext()->get_instr_block(block_id);

    // If the block is a loop header, add a simple preheader. We can do this
    // because we have excluded all the non-reachable headers.
    if (block->IsLoopHeader()) {
      block = GetOrCreateSimpleLoopPreheader(block->id());
      block_id = block->id();
    }

    assert(!block->IsLoopHeader() &&
           "The block cannot be a loop header at this point.");

    // If the block is a merge block, a continue block or it does not have
    // exactly 1 predecessor, split it after any OpPhi or OpVariable
    // instructions.
    if (GetIRContext()->GetStructuredCFGAnalysis()->IsMergeBlock(block->id()) ||
        GetIRContext()->GetStructuredCFGAnalysis()->IsContinueBlock(
            block->id()) ||
        GetIRContext()->cfg()->preds(block->id()).size() != 1) {
      block = SplitBlockAfterOpPhiOrOpVariable(block->id());
      block_id = block->id();
    }

    // Randomly decide the values for the number of iterations and the step
    // value, and compute the initial value accordingly.

    // The maximum number of iterations depends on the maximum possible loop
    // nesting depth of the block, computed interprocedurally, i.e. also
    // considering the possibility that the enclosing function is called inside
    // a loop. It is:
    // - 1 if the nesting depth is >= kMaxNestingDepth
    // - 2^(kMaxNestingDepth - nesting_depth) otherwise
    uint32_t max_nesting_depth =
        call_graph.GetMaxCallNestingDepth(block->GetParent()->result_id()) +
        GetIRContext()->GetStructuredCFGAnalysis()->LoopNestingDepth(
            block->id());
    uint32_t num_iterations =
        max_nesting_depth >= kMaxNestingDepth
            ? 1
            : GetFuzzerContext()->GetRandomNumberOfLoopIterations(
                  1u << (kMaxNestingDepth - max_nesting_depth));

    // Find or create the corresponding constant containing the number of
    // iterations.
    uint32_t num_iterations_id =
        FindOrCreateIntegerConstant({num_iterations}, 32, true, false);

    // Find the other constants.
    // We use 64-bit values and then use the bits that we need. We find the
    // step value (S) randomly and then compute the initial value (I) using
    // the equation I = C + S*N.
    uint32_t initial_value_id = 0;
    uint32_t step_value_id = 0;

    // Get the content of the existing constant.
    const auto constant =
        GetIRContext()->get_constant_mgr()->FindDeclaredConstant(constant_id);
    const auto constant_type_id =
        GetIRContext()->get_def_use_mgr()->GetDef(constant_id)->type_id();

    if (constant->AsIntConstant()) {
      // The constant is a scalar integer.

      std::tie(initial_value_id, step_value_id) =
          FindSuitableStepAndInitialValueConstants(
              constant->GetZeroExtendedValue(),
              constant->type()->AsInteger()->width(),
              constant->type()->AsInteger()->IsSigned(), num_iterations);
    } else {
      // The constant is a vector of integers.
      assert(constant->AsVectorConstant() &&
             constant->AsVectorConstant()->component_type()->AsInteger() &&
             "If the program got here, the constant should be a vector of "
             "integers.");

      // Find a constant for each component of the initial value and the step
      // values.
      std::vector<uint32_t> initial_value_component_ids;
      std::vector<uint32_t> step_value_component_ids;

      // Get the value, width and signedness of the components.
      std::vector<uint64_t> component_values;
      for (auto component : constant->AsVectorConstant()->GetComponents()) {
        component_values.push_back(component->GetZeroExtendedValue());
      }
      uint32_t bit_width =
          constant->AsVectorConstant()->component_type()->AsInteger()->width();
      uint32_t is_signed = constant->AsVectorConstant()
                               ->component_type()
                               ->AsInteger()
                               ->IsSigned();

      for (uint64_t component_val : component_values) {
        uint32_t initial_val_id;
        uint32_t step_val_id;
        std::tie(initial_val_id, step_val_id) =
            FindSuitableStepAndInitialValueConstants(component_val, bit_width,
                                                     is_signed, num_iterations);
        initial_value_component_ids.push_back(initial_val_id);
        step_value_component_ids.push_back(step_val_id);
      }

      // Find or create the vector constants.
      initial_value_id = FindOrCreateCompositeConstant(
          initial_value_component_ids, constant_type_id, false);
      step_value_id = FindOrCreateCompositeConstant(step_value_component_ids,
                                                    constant_type_id, false);
    }

    assert(initial_value_id && step_value_id &&
           "|initial_value_id| and |step_value_id| should have been defined.");

    // Randomly decide whether to have two blocks (or just one) in the new
    // loop.
    uint32_t additional_block_id =
        GetFuzzerContext()->ChoosePercentage(
            GetFuzzerContext()
                ->GetChanceOfHavingTwoBlocksInLoopToCreateIntSynonym())
            ? GetFuzzerContext()->GetFreshId()
            : 0;

    // Add the loop and create the synonym.
    ApplyTransformation(TransformationAddLoopToCreateIntConstantSynonym(
        constant_id, initial_value_id, step_value_id, num_iterations_id,
        block_id, GetFuzzerContext()->GetFreshId(),
        GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId(),
        GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId(),
        GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId(),
        additional_block_id));
  }
}

std::pair<uint32_t, uint32_t> FuzzerPassAddLoopsToCreateIntConstantSynonyms::
    FindSuitableStepAndInitialValueConstants(uint64_t constant_val,
                                             uint32_t bit_width, bool is_signed,
                                             uint32_t num_iterations) {
  // Choose the step value randomly and compute the initial value accordingly.
  // The result of |initial_value| could overflow, but this is OK, since
  // the transformation takes overflows into consideration (the equation still
  // holds as long as the last |bit_width| bits of C and of (I-S*N) match).
  uint64_t step_value =
      GetFuzzerContext()->GetRandomValueForStepConstantInLoop();
  uint64_t initial_value = constant_val + step_value * num_iterations;

  uint32_t initial_val_id = FindOrCreateIntegerConstant(
      fuzzerutil::IntToWords(initial_value, bit_width, is_signed), bit_width,
      is_signed, false);

  uint32_t step_val_id = FindOrCreateIntegerConstant(
      fuzzerutil::IntToWords(step_value, bit_width, is_signed), bit_width,
      is_signed, false);

  return {initial_val_id, step_val_id};
}

}  // namespace fuzz
}  // namespace spvtools