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

namespace spvtools {
namespace fuzz {

opt::Instruction* FindInstruction(
    const protobufs::InstructionDescriptor& instruction_descriptor,
    spvtools::opt::IRContext* context) {
  for (auto& function : *context->module()) {
    for (auto& block : function) {
      bool found_base =
          block.id() == instruction_descriptor.base_instruction_result_id();
      uint32_t num_ignored = 0;
      for (auto& instruction : block) {
        if (instruction.HasResultId() &&
            instruction.result_id() ==
                instruction_descriptor.base_instruction_result_id()) {
          assert(!found_base &&
                 "It should not be possible to find the base instruction "
                 "multiple times.");
          found_base = true;
          assert(num_ignored == 0 &&
                 "The skipped instruction count should only be incremented "
                 "after the instruction base has been found.");
        }
        if (found_base &&
            instruction.opcode() ==
                instruction_descriptor.target_instruction_opcode()) {
          if (num_ignored == instruction_descriptor.num_opcodes_to_ignore()) {
            return &instruction;
          }
          num_ignored++;
        }
      }
      if (found_base) {
        // We found the base instruction, but did not find the target
        // instruction in the same block.
        return nullptr;
      }
    }
  }
  return nullptr;
}

protobufs::InstructionDescriptor MakeInstructionDescriptor(
    uint32_t base_instruction_result_id, SpvOp target_instruction_opcode,
    uint32_t num_opcodes_to_ignore) {
  protobufs::InstructionDescriptor result;
  result.set_base_instruction_result_id(base_instruction_result_id);
  result.set_target_instruction_opcode(target_instruction_opcode);
  result.set_num_opcodes_to_ignore(num_opcodes_to_ignore);
  return result;
}

protobufs::InstructionDescriptor MakeInstructionDescriptor(
    const opt::BasicBlock& block,
    const opt::BasicBlock::const_iterator& inst_it) {
  const SpvOp opcode =
      inst_it->opcode();    // The opcode of the instruction being described.
  uint32_t skip_count = 0;  // The number of these opcodes we have skipped when
                            // searching backwards.

  // Consider instructions in the block in reverse order, starting from
  // |inst_it|.
  for (opt::BasicBlock::const_iterator backwards_iterator = inst_it;;
       --backwards_iterator) {
    if (backwards_iterator->HasResultId()) {
      // As soon as we find an instruction with a result id, we can return a
      // descriptor for |inst_it|.
      return MakeInstructionDescriptor(backwards_iterator->result_id(), opcode,
                                       skip_count);
    }
    if (backwards_iterator != inst_it &&
        backwards_iterator->opcode() == opcode) {
      // We are skipping over an instruction with the same opcode as |inst_it|;
      // we increase our skip count to reflect this.
      skip_count++;
    }
    if (backwards_iterator == block.begin()) {
      // We exit the loop when we reach the start of the block, but only after
      // we have processed the first instruction in the block.
      break;
    }
  }
  // We did not find an instruction inside the block with a result id, so we use
  // the block's label's id.
  return MakeInstructionDescriptor(block.id(), opcode, skip_count);
}

}  // namespace fuzz
}  // namespace spvtools
