1 // Copyright (c) 2020 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SOURCE_FUZZ_TRANSFORMATION_EQUATION_INSTRUCTION_H_ 16 #define SOURCE_FUZZ_TRANSFORMATION_EQUATION_INSTRUCTION_H_ 17 18 #include <vector> 19 20 #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" 21 #include "source/fuzz/transformation.h" 22 #include "source/fuzz/transformation_context.h" 23 #include "source/opt/ir_context.h" 24 25 namespace spvtools { 26 namespace fuzz { 27 28 class TransformationEquationInstruction : public Transformation { 29 public: 30 explicit TransformationEquationInstruction( 31 const protobufs::TransformationEquationInstruction& message); 32 33 TransformationEquationInstruction( 34 uint32_t fresh_id, SpvOp opcode, 35 const std::vector<uint32_t>& in_operand_id, 36 const protobufs::InstructionDescriptor& instruction_to_insert_before); 37 38 // - |message_.fresh_id| must be fresh. 39 // - |message_.instruction_to_insert_before| must identify an instruction 40 // before which an equation instruction can legitimately be inserted. 41 // - Each id in |message_.in_operand_id| must exist, not be an OpUndef, and 42 // be available before |message_.instruction_to_insert_before|. 43 // - |message_.opcode| must be an opcode for which we know how to handle 44 // equations, the types of the ids in |message_.in_operand_id| must be 45 // suitable for use with this opcode, and the module must contain an 46 // appropriate result type id. 47 bool IsApplicable( 48 opt::IRContext* ir_context, 49 const TransformationContext& transformation_context) const override; 50 51 // Adds an instruction to the module, right before 52 // |message_.instruction_to_insert_before|, of the form: 53 // 54 // |message_.fresh_id| = |message_.opcode| %type |message_.in_operand_ids| 55 // 56 // where %type is a type id that already exists in the module and that is 57 // compatible with the opcode and input operands. 58 // 59 // The fact manager is also updated to inform it of this equation fact. 60 void Apply(opt::IRContext* ir_context, 61 TransformationContext* transformation_context) const override; 62 63 std::unordered_set<uint32_t> GetFreshIds() const override; 64 65 protobufs::Transformation ToMessage() const override; 66 67 private: 68 // Returns type id for the equation instruction. Returns 0 if result type does 69 // not exist. 70 uint32_t MaybeGetResultTypeId(opt::IRContext* ir_context) const; 71 72 protobufs::TransformationEquationInstruction message_; 73 }; 74 75 } // namespace fuzz 76 } // namespace spvtools 77 78 #endif // SOURCE_FUZZ_TRANSFORMATION_EQUATION_INSTRUCTION_H_ 79