Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:56

0001 //===- RandomIRBuilder.h - Utils for randomly mutation IR -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Provides the Mutator class, which is used to mutate IR for fuzzing.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_FUZZMUTATE_RANDOMIRBUILDER_H
0014 #define LLVM_FUZZMUTATE_RANDOMIRBUILDER_H
0015 
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/SmallVector.h"
0018 #include <random>
0019 
0020 namespace llvm {
0021 class AllocaInst;
0022 class BasicBlock;
0023 class Function;
0024 class GlobalVariable;
0025 class Instruction;
0026 class LLVMContext;
0027 class Module;
0028 class Type;
0029 class Value;
0030 
0031 namespace fuzzerop {
0032 class SourcePred;
0033 }
0034 
0035 using RandomEngine = std::mt19937;
0036 
0037 struct RandomIRBuilder {
0038   RandomEngine Rand;
0039   SmallVector<Type *, 16> KnownTypes;
0040 
0041   uint64_t MinArgNum = 0;
0042   uint64_t MaxArgNum = 5;
0043   uint64_t MinFunctionNum = 1;
0044 
0045   RandomIRBuilder(int Seed, ArrayRef<Type *> AllowedTypes)
0046       : Rand(Seed), KnownTypes(AllowedTypes) {}
0047 
0048   // TODO: Try to make this a bit less of a random mishmash of functions.
0049 
0050   /// Create a stack memory at the head of the function, store \c Init to the
0051   /// memory if provided.
0052   AllocaInst *createStackMemory(Function *F, Type *Ty, Value *Init = nullptr);
0053   /// Find or create a global variable. It will be initialized by random
0054   /// constants that satisfies \c Pred. It will also report whether this global
0055   /// variable found or created.
0056   std::pair<GlobalVariable *, bool>
0057   findOrCreateGlobalVariable(Module *M, ArrayRef<Value *> Srcs,
0058                              fuzzerop::SourcePred Pred);
0059   enum SourceType {
0060     SrcFromInstInCurBlock,
0061     FunctionArgument,
0062     InstInDominator,
0063     SrcFromGlobalVariable,
0064     NewConstOrStack,
0065     EndOfValueSource,
0066   };
0067   /// Find a "source" for some operation, which will be used in one of the
0068   /// operation's operands. This either selects an instruction in \c Insts or
0069   /// returns some new arbitrary Value.
0070   Value *findOrCreateSource(BasicBlock &BB, ArrayRef<Instruction *> Insts);
0071   /// Find a "source" for some operation, which will be used in one of the
0072   /// operation's operands. This either selects an instruction in \c Insts that
0073   /// matches \c Pred, or returns some new Value that matches \c Pred. The
0074   /// values in \c Srcs should be source operands that have already been
0075   /// selected.
0076   Value *findOrCreateSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
0077                             ArrayRef<Value *> Srcs, fuzzerop::SourcePred Pred,
0078                             bool allowConstant = true);
0079   /// Create some Value suitable as a source for some operation.
0080   Value *newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
0081                    ArrayRef<Value *> Srcs, fuzzerop::SourcePred Pred,
0082                    bool allowConstant = true);
0083 
0084   enum SinkType {
0085     /// TODO: Also consider pointers in function argument.
0086     SinkToInstInCurBlock,
0087     PointersInDominator,
0088     InstInDominatee,
0089     NewStore,
0090     SinkToGlobalVariable,
0091     EndOfValueSink,
0092   };
0093   /// Find a viable user for \c V in \c Insts, which should all be contained in
0094   /// \c BB. This may also create some new instruction in \c BB and use that.
0095   Instruction *connectToSink(BasicBlock &BB, ArrayRef<Instruction *> Insts,
0096                              Value *V);
0097   /// Create a user for \c V in \c BB.
0098   Instruction *newSink(BasicBlock &BB, ArrayRef<Instruction *> Insts, Value *V);
0099   Value *findPointer(BasicBlock &BB, ArrayRef<Instruction *> Insts);
0100   /// Return a uniformly choosen type from \c AllowedTypes
0101   Type *randomType();
0102   Function *createFunctionDeclaration(Module &M, uint64_t ArgNum);
0103   Function *createFunctionDeclaration(Module &M);
0104   Function *createFunctionDefinition(Module &M, uint64_t ArgNum);
0105   Function *createFunctionDefinition(Module &M);
0106 };
0107 
0108 } // namespace llvm
0109 
0110 #endif // LLVM_FUZZMUTATE_RANDOMIRBUILDER_H