LLVM  6.0.0svn
RandomIRBuilder.cpp
Go to the documentation of this file.
1 //===-- RandomIRBuilder.cpp -----------------------------------------------===//
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 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/FuzzMutate/Random.h"
13 #include "llvm/IR/BasicBlock.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/IntrinsicInst.h"
18 #include "llvm/IR/Module.h"
19 
20 using namespace llvm;
21 using namespace fuzzerop;
22 
25  return findOrCreateSource(BB, Insts, {}, anyType());
26 }
27 
30  ArrayRef<Value *> Srcs,
31  SourcePred Pred) {
32  auto MatchesPred = [&Srcs, &Pred](Instruction *Inst) {
33  return Pred.matches(Srcs, Inst);
34  };
35  auto RS = makeSampler(Rand, make_filter_range(Insts, MatchesPred));
36  // Also consider choosing no source, meaning we want a new one.
37  RS.sample(nullptr, /*Weight=*/1);
38  if (Instruction *Src = RS.getSelection())
39  return Src;
40  return newSource(BB, Insts, Srcs, Pred);
41 }
42 
44  ArrayRef<Value *> Srcs, SourcePred Pred) {
45  // Generate some constants to choose from.
46  auto RS = makeSampler<Value *>(Rand);
47  RS.sample(Pred.generate(Srcs, KnownTypes));
48  assert(!RS.isEmpty() && "Failed to generate sources");
49 
50  // If we can find a pointer to load from, use it half the time.
51  Value *Ptr = findPointer(BB, Insts, Srcs, Pred);
52  if (Ptr)
53  RS.sample(Ptr, RS.totalWeight());
54 
55  Value *Result = RS.getSelection();
56  if (Result != Ptr)
57  return Result;
58 
59  // If we choose the pointer, we need to create a load.
60  auto IP = BB.getFirstInsertionPt();
61  if (auto *I = dyn_cast<Instruction>(Ptr))
62  IP = ++I->getIterator();
63  return new LoadInst(Ptr, "L", &*IP);
64 }
65 
66 static bool isCompatibleReplacement(const Instruction *I, const Use &Operand,
67  const Value *Replacement) {
68  if (Operand->getType() != Replacement->getType())
69  return false;
70  switch (I->getOpcode()) {
71  case Instruction::GetElementPtr:
72  case Instruction::ExtractElement:
73  case Instruction::ExtractValue:
74  // TODO: We could potentially validate these, but for now just leave indices
75  // alone.
76  if (Operand.getOperandNo() > 1)
77  return false;
78  break;
79  case Instruction::InsertValue:
80  case Instruction::InsertElement:
81  if (Operand.getOperandNo() > 2)
82  return false;
83  break;
84  default:
85  break;
86  }
87  return true;
88 }
89 
91  ArrayRef<Instruction *> Insts, Value *V) {
92  auto RS = makeSampler<Use *>(Rand);
93  for (auto &I : Insts) {
94  if (isa<IntrinsicInst>(I))
95  // TODO: Replacing operands of intrinsics would be interesting, but
96  // there's no easy way to verify that a given replacement is valid given
97  // that intrinsics can impose arbitrary constraints.
98  continue;
99  for (Use &U : I->operands())
100  if (isCompatibleReplacement(I, U, V))
101  RS.sample(&U, 1);
102  }
103  // Also consider choosing no sink, meaning we want a new one.
104  RS.sample(nullptr, /*Weight=*/1);
105 
106  if (Use *Sink = RS.getSelection()) {
107  User *U = Sink->getUser();
108  unsigned OpNo = Sink->getOperandNo();
109  U->setOperand(OpNo, V);
110  return;
111  }
112  newSink(BB, Insts, V);
113 }
114 
116  Value *V) {
117  Value *Ptr = findPointer(BB, Insts, {V}, matchFirstType());
118  if (!Ptr) {
119  if (uniform(Rand, 0, 1))
120  Ptr = new AllocaInst(V->getType(), 0, "A", &*BB.getFirstInsertionPt());
121  else
122  Ptr = UndefValue::get(PointerType::get(V->getType(), 0));
123  }
124 
125  new StoreInst(V, Ptr, Insts.back());
126 }
127 
130  ArrayRef<Value *> Srcs, SourcePred Pred) {
131  auto IsMatchingPtr = [&Srcs, &Pred](Instruction *Inst) {
132  if (auto PtrTy = dyn_cast<PointerType>(Inst->getType()))
133  // TODO: Check if this is horribly expensive.
134  return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType()));
135  return false;
136  };
137  if (auto RS = makeSampler(Rand, make_filter_range(Insts, IsMatchingPtr)))
138  return RS.getSelection();
139  return nullptr;
140 }
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:158
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Value * findPointer(BasicBlock &BB, ArrayRef< Instruction *> Insts, ArrayRef< Value *> Srcs, fuzzerop::SourcePred Pred)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
Definition: Type.cpp:617
An instruction for reading from memory.
Definition: Instructions.h:164
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
T uniform(GenT &Gen, T Min, T Max)
Return a uniformly distributed random value between Min and Max.
Definition: Random.h:22
static SourcePred matchFirstType()
Match values that have the same type as the first source.
Definition: OpDescriptor.h:165
Value * newSource(BasicBlock &BB, ArrayRef< Instruction *> Insts, ArrayRef< Value *> Srcs, fuzzerop::SourcePred Pred)
Create some Value suitable as a source for some operation.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:125
static SourcePred anyType()
Definition: OpDescriptor.h:105
An instruction for storing to memory.
Definition: Instructions.h:306
unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition: Use.cpp:48
static bool isCompatibleReplacement(const Instruction *I, const Use &Operand, const Value *Replacement)
Value * findOrCreateSource(BasicBlock &BB, ArrayRef< Instruction *> Insts)
Find a "source" for some operation, which will be used in one of the operation&#39;s operands.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:200
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ReservoirSampler< ElT, GenT > makeSampler(GenT &RandGen, RangeT &&Items)
Definition: Random.h:76
bool matches(ArrayRef< Value *> Cur, const Value *New)
Returns true if New is compatible for the argument after Cur.
Definition: OpDescriptor.h:77
static UndefValue * get(Type *T)
Static factory methods - Return an &#39;undef&#39; object of the specified type.
Definition: Constants.cpp:1320
void connectToSink(BasicBlock &BB, ArrayRef< Instruction *> Insts, Value *V)
Find a viable user for V in Insts, which should all be contained in BB.
std::vector< Constant * > generate(ArrayRef< Value *> Cur, ArrayRef< Type *> BaseTypes)
Generates a list of potential values for the argument after Cur.
Definition: OpDescriptor.h:82
Module.h This file contains the declarations for the Module class.
A matcher/generator for finding suitable values for the next source in an operation&#39;s partially compl...
Definition: OpDescriptor.h:43
void setOperand(unsigned i, Value *Val)
Definition: User.h:159
void newSink(BasicBlock &BB, ArrayRef< Instruction *> Insts, Value *V)
Create a user for V in BB.
#define I(x, y, z)
Definition: MD5.cpp:58
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition: STLExtras.h:286
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
an instruction to allocate memory on the stack
Definition: Instructions.h:60