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_COMPOSITE_INSERT_H_ 16 #define SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_INSERT_H_ 17 18 #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" 19 #include "source/fuzz/transformation.h" 20 #include "source/fuzz/transformation_context.h" 21 #include "source/opt/ir_context.h" 22 23 namespace spvtools { 24 namespace fuzz { 25 26 class TransformationCompositeInsert : public Transformation { 27 public: 28 explicit TransformationCompositeInsert( 29 const protobufs::TransformationCompositeInsert& message); 30 31 TransformationCompositeInsert( 32 const protobufs::InstructionDescriptor& instruction_to_insert_before, 33 uint32_t fresh_id, uint32_t composite_id, uint32_t object_id, 34 const std::vector<uint32_t>& index); 35 36 // - |message_.fresh_id| must be fresh. 37 // - |message_.composite_id| must refer to an existing composite value. 38 // - |message_.index| must refer to a correct index in the composite. 39 // - The type id of the object and the type id of the component of the 40 // composite at index |message_.index| must be the same. 41 // - |message_.instruction_to_insert_before| must refer to a defined 42 // instruction. 43 // - It must be possible to insert OpCompositeInsert before 44 // |instruction_to_insert_before|. 45 bool IsApplicable( 46 opt::IRContext* ir_context, 47 const TransformationContext& transformation_context) const override; 48 49 // Adds an instruction OpCompositeInsert before 50 // |instruction_to_insert_before|, which creates a new composite from 51 // |composite_id| by inserting |object_id| at the specified |index|. 52 // Synonyms are created between those components which are identical in the 53 // original and the modified composite and between the inserted object and its 54 // copy in the modified composite. 55 void Apply(opt::IRContext* ir_context, 56 TransformationContext* transformation_context) const override; 57 58 std::unordered_set<uint32_t> GetFreshIds() const override; 59 60 protobufs::Transformation ToMessage() const override; 61 62 // Checks if |instruction| is a instruction of a composite type supported by 63 // this transformation. 64 static bool IsCompositeInstructionSupported(opt::IRContext* ir_context, 65 opt::Instruction* instruction); 66 67 private: 68 // Helper method for adding data synonym facts when applying the 69 // transformation to |ir_context| and |transformation_context|. 70 void AddDataSynonymFacts(opt::IRContext* ir_context, 71 TransformationContext* transformation_context) const; 72 73 protobufs::TransformationCompositeInsert message_; 74 }; 75 76 } // namespace fuzz 77 } // namespace spvtools 78 79 #endif // SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_INSERT_H_ 80