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_FUZZER_PASS_OUTLINE_FUNCTIONS_H_ 16 #define SOURCE_FUZZ_FUZZER_PASS_OUTLINE_FUNCTIONS_H_ 17 18 #include "source/fuzz/fuzzer_pass.h" 19 20 namespace spvtools { 21 namespace fuzz { 22 23 // A fuzzer pass for outlining single-entry single-exit regions of a control 24 // flow graph into their own functions. 25 class FuzzerPassOutlineFunctions : public FuzzerPass { 26 public: 27 FuzzerPassOutlineFunctions( 28 opt::IRContext* ir_context, TransformationContext* transformation_context, 29 FuzzerContext* fuzzer_context, 30 protobufs::TransformationSequence* transformations); 31 32 ~FuzzerPassOutlineFunctions(); 33 34 void Apply() override; 35 36 // Returns a block suitable to be an entry block for a region that can be 37 // outlined, i.e. a block that is not a loop header and that does not start 38 // with OpPhi or OpVariable. In particular, it returns: 39 // - |entry_block| if it is suitable 40 // - otherwise, a block found by: 41 // - looking for or creating a new preheader, if |entry_block| is a loop 42 // header 43 // - splitting the candidate entry block, if it starts with OpPhi or 44 // OpVariable. 45 // Returns nullptr if a suitable block cannot be found following the 46 // instructions above. 47 opt::BasicBlock* MaybeGetEntryBlockSuitableForOutlining( 48 opt::BasicBlock* entry_block); 49 50 // Returns: 51 // - |exit_block| if it is not a merge block 52 // - the second block obtained by splitting |exit_block|, if |exit_block| is a 53 // merge block. 54 // Assumes that |exit_block| is not a continue target. 55 // The block returned by this function should be suitable to be the exit block 56 // of a region that can be outlined. 57 // Returns nullptr if |exit_block| is a merge block and it cannot be split. 58 opt::BasicBlock* MaybeGetExitBlockSuitableForOutlining( 59 opt::BasicBlock* exit_block); 60 }; 61 62 } // namespace fuzz 63 } // namespace spvtools 64 65 #endif // SOURCE_FUZZ_FUZZER_PASS_OUTLINE_FUNCTIONS_H_ 66