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(opt::IRContext* ir_context, 28 TransformationContext* transformation_context, 29 FuzzerContext* fuzzer_context, 30 protobufs::TransformationSequence* transformations, 31 bool ignore_inapplicable_transformations); 32 33 void Apply() override; 34 35 // Returns a block suitable to be an entry block for a region that can be 36 // outlined, i.e. a block that is not a loop header and that does not start 37 // with OpPhi or OpVariable. In particular, it returns: 38 // - |entry_block| if it is suitable 39 // - otherwise, a block found by: 40 // - looking for or creating a new preheader, if |entry_block| is a loop 41 // header 42 // - splitting the candidate entry block, if it starts with OpPhi or 43 // OpVariable. 44 // Returns nullptr if a suitable block cannot be found following the 45 // instructions above. 46 opt::BasicBlock* MaybeGetEntryBlockSuitableForOutlining( 47 opt::BasicBlock* entry_block); 48 49 // Returns: 50 // - |exit_block| if it is not a merge block 51 // - the second block obtained by splitting |exit_block|, if |exit_block| is a 52 // merge block. 53 // Assumes that |exit_block| is not a continue target. 54 // The block returned by this function should be suitable to be the exit block 55 // of a region that can be outlined. 56 // Returns nullptr if |exit_block| is a merge block and it cannot be split. 57 opt::BasicBlock* MaybeGetExitBlockSuitableForOutlining( 58 opt::BasicBlock* exit_block); 59 }; 60 61 } // namespace fuzz 62 } // namespace spvtools 63 64 #endif // SOURCE_FUZZ_FUZZER_PASS_OUTLINE_FUNCTIONS_H_ 65