1 // Copyright (c) 2019 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_CONSTRUCT_H_ 16 #define SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_CONSTRUCT_H_ 17 18 #include "source/fuzz/fact_manager.h" 19 #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" 20 #include "source/fuzz/transformation.h" 21 #include "source/opt/ir_context.h" 22 23 namespace spvtools { 24 namespace fuzz { 25 26 class TransformationCompositeConstruct : public Transformation { 27 public: 28 explicit TransformationCompositeConstruct( 29 const protobufs::TransformationCompositeConstruct& message); 30 31 TransformationCompositeConstruct( 32 uint32_t composite_type_id, std::vector<uint32_t> component, 33 const protobufs::InstructionDescriptor& instruction_to_insert_before, 34 uint32_t fresh_id); 35 36 // - |message_.fresh_id| must not be used by the module. 37 // - |message_.composite_type_id| must be the id of a composite type 38 // - The elements of |message_.component| must be result ids that are 39 // suitable for constructing an element of the given composite type, in 40 // order 41 // - The elements of |message_.component| must not be the target of any 42 // decorations. 43 // - |message_.base_instruction_id| must be the result id of an instruction 44 // 'base' in some block 'blk'. 45 // - 'blk' must contain an instruction 'inst' located |message_.offset| 46 // instructions after 'base' (if |message_.offset| = 0 then 'inst' = 47 // 'base'). 48 // - It must be legal to insert an OpCompositeConstruct instruction directly 49 // before 'inst'. 50 // - Each element of |message_.component| must be available directly before 51 // 'inst'. 52 bool IsApplicable(opt::IRContext* context, 53 const FactManager& fact_manager) const override; 54 55 // Inserts a new OpCompositeConstruct instruction, with id 56 // |message_.fresh_id|, directly before the instruction identified by 57 // |message_.base_instruction_id| and |message_.offset|. The instruction 58 // creates a composite of type |message_.composite_type_id| using the ids of 59 // |message_.component|. 60 void Apply(opt::IRContext* context, FactManager* fact_manager) const override; 61 62 protobufs::Transformation ToMessage() const override; 63 64 private: 65 // Helper to decide whether the components of the transformation are suitable 66 // for constructing an array of the given type. 67 bool ComponentsForArrayConstructionAreOK( 68 opt::IRContext* context, const opt::analysis::Array& array_type) const; 69 70 // Similar, but for matrices. 71 bool ComponentsForMatrixConstructionAreOK( 72 opt::IRContext* context, const opt::analysis::Matrix& matrix_type) const; 73 74 // Similar, but for structs. 75 bool ComponentsForStructConstructionAreOK( 76 opt::IRContext* context, const opt::analysis::Struct& struct_type) const; 77 78 // Similar, but for vectors. 79 bool ComponentsForVectorConstructionAreOK( 80 opt::IRContext* context, const opt::analysis::Vector& vector_type) const; 81 82 protobufs::TransformationCompositeConstruct message_; 83 }; 84 85 } // namespace fuzz 86 } // namespace spvtools 87 88 #endif // SOURCE_FUZZ_TRANSFORMATION_COMPOSITE_CONSTRUCT_H_ 89