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_ADD_OPPHI_SYNONYM_H_ 16 #define SOURCE_FUZZ_TRANSFORMATION_ADD_OPPHI_SYNONYM_H_ 17 18 #include "source/fuzz/transformation.h" 19 20 namespace spvtools { 21 namespace fuzz { 22 class TransformationAddOpPhiSynonym : public Transformation { 23 public: 24 explicit TransformationAddOpPhiSynonym( 25 const protobufs::TransformationAddOpPhiSynonym& message); 26 27 TransformationAddOpPhiSynonym( 28 uint32_t block_id, const std::map<uint32_t, uint32_t>& preds_to_ids, 29 uint32_t fresh_id); 30 31 // - |message_.block_id| is the label of a block with at least one 32 // predecessor. 33 // - |message_.block_id| must not be a dead block. 34 // - |message_.pred_to_id| contains a mapping from each of the predecessors of 35 // the block to an id that is available at the end of the predecessor. 36 // - All the ids corresponding to a predecessor in |message_.pred_to_id|: 37 // - have been recorded as synonymous and all have the same type. 38 // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3726): if a 39 // predecessor is a dead block, any id of the right type could be used, 40 // even if it is not synonym with the others. 41 // - have one of the following types: Bool, Integer, Float, Vector, Matrix, 42 // Array, Struct. Pointer types are also allowed if the VariablePointers 43 // capability is enabled and the storage class is Workgroup or 44 // StorageBuffer. 45 // - |message_.fresh_id| is a fresh id. 46 bool IsApplicable( 47 opt::IRContext* ir_context, 48 const TransformationContext& transformation_context) const override; 49 50 // Given a block with n predecessors, with n >= 1, and n corresponding 51 // synonymous ids of the same type, each available to use at the end of the 52 // corresponding predecessor, adds an OpPhi instruction at the beginning of 53 // the block of the form: 54 // %fresh_id = OpPhi %type %id_1 %pred_1 %id_2 %pred_2 ... %id_n %pred_n 55 // This instruction is then marked as synonymous with the ids. 56 void Apply(opt::IRContext* ir_context, 57 TransformationContext* transformation_context) const override; 58 59 // Returns true if |type_id| is the id of a type in the module, which is one 60 // of the following: Bool, Integer, Float, Vector, Matrix, Array, Struct. 61 // Pointer types are also allowed if the VariablePointers capability is 62 // enabled and the storage class is Workgroup or StorageBuffer. 63 static bool CheckTypeIsAllowed(opt::IRContext* ir_context, uint32_t type_id); 64 65 std::unordered_set<uint32_t> GetFreshIds() const override; 66 67 protobufs::Transformation ToMessage() const override; 68 69 private: 70 protobufs::TransformationAddOpPhiSynonym message_; 71 }; 72 } // namespace fuzz 73 } // namespace spvtools 74 75 #endif // SOURCE_FUZZ_TRANSFORMATION_ADD_OPPHI_SYNONYM_H_ 76