// 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, TransformationContext* transformation_context,
    FuzzerContext* fuzzer_context,
    protobufs::TransformationSequence* transformations,
    bool ignore_inapplicable_transformations)
    : FuzzerPass(ir_context, transformation_context, fuzzer_context,
                 transformations, ignore_inapplicable_transformations) {}

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);
        ApplyTransformation(transformation);
      }
    }
  }
}

}  // namespace fuzz
}  // namespace spvtools
