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

#include "source/fuzz/transformation_set_loop_control.h"

namespace spvtools {
namespace fuzz {

FuzzerPassAdjustLoopControls::FuzzerPassAdjustLoopControls(
    opt::IRContext* ir_context, FactManager* fact_manager,
    FuzzerContext* fuzzer_context,
    protobufs::TransformationSequence* transformations)
    : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {}

FuzzerPassAdjustLoopControls::~FuzzerPassAdjustLoopControls() = default;

void FuzzerPassAdjustLoopControls::Apply() {
  // Consider every merge instruction in the module (via looking through all
  // functions and blocks).
  for (auto& function : *GetIRContext()->module()) {
    for (auto& block : function) {
      if (auto merge_inst = block.GetMergeInst()) {
        // Ignore the instruction if it is not a loop merge.
        if (merge_inst->opcode() != SpvOpLoopMerge) {
          continue;
        }

        // Decide randomly whether to adjust this loop merge.
        if (!GetFuzzerContext()->ChoosePercentage(
                GetFuzzerContext()->GetChanceOfAdjustingLoopControl())) {
          continue;
        }

        uint32_t existing_mask = merge_inst->GetSingleWordOperand(
            TransformationSetLoopControl::kLoopControlMaskInOperandIndex);

        // First, set the new mask to one of None, Unroll or DontUnroll.
        std::vector<uint32_t> basic_masks = {SpvLoopControlMaskNone,
                                             SpvLoopControlUnrollMask,
                                             SpvLoopControlDontUnrollMask};
        uint32_t new_mask =
            basic_masks[GetFuzzerContext()->RandomIndex(basic_masks)];

        // For the loop controls that depend on guarantees about what the loop
        // does, check which of these were present in the existing mask and
        // randomly decide whether to keep them.  They are just hints, so
        // removing them should not change the semantics of the module.
        for (auto mask_bit :
             {SpvLoopControlDependencyInfiniteMask,
              SpvLoopControlDependencyLengthMask,
              SpvLoopControlMinIterationsMask, SpvLoopControlMaxIterationsMask,
              SpvLoopControlIterationMultipleMask}) {
          if ((existing_mask & mask_bit) && GetFuzzerContext()->ChooseEven()) {
            // The mask bits we are considering are not available in all SPIR-V
            // versions.  However, we only include a mask bit if it was present
            // in the original loop control mask, and we work under the
            // assumption that we are transforming a valid module, thus we don't
            // need to actually check whether the SPIR-V version being used
            // supports these loop control mask bits.
            new_mask |= mask_bit;
          }
        }

        // We use 0 for peel count and partial count in the case that we choose
        // not to set these controls.
        uint32_t peel_count = 0;
        uint32_t partial_count = 0;

        // PeelCount and PartialCount are not compatible with DontUnroll, so
        // we check whether DontUnroll is set.
        if (!(new_mask & SpvLoopControlDontUnrollMask)) {
          // If PeelCount is supported by this SPIR-V version, randomly choose
          // whether to set it.  If it was set in the original mask and is not
          // selected for setting here, that amounts to dropping it.
          if (TransformationSetLoopControl::PeelCountIsSupported(
                  GetIRContext()) &&
              GetFuzzerContext()->ChooseEven()) {
            new_mask |= SpvLoopControlPeelCountMask;
            // The peel count is chosen randomly - if PeelCount was already set
            // this will overwrite whatever peel count was previously used.
            peel_count = GetFuzzerContext()->GetRandomLoopControlPeelCount();
          }
          // Similar, but for PartialCount.
          if (TransformationSetLoopControl::PartialCountIsSupported(
                  GetIRContext()) &&
              GetFuzzerContext()->ChooseEven()) {
            new_mask |= SpvLoopControlPartialCountMask;
            partial_count =
                GetFuzzerContext()->GetRandomLoopControlPartialCount();
          }
        }

        // Apply the transformation and add it to the output transformation
        // sequence.
        TransformationSetLoopControl transformation(block.id(), new_mask,
                                                    peel_count, partial_count);
        assert(transformation.IsApplicable(GetIRContext(), *GetFactManager()) &&
               "Transformation should be applicable by construction.");
        transformation.Apply(GetIRContext(), GetFactManager());
        *GetTransformations()->add_transformation() =
            transformation.ToMessage();
      }
    }
  }
}

}  // namespace fuzz
}  // namespace spvtools
