| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // 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/id_use_descriptor.h"
- namespace spvtools {
- namespace fuzz {
- opt::Instruction* transformation::FindInstruction(
- const protobufs::IdUseDescriptor& descriptor,
- spvtools::opt::IRContext* context) {
- for (auto& function : *context->module()) {
- for (auto& block : function) {
- bool found_base = block.id() == descriptor.base_instruction_result_id();
- uint32_t num_ignored = 0;
- for (auto& instruction : block) {
- if (instruction.HasResultId() &&
- instruction.result_id() ==
- 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() == descriptor.target_instruction_opcode()) {
- if (num_ignored == descriptor.num_opcodes_to_ignore()) {
- if (descriptor.in_operand_index() >= instruction.NumInOperands()) {
- return nullptr;
- }
- auto in_operand =
- instruction.GetInOperand(descriptor.in_operand_index());
- if (in_operand.type != SPV_OPERAND_TYPE_ID) {
- return nullptr;
- }
- if (in_operand.words[0] != descriptor.id_of_interest()) {
- return nullptr;
- }
- 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::IdUseDescriptor transformation::MakeIdUseDescriptor(
- uint32_t id_of_interest, SpvOp target_instruction_opcode,
- uint32_t in_operand_index, uint32_t base_instruction_result_id,
- uint32_t num_opcodes_to_ignore) {
- protobufs::IdUseDescriptor result;
- result.set_id_of_interest(id_of_interest);
- result.set_target_instruction_opcode(target_instruction_opcode);
- result.set_in_operand_index(in_operand_index);
- result.set_base_instruction_result_id(base_instruction_result_id);
- result.set_num_opcodes_to_ignore(num_opcodes_to_ignore);
- return result;
- }
- } // namespace fuzz
- } // namespace spvtools
|