]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/FuzzMutate/IRMutator.h
Import tzdata 2018a
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / FuzzMutate / IRMutator.h
1 //===-- IRMutator.h - Mutation engine for fuzzing IR ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Provides the IRMutator class, which drives mutations on IR based on a
11 // configurable set of strategies. Some common strategies are also included
12 // here.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_FUZZMUTATE_IRMUTATOR_H
17 #define LLVM_FUZZMUTATE_IRMUTATOR_H
18
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/FuzzMutate/OpDescriptor.h"
21 #include "llvm/Support/ErrorHandling.h"
22
23 namespace llvm {
24 class BasicBlock;
25 class Function;
26 class Instruction;
27 class Module;
28
29 struct RandomIRBuilder;
30
31 /// Base class for describing how to mutate a module. mutation functions for
32 /// each IR unit forward to the contained unit.
33 class IRMutationStrategy {
34 public:
35   virtual ~IRMutationStrategy() = default;
36
37   /// Provide a weight to bias towards choosing this strategy for a mutation.
38   ///
39   /// The value of the weight is arbitrary, but a good default is "the number of
40   /// distinct ways in which this strategy can mutate a unit". This can also be
41   /// used to prefer strategies that shrink the overall size of the result when
42   /// we start getting close to \c MaxSize.
43   virtual uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
44                              uint64_t CurrentWeight) = 0;
45
46   /// @{
47   /// Mutators for each IR unit. By default these forward to a contained
48   /// instance of the next smaller unit.
49   virtual void mutate(Module &M, RandomIRBuilder &IB);
50   virtual void mutate(Function &F, RandomIRBuilder &IB);
51   virtual void mutate(BasicBlock &BB, RandomIRBuilder &IB);
52   virtual void mutate(Instruction &I, RandomIRBuilder &IB) {
53     llvm_unreachable("Strategy does not implement any mutators");
54   }
55   /// @}
56 };
57
58 using TypeGetter = std::function<Type *(LLVMContext &)>;
59
60 /// Entry point for configuring and running IR mutations.
61 class IRMutator {
62   std::vector<TypeGetter> AllowedTypes;
63   std::vector<std::unique_ptr<IRMutationStrategy>> Strategies;
64
65 public:
66   IRMutator(std::vector<TypeGetter> &&AllowedTypes,
67             std::vector<std::unique_ptr<IRMutationStrategy>> &&Strategies)
68       : AllowedTypes(std::move(AllowedTypes)),
69         Strategies(std::move(Strategies)) {}
70
71   void mutateModule(Module &M, int Seed, size_t CurSize, size_t MaxSize);
72 };
73
74 /// Strategy that injects operations into the function.
75 class InjectorIRStrategy : public IRMutationStrategy {
76   std::vector<fuzzerop::OpDescriptor> Operations;
77
78   Optional<fuzzerop::OpDescriptor> chooseOperation(Value *Src,
79                                                    RandomIRBuilder &IB);
80
81 public:
82   InjectorIRStrategy(std::vector<fuzzerop::OpDescriptor> &&Operations)
83       : Operations(std::move(Operations)) {}
84   static std::vector<fuzzerop::OpDescriptor> getDefaultOps();
85
86   uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
87                      uint64_t CurrentWeight) override {
88     return Operations.size();
89   }
90
91   using IRMutationStrategy::mutate;
92   void mutate(Function &F, RandomIRBuilder &IB) override;
93   void mutate(BasicBlock &BB, RandomIRBuilder &IB) override;
94 };
95
96 class InstDeleterIRStrategy : public IRMutationStrategy {
97 public:
98   uint64_t getWeight(size_t CurrentSize, size_t MaxSize,
99                      uint64_t CurrentWeight) override;
100
101   using IRMutationStrategy::mutate;
102   void mutate(Function &F, RandomIRBuilder &IB) override;
103   void mutate(Instruction &Inst, RandomIRBuilder &IB) override;
104 };
105
106 } // end llvm namespace
107
108 #endif // LLVM_FUZZMUTATE_IRMUTATOR_H