1 //===- RandomIRBuilder.h - Utils for randomly mutation IR -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Provides the Mutator class, which is used to mutate IR for fuzzing. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_FUZZMUTATE_RANDOMIRBUILDER_H 14 #define LLVM_FUZZMUTATE_RANDOMIRBUILDER_H 15 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include <random> 19 20 namespace llvm { 21 class BasicBlock; 22 class Instruction; 23 class LLVMContext; 24 class Type; 25 class Value; 26 namespace fuzzerop { 27 class SourcePred; 28 } 29 30 using RandomEngine = std::mt19937; 31 32 struct RandomIRBuilder { 33 RandomEngine Rand; 34 SmallVector<Type *, 16> KnownTypes; 35 36 RandomIRBuilder(int Seed, ArrayRef<Type *> AllowedTypes) 37 : Rand(Seed), KnownTypes(AllowedTypes.begin(), AllowedTypes.end()) {} 38 39 // TODO: Try to make this a bit less of a random mishmash of functions. 40 41 /// Find a "source" for some operation, which will be used in one of the 42 /// operation's operands. This either selects an instruction in \c Insts or 43 /// returns some new arbitrary Value. 44 Value *findOrCreateSource(BasicBlock &BB, ArrayRef<Instruction *> Insts); 45 /// Find a "source" for some operation, which will be used in one of the 46 /// operation's operands. This either selects an instruction in \c Insts that 47 /// matches \c Pred, or returns some new Value that matches \c Pred. The 48 /// values in \c Srcs should be source operands that have already been 49 /// selected. 50 Value *findOrCreateSource(BasicBlock &BB, ArrayRef<Instruction *> Insts, 51 ArrayRef<Value *> Srcs, fuzzerop::SourcePred Pred, 52 bool allowConstant = true); 53 /// Create some Value suitable as a source for some operation. 54 Value *newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts, 55 ArrayRef<Value *> Srcs, fuzzerop::SourcePred Pred, 56 bool allowConstant = true); 57 /// Find a viable user for \c V in \c Insts, which should all be contained in 58 /// \c BB. This may also create some new instruction in \c BB and use that. 59 void connectToSink(BasicBlock &BB, ArrayRef<Instruction *> Insts, Value *V); 60 /// Create a user for \c V in \c BB. 61 void newSink(BasicBlock &BB, ArrayRef<Instruction *> Insts, Value *V); 62 Value *findPointer(BasicBlock &BB, ArrayRef<Instruction *> Insts, 63 ArrayRef<Value *> Srcs, fuzzerop::SourcePred Pred); 64 Type *chooseType(LLVMContext &Context, ArrayRef<Value *> Srcs, 65 fuzzerop::SourcePred Pred); 66 /// Return a uniformly choosen type from \c AllowedTypes 67 Type *randomType(); 68 }; 69 70 } // namespace llvm 71 72 #endif // LLVM_FUZZMUTATE_RANDOMIRBUILDER_H 73