// Copyright (c) 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SOURCE_FUZZ_TRANSFORMATION_DUPLICATE_REGION_WITH_SELECTION_H_ #define SOURCE_FUZZ_TRANSFORMATION_DUPLICATE_REGION_WITH_SELECTION_H_ #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" #include "source/fuzz/transformation.h" #include "source/fuzz/transformation_context.h" #include "source/opt/ir_context.h" namespace spvtools { namespace fuzz { class TransformationDuplicateRegionWithSelection : public Transformation { public: explicit TransformationDuplicateRegionWithSelection( const protobufs::TransformationDuplicateRegionWithSelection& message); explicit TransformationDuplicateRegionWithSelection( uint32_t new_entry_fresh_id, uint32_t condition_id, uint32_t merge_label_fresh_id, uint32_t entry_block_id, uint32_t exit_block_id, const std::map& original_label_to_duplicate_label, const std::map& original_id_to_duplicate_id, const std::map& original_id_to_phi_id); // - |new_entry_fresh_id|, |merge_label_fresh_id| must be fresh and distinct. // - |condition_id| must refer to a valid instruction of boolean type. // - |entry_block_id| and |exit_block_id| must refer to valid blocks and they // must form a single-entry, single-exit region. Its constructs and their // merge blocks must be either wholly within or wholly outside of the // region. // - |original_label_to_duplicate_label| must contain at least a key for every // block in the original region. // - |original_id_to_duplicate_id| must contain at least a key for every // result id in the original region. // - |original_id_to_phi_id| must contain at least a key for every result id // available at the end of the original region. // - In each of these three maps, each value must be a distinct, fresh id. bool IsApplicable( opt::IRContext* ir_context, const TransformationContext& transformation_context) const override; // A transformation that inserts a conditional statement with a boolean // expression of arbitrary value and duplicates a given single-entry, // single-exit region, so that it is present in each conditional branch and // will be executed regardless of which branch will be taken. void Apply(opt::IRContext* ir_context, TransformationContext* transformation_context) const override; // Returns the set of blocks dominated by |entry_block| and post-dominated // by |exit_block|. static std::set GetRegionBlocks( opt::IRContext* ir_context, opt::BasicBlock* entry_block, opt::BasicBlock* exit_block); protobufs::Transformation ToMessage() const override; private: protobufs::TransformationDuplicateRegionWithSelection message_; }; } // namespace fuzz } // namespace spvtools #endif // SOURCE_FUZZ_TRANSFORMATION_DUPLICATE_REGION_WITH_SELECTION_H_