1 // Copyright (c) 2020 Vasyl Teliman 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_REPLACE_PARAMS_WITH_STRUCT_H_ 16 #define SOURCE_FUZZ_TRANSFORMATION_REPLACE_PARAMS_WITH_STRUCT_H_ 17 18 #include <map> 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 TransformationReplaceParamsWithStruct : public Transformation { 29 public: 30 explicit TransformationReplaceParamsWithStruct( 31 protobufs::TransformationReplaceParamsWithStruct message); 32 33 TransformationReplaceParamsWithStruct( 34 const std::vector<uint32_t>& parameter_id, 35 uint32_t fresh_function_type_id, uint32_t fresh_parameter_id, 36 const std::map<uint32_t, uint32_t>& caller_id_to_fresh_composite_id); 37 38 // - Each element of |parameter_id| is a valid result id of some 39 // OpFunctionParameter instruction. All parameter ids must correspond to 40 // parameters of the same function. That function may not be an entry-point 41 // function. 42 // - Types of all parameters must be supported by this transformation (see 43 // IsParameterTypeSupported method). 44 // - |parameter_id| may not be empty or contain duplicates. 45 // - There must exist an OpTypeStruct instruction containing types of all 46 // replaced parameters. Type of the i'th component of the struct is equal 47 // to the type of the instruction with result id |parameter_id[i]|. 48 // - |caller_id_to_fresh_composite_id| should contain a key for at least every 49 // result id of an OpFunctionCall instruction that calls the function. 50 // - |fresh_function_type_id|, |fresh_parameter_id|, 51 // |caller_id_to_fresh_composite_id| are all fresh and unique ids. 52 bool IsApplicable( 53 opt::IRContext* ir_context, 54 const TransformationContext& transformation_context) const override; 55 56 // - Creates a new function parameter with result id |fresh_parameter_id|. 57 // Parameter's type is OpTypeStruct with each components type equal to the 58 // type of the replaced parameter. 59 // - OpCompositeConstruct with result id from |fresh_composite_id| is inserted 60 // before each OpFunctionCall instruction. 61 // - OpCompositeExtract with result id equal to the result id of the replaced 62 // parameter is created in the function. 63 void Apply(opt::IRContext* ir_context, 64 TransformationContext* transformation_context) const override; 65 66 std::unordered_set<uint32_t> GetFreshIds() const override; 67 68 protobufs::Transformation ToMessage() const override; 69 70 // Returns true if parameter's type is supported by this transformation. 71 static bool IsParameterTypeSupported(opt::IRContext* ir_context, 72 uint32_t param_type_id); 73 74 private: 75 // Returns a result id of the OpTypeStruct instruction required by this 76 // transformation (see docs on the IsApplicable method to learn more). 77 uint32_t MaybeGetRequiredStructType(opt::IRContext* ir_context) const; 78 79 // Returns a vector of indices of parameters to replace. Concretely, i'th 80 // element is the index of the parameter with result id |parameter_id[i]| in 81 // its function. 82 std::vector<uint32_t> ComputeIndicesOfReplacedParameters( 83 opt::IRContext* ir_context) const; 84 85 protobufs::TransformationReplaceParamsWithStruct message_; 86 }; 87 88 } // namespace fuzz 89 } // namespace spvtools 90 91 #endif // SOURCE_FUZZ_TRANSFORMATION_REPLACE_PARAMS_WITH_STRUCT_H_ 92