• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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