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

#include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_set_memory_operands_mask.h"

namespace spvtools {
namespace fuzz {

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

void FuzzerPassAdjustMemoryOperandsMasks::Apply() {
  // Consider every block in every function.
  for (auto& function : *GetIRContext()->module()) {
    for (auto& block : function) {
      // Consider every instruction in this block, using an explicit iterator so
      // that when we find an instruction of interest we can search backwards to
      // create an id descriptor for it.
      for (auto inst_it = block.cbegin(); inst_it != block.cend(); ++inst_it) {
        if (!TransformationSetMemoryOperandsMask::IsMemoryAccess(*inst_it)) {
          // We are only interested in memory access instructions.
          continue;
        }

        std::vector<uint32_t> indices_of_available_masks_to_adjust;
        // All memory instructions have at least one memory operands mask.
        indices_of_available_masks_to_adjust.push_back(0);
        // From SPIR-V 1.4 onwards, OpCopyMemory and OpCopyMemorySized have a
        // second mask.
        switch (inst_it->opcode()) {
          case SpvOpCopyMemory:
          case SpvOpCopyMemorySized:
            if (TransformationSetMemoryOperandsMask::
                    MultipleMemoryOperandMasksAreSupported(GetIRContext())) {
              indices_of_available_masks_to_adjust.push_back(1);
            }
            break;
          default:
            break;
        }

        // Consider the available masks
        for (auto mask_index : indices_of_available_masks_to_adjust) {
          // Randomly decide whether to adjust this mask.
          if (!GetFuzzerContext()->ChoosePercentage(
                  GetFuzzerContext()
                      ->GetChanceOfAdjustingMemoryOperandsMask())) {
            continue;
          }
          // Get the existing mask, using None if there was no mask present at
          // all.
          auto existing_mask_in_operand_index =
              TransformationSetMemoryOperandsMask::GetInOperandIndexForMask(
                  *inst_it, mask_index);
          auto existing_mask =
              existing_mask_in_operand_index < inst_it->NumInOperands()
                  ? inst_it->GetSingleWordInOperand(
                        existing_mask_in_operand_index)
                  : static_cast<uint32_t>(SpvMemoryAccessMaskNone);

          // There are two things we can do to a mask:
          // - add Volatile if not already present
          // - toggle Nontemporal
          // The following ensures that we do at least one of these
          bool add_volatile = !(existing_mask & SpvMemoryAccessVolatileMask) &&
                              GetFuzzerContext()->ChooseEven();
          bool toggle_nontemporal =
              !add_volatile || GetFuzzerContext()->ChooseEven();

          // These bitwise operations use '|' to add Volatile if desired, and
          // '^' to toggle Nontemporal if desired.
          uint32_t new_mask =
              (existing_mask | (add_volatile ? SpvMemoryAccessVolatileMask
                                             : SpvMemoryAccessMaskNone)) ^
              (toggle_nontemporal ? SpvMemoryAccessNontemporalMask
                                  : SpvMemoryAccessMaskNone);

          TransformationSetMemoryOperandsMask transformation(
              MakeInstructionDescriptor(block, inst_it), new_mask, mask_index);
          ApplyTransformation(transformation);
        }
      }
    }
  }
}

}  // namespace fuzz
}  // namespace spvtools
