1198892Srdivacky//===------ MemoryBuiltins.cpp - Identify calls to memory builtins --------===//
2198892Srdivacky//
3198892Srdivacky//                     The LLVM Compiler Infrastructure
4198892Srdivacky//
5198892Srdivacky// This file is distributed under the University of Illinois Open Source
6198892Srdivacky// License. See LICENSE.TXT for details.
7198892Srdivacky//
8198892Srdivacky//===----------------------------------------------------------------------===//
9198892Srdivacky//
10198892Srdivacky// This family of functions identifies calls to builtin functions that allocate
11249423Sdim// or free memory.
12198892Srdivacky//
13198892Srdivacky//===----------------------------------------------------------------------===//
14198892Srdivacky
15239462Sdim#define DEBUG_TYPE "memory-builtins"
16249423Sdim#include "llvm/Analysis/MemoryBuiltins.h"
17249423Sdim#include "llvm/ADT/STLExtras.h"
18239462Sdim#include "llvm/ADT/Statistic.h"
19199481Srdivacky#include "llvm/Analysis/ValueTracking.h"
20249423Sdim#include "llvm/IR/DataLayout.h"
21249423Sdim#include "llvm/IR/GlobalVariable.h"
22249423Sdim#include "llvm/IR/Instructions.h"
23249423Sdim#include "llvm/IR/Intrinsics.h"
24249423Sdim#include "llvm/IR/Metadata.h"
25249423Sdim#include "llvm/IR/Module.h"
26239462Sdim#include "llvm/Support/Debug.h"
27239462Sdim#include "llvm/Support/MathExtras.h"
28239462Sdim#include "llvm/Support/raw_ostream.h"
29243830Sdim#include "llvm/Target/TargetLibraryInfo.h"
30239462Sdim#include "llvm/Transforms/Utils/Local.h"
31198892Srdivackyusing namespace llvm;
32198892Srdivacky
33239462Sdimenum AllocType {
34263508Sdim  OpNewLike          = 1<<0, // allocates; never returns null
35263508Sdim  MallocLike         = 1<<1 | OpNewLike, // allocates; may return null
36263508Sdim  CallocLike         = 1<<2, // allocates + bzero
37263508Sdim  ReallocLike        = 1<<3, // reallocates
38263508Sdim  StrDupLike         = 1<<4,
39239462Sdim  AllocLike          = MallocLike | CallocLike | StrDupLike,
40263508Sdim  AnyAlloc           = AllocLike | ReallocLike
41239462Sdim};
42198892Srdivacky
43239462Sdimstruct AllocFnsTy {
44243830Sdim  LibFunc::Func Func;
45239462Sdim  AllocType AllocTy;
46239462Sdim  unsigned char NumParams;
47239462Sdim  // First and Second size parameters (or -1 if unused)
48239462Sdim  signed char FstParam, SndParam;
49239462Sdim};
50239462Sdim
51239462Sdim// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
52239462Sdim// know which functions are nounwind, noalias, nocapture parameters, etc.
53239462Sdimstatic const AllocFnsTy AllocationFnData[] = {
54243830Sdim  {LibFunc::malloc,              MallocLike,  1, 0,  -1},
55243830Sdim  {LibFunc::valloc,              MallocLike,  1, 0,  -1},
56263508Sdim  {LibFunc::Znwj,                OpNewLike,   1, 0,  -1}, // new(unsigned int)
57243830Sdim  {LibFunc::ZnwjRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new(unsigned int, nothrow)
58263508Sdim  {LibFunc::Znwm,                OpNewLike,   1, 0,  -1}, // new(unsigned long)
59243830Sdim  {LibFunc::ZnwmRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new(unsigned long, nothrow)
60263508Sdim  {LibFunc::Znaj,                OpNewLike,   1, 0,  -1}, // new[](unsigned int)
61243830Sdim  {LibFunc::ZnajRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new[](unsigned int, nothrow)
62263508Sdim  {LibFunc::Znam,                OpNewLike,   1, 0,  -1}, // new[](unsigned long)
63243830Sdim  {LibFunc::ZnamRKSt9nothrow_t,  MallocLike,  2, 0,  -1}, // new[](unsigned long, nothrow)
64243830Sdim  {LibFunc::calloc,              CallocLike,  2, 0,   1},
65243830Sdim  {LibFunc::realloc,             ReallocLike, 2, 1,  -1},
66243830Sdim  {LibFunc::reallocf,            ReallocLike, 2, 1,  -1},
67243830Sdim  {LibFunc::strdup,              StrDupLike,  1, -1, -1},
68243830Sdim  {LibFunc::strndup,             StrDupLike,  2, 1,  -1}
69263508Sdim  // TODO: Handle "int posix_memalign(void **, size_t, size_t)"
70239462Sdim};
71239462Sdim
72239462Sdim
73239462Sdimstatic Function *getCalledFunction(const Value *V, bool LookThroughBitCast) {
74239462Sdim  if (LookThroughBitCast)
75239462Sdim    V = V->stripPointerCasts();
76239462Sdim
77239462Sdim  CallSite CS(const_cast<Value*>(V));
78239462Sdim  if (!CS.getInstruction())
79239462Sdim    return 0;
80239462Sdim
81263508Sdim  if (CS.isNoBuiltin())
82263508Sdim    return 0;
83263508Sdim
84239462Sdim  Function *Callee = CS.getCalledFunction();
85239462Sdim  if (!Callee || !Callee->isDeclaration())
86239462Sdim    return 0;
87239462Sdim  return Callee;
88198892Srdivacky}
89198892Srdivacky
90239462Sdim/// \brief Returns the allocation data for the given value if it is a call to a
91239462Sdim/// known allocation function, and NULL otherwise.
92239462Sdimstatic const AllocFnsTy *getAllocationData(const Value *V, AllocType AllocTy,
93243830Sdim                                           const TargetLibraryInfo *TLI,
94239462Sdim                                           bool LookThroughBitCast = false) {
95249423Sdim  // Skip intrinsics
96249423Sdim  if (isa<IntrinsicInst>(V))
97249423Sdim    return 0;
98249423Sdim
99239462Sdim  Function *Callee = getCalledFunction(V, LookThroughBitCast);
100239462Sdim  if (!Callee)
101239462Sdim    return 0;
102198892Srdivacky
103243830Sdim  // Make sure that the function is available.
104243830Sdim  StringRef FnName = Callee->getName();
105243830Sdim  LibFunc::Func TLIFn;
106243830Sdim  if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
107243830Sdim    return 0;
108243830Sdim
109239462Sdim  unsigned i = 0;
110239462Sdim  bool found = false;
111239462Sdim  for ( ; i < array_lengthof(AllocationFnData); ++i) {
112243830Sdim    if (AllocationFnData[i].Func == TLIFn) {
113239462Sdim      found = true;
114239462Sdim      break;
115239462Sdim    }
116239462Sdim  }
117239462Sdim  if (!found)
118239462Sdim    return 0;
119198892Srdivacky
120239462Sdim  const AllocFnsTy *FnData = &AllocationFnData[i];
121263508Sdim  if ((FnData->AllocTy & AllocTy) != FnData->AllocTy)
122239462Sdim    return 0;
123239462Sdim
124239462Sdim  // Check function prototype.
125239462Sdim  int FstParam = FnData->FstParam;
126239462Sdim  int SndParam = FnData->SndParam;
127226633Sdim  FunctionType *FTy = Callee->getFunctionType();
128239462Sdim
129239462Sdim  if (FTy->getReturnType() == Type::getInt8PtrTy(FTy->getContext()) &&
130239462Sdim      FTy->getNumParams() == FnData->NumParams &&
131239462Sdim      (FstParam < 0 ||
132239462Sdim       (FTy->getParamType(FstParam)->isIntegerTy(32) ||
133239462Sdim        FTy->getParamType(FstParam)->isIntegerTy(64))) &&
134239462Sdim      (SndParam < 0 ||
135239462Sdim       FTy->getParamType(SndParam)->isIntegerTy(32) ||
136239462Sdim       FTy->getParamType(SndParam)->isIntegerTy(64)))
137239462Sdim    return FnData;
138239462Sdim  return 0;
139198892Srdivacky}
140198892Srdivacky
141239462Sdimstatic bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
142239462Sdim  ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
143249423Sdim  return CS && CS.hasFnAttr(Attribute::NoAlias);
144198892Srdivacky}
145198892Srdivacky
146239462Sdim
147239462Sdim/// \brief Tests if a value is a call or invoke to a library function that
148239462Sdim/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
149239462Sdim/// like).
150243830Sdimbool llvm::isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
151243830Sdim                          bool LookThroughBitCast) {
152243830Sdim  return getAllocationData(V, AnyAlloc, TLI, LookThroughBitCast);
153198892Srdivacky}
154198892Srdivacky
155239462Sdim/// \brief Tests if a value is a call or invoke to a function that returns a
156239462Sdim/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
157243830Sdimbool llvm::isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
158243830Sdim                       bool LookThroughBitCast) {
159239462Sdim  // it's safe to consider realloc as noalias since accessing the original
160239462Sdim  // pointer is undefined behavior
161243830Sdim  return isAllocationFn(V, TLI, LookThroughBitCast) ||
162239462Sdim         hasNoAliasAttr(V, LookThroughBitCast);
163198892Srdivacky}
164198892Srdivacky
165239462Sdim/// \brief Tests if a value is a call or invoke to a library function that
166239462Sdim/// allocates uninitialized memory (such as malloc).
167243830Sdimbool llvm::isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
168243830Sdim                          bool LookThroughBitCast) {
169243830Sdim  return getAllocationData(V, MallocLike, TLI, LookThroughBitCast);
170198892Srdivacky}
171198892Srdivacky
172239462Sdim/// \brief Tests if a value is a call or invoke to a library function that
173239462Sdim/// allocates zero-filled memory (such as calloc).
174243830Sdimbool llvm::isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
175243830Sdim                          bool LookThroughBitCast) {
176243830Sdim  return getAllocationData(V, CallocLike, TLI, LookThroughBitCast);
177198892Srdivacky}
178198892Srdivacky
179239462Sdim/// \brief Tests if a value is a call or invoke to a library function that
180239462Sdim/// allocates memory (either malloc, calloc, or strdup like).
181243830Sdimbool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
182243830Sdim                         bool LookThroughBitCast) {
183243830Sdim  return getAllocationData(V, AllocLike, TLI, LookThroughBitCast);
184239462Sdim}
185239462Sdim
186239462Sdim/// \brief Tests if a value is a call or invoke to a library function that
187239462Sdim/// reallocates memory (such as realloc).
188243830Sdimbool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
189243830Sdim                           bool LookThroughBitCast) {
190243830Sdim  return getAllocationData(V, ReallocLike, TLI, LookThroughBitCast);
191239462Sdim}
192239462Sdim
193263508Sdim/// \brief Tests if a value is a call or invoke to a library function that
194263508Sdim/// allocates memory and never returns null (such as operator new).
195263508Sdimbool llvm::isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
196263508Sdim                               bool LookThroughBitCast) {
197263508Sdim  return getAllocationData(V, OpNewLike, TLI, LookThroughBitCast);
198263508Sdim}
199263508Sdim
200239462Sdim/// extractMallocCall - Returns the corresponding CallInst if the instruction
201239462Sdim/// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
202239462Sdim/// ignore InvokeInst here.
203243830Sdimconst CallInst *llvm::extractMallocCall(const Value *I,
204243830Sdim                                        const TargetLibraryInfo *TLI) {
205243830Sdim  return isMallocLikeFn(I, TLI) ? dyn_cast<CallInst>(I) : 0;
206239462Sdim}
207239462Sdim
208263508Sdimstatic Value *computeArraySize(const CallInst *CI, const DataLayout *DL,
209243830Sdim                               const TargetLibraryInfo *TLI,
210199481Srdivacky                               bool LookThroughSExt = false) {
211198892Srdivacky  if (!CI)
212249423Sdim    return 0;
213198892Srdivacky
214198953Srdivacky  // The size of the malloc's result type must be known to determine array size.
215243830Sdim  Type *T = getMallocAllocatedType(CI, TLI);
216263508Sdim  if (!T || !T->isSized() || !DL)
217249423Sdim    return 0;
218198892Srdivacky
219263508Sdim  unsigned ElementSize = DL->getTypeAllocSize(T);
220226633Sdim  if (StructType *ST = dyn_cast<StructType>(T))
221263508Sdim    ElementSize = DL->getStructLayout(ST)->getSizeInBytes();
222198892Srdivacky
223210299Sed  // If malloc call's arg can be determined to be a multiple of ElementSize,
224199481Srdivacky  // return the multiple.  Otherwise, return NULL.
225210299Sed  Value *MallocArg = CI->getArgOperand(0);
226249423Sdim  Value *Multiple = 0;
227199481Srdivacky  if (ComputeMultiple(MallocArg, ElementSize, Multiple,
228199481Srdivacky                      LookThroughSExt))
229199481Srdivacky    return Multiple;
230198892Srdivacky
231249423Sdim  return 0;
232198892Srdivacky}
233198892Srdivacky
234249423Sdim/// isArrayMalloc - Returns the corresponding CallInst if the instruction
235198892Srdivacky/// is a call to malloc whose array size can be determined and the array size
236198892Srdivacky/// is not constant 1.  Otherwise, return NULL.
237243830Sdimconst CallInst *llvm::isArrayMalloc(const Value *I,
238263508Sdim                                    const DataLayout *DL,
239243830Sdim                                    const TargetLibraryInfo *TLI) {
240243830Sdim  const CallInst *CI = extractMallocCall(I, TLI);
241263508Sdim  Value *ArraySize = computeArraySize(CI, DL, TLI);
242198892Srdivacky
243249423Sdim  if (ConstantInt *ConstSize = dyn_cast_or_null<ConstantInt>(ArraySize))
244249423Sdim    if (ConstSize->isOne())
245249423Sdim      return CI;
246198892Srdivacky
247198892Srdivacky  // CI is a non-array malloc or we can't figure out that it is an array malloc.
248249423Sdim  return 0;
249198892Srdivacky}
250198892Srdivacky
251198892Srdivacky/// getMallocType - Returns the PointerType resulting from the malloc call.
252198953Srdivacky/// The PointerType depends on the number of bitcast uses of the malloc call:
253198953Srdivacky///   0: PointerType is the calls' return type.
254198953Srdivacky///   1: PointerType is the bitcast's result type.
255198953Srdivacky///  >1: Unique PointerType cannot be determined, return NULL.
256243830SdimPointerType *llvm::getMallocType(const CallInst *CI,
257243830Sdim                                 const TargetLibraryInfo *TLI) {
258243830Sdim  assert(isMallocLikeFn(CI, TLI) && "getMallocType and not malloc call");
259249423Sdim
260249423Sdim  PointerType *MallocType = 0;
261198953Srdivacky  unsigned NumOfBitCastUses = 0;
262198953Srdivacky
263198892Srdivacky  // Determine if CallInst has a bitcast use.
264206083Srdivacky  for (Value::const_use_iterator UI = CI->use_begin(), E = CI->use_end();
265198892Srdivacky       UI != E; )
266198953Srdivacky    if (const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) {
267198953Srdivacky      MallocType = cast<PointerType>(BCI->getDestTy());
268198953Srdivacky      NumOfBitCastUses++;
269198953Srdivacky    }
270198892Srdivacky
271198953Srdivacky  // Malloc call has 1 bitcast use, so type is the bitcast's destination type.
272198953Srdivacky  if (NumOfBitCastUses == 1)
273198953Srdivacky    return MallocType;
274198892Srdivacky
275198892Srdivacky  // Malloc call was not bitcast, so type is the malloc function's return type.
276198953Srdivacky  if (NumOfBitCastUses == 0)
277198892Srdivacky    return cast<PointerType>(CI->getType());
278198892Srdivacky
279198892Srdivacky  // Type could not be determined.
280249423Sdim  return 0;
281198892Srdivacky}
282198892Srdivacky
283198953Srdivacky/// getMallocAllocatedType - Returns the Type allocated by malloc call.
284198953Srdivacky/// The Type depends on the number of bitcast uses of the malloc call:
285198953Srdivacky///   0: PointerType is the malloc calls' return type.
286198953Srdivacky///   1: PointerType is the bitcast's result type.
287198953Srdivacky///  >1: Unique PointerType cannot be determined, return NULL.
288243830SdimType *llvm::getMallocAllocatedType(const CallInst *CI,
289243830Sdim                                   const TargetLibraryInfo *TLI) {
290243830Sdim  PointerType *PT = getMallocType(CI, TLI);
291249423Sdim  return PT ? PT->getElementType() : 0;
292198892Srdivacky}
293198892Srdivacky
294249423Sdim/// getMallocArraySize - Returns the array size of a malloc call.  If the
295198892Srdivacky/// argument passed to malloc is a multiple of the size of the malloced type,
296198892Srdivacky/// then return that multiple.  For non-array mallocs, the multiple is
297198892Srdivacky/// constant 1.  Otherwise, return NULL for mallocs whose array size cannot be
298198892Srdivacky/// determined.
299263508SdimValue *llvm::getMallocArraySize(CallInst *CI, const DataLayout *DL,
300243830Sdim                                const TargetLibraryInfo *TLI,
301199481Srdivacky                                bool LookThroughSExt) {
302243830Sdim  assert(isMallocLikeFn(CI, TLI) && "getMallocArraySize and not malloc call");
303263508Sdim  return computeArraySize(CI, DL, TLI, LookThroughSExt);
304198892Srdivacky}
305198892Srdivacky
306198892Srdivacky
307239462Sdim/// extractCallocCall - Returns the corresponding CallInst if the instruction
308239462Sdim/// is a calloc call.
309243830Sdimconst CallInst *llvm::extractCallocCall(const Value *I,
310243830Sdim                                        const TargetLibraryInfo *TLI) {
311243830Sdim  return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : 0;
312239462Sdim}
313239462Sdim
314239462Sdim
315210299Sed/// isFreeCall - Returns non-null if the value is a call to the builtin free()
316243830Sdimconst CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
317198892Srdivacky  const CallInst *CI = dyn_cast<CallInst>(I);
318249423Sdim  if (!CI || isa<IntrinsicInst>(CI))
319210299Sed    return 0;
320198892Srdivacky  Function *Callee = CI->getCalledFunction();
321221345Sdim  if (Callee == 0 || !Callee->isDeclaration())
322210299Sed    return 0;
323198892Srdivacky
324243830Sdim  StringRef FnName = Callee->getName();
325243830Sdim  LibFunc::Func TLIFn;
326243830Sdim  if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
327221345Sdim    return 0;
328221345Sdim
329263508Sdim  unsigned ExpectedNumParams;
330263508Sdim  if (TLIFn == LibFunc::free ||
331263508Sdim      TLIFn == LibFunc::ZdlPv || // operator delete(void*)
332263508Sdim      TLIFn == LibFunc::ZdaPv)   // operator delete[](void*)
333263508Sdim    ExpectedNumParams = 1;
334263508Sdim  else if (TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow)
335263508Sdim           TLIFn == LibFunc::ZdaPvRKSt9nothrow_t)   // delete[](void*, nothrow)
336263508Sdim    ExpectedNumParams = 2;
337263508Sdim  else
338243830Sdim    return 0;
339243830Sdim
340198892Srdivacky  // Check free prototype.
341249423Sdim  // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
342198892Srdivacky  // attribute will exist.
343226633Sdim  FunctionType *FTy = Callee->getFunctionType();
344198892Srdivacky  if (!FTy->getReturnType()->isVoidTy())
345210299Sed    return 0;
346263508Sdim  if (FTy->getNumParams() != ExpectedNumParams)
347210299Sed    return 0;
348224145Sdim  if (FTy->getParamType(0) != Type::getInt8PtrTy(Callee->getContext()))
349210299Sed    return 0;
350198892Srdivacky
351210299Sed  return CI;
352198892Srdivacky}
353239462Sdim
354239462Sdim
355239462Sdim
356239462Sdim//===----------------------------------------------------------------------===//
357239462Sdim//  Utility functions to compute size of objects.
358239462Sdim//
359239462Sdim
360239462Sdim
361239462Sdim/// \brief Compute the size of the object pointed by Ptr. Returns true and the
362239462Sdim/// object size in Size if successful, and false otherwise.
363239462Sdim/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
364239462Sdim/// byval arguments, and global variables.
365263508Sdimbool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL,
366243830Sdim                         const TargetLibraryInfo *TLI, bool RoundToAlign) {
367263508Sdim  if (!DL)
368239462Sdim    return false;
369239462Sdim
370263508Sdim  ObjectSizeOffsetVisitor Visitor(DL, TLI, Ptr->getContext(), RoundToAlign);
371239462Sdim  SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
372239462Sdim  if (!Visitor.bothKnown(Data))
373239462Sdim    return false;
374239462Sdim
375239462Sdim  APInt ObjSize = Data.first, Offset = Data.second;
376239462Sdim  // check for overflow
377239462Sdim  if (Offset.slt(0) || ObjSize.ult(Offset))
378239462Sdim    Size = 0;
379239462Sdim  else
380239462Sdim    Size = (ObjSize - Offset).getZExtValue();
381239462Sdim  return true;
382239462Sdim}
383239462Sdim
384239462Sdim
385239462SdimSTATISTIC(ObjectVisitorArgument,
386239462Sdim          "Number of arguments with unsolved size and offset");
387239462SdimSTATISTIC(ObjectVisitorLoad,
388239462Sdim          "Number of load instructions with unsolved size and offset");
389239462Sdim
390239462Sdim
391239462SdimAPInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) {
392239462Sdim  if (RoundToAlign && Align)
393239462Sdim    return APInt(IntTyBits, RoundUpToAlignment(Size.getZExtValue(), Align));
394239462Sdim  return Size;
395239462Sdim}
396239462Sdim
397263508SdimObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout *DL,
398243830Sdim                                                 const TargetLibraryInfo *TLI,
399239462Sdim                                                 LLVMContext &Context,
400239462Sdim                                                 bool RoundToAlign)
401263508Sdim: DL(DL), TLI(TLI), RoundToAlign(RoundToAlign) {
402263508Sdim  IntegerType *IntTy = DL->getIntPtrType(Context);
403239462Sdim  IntTyBits = IntTy->getBitWidth();
404239462Sdim  Zero = APInt::getNullValue(IntTyBits);
405239462Sdim}
406239462Sdim
407239462SdimSizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) {
408239462Sdim  V = V->stripPointerCasts();
409251662Sdim  if (Instruction *I = dyn_cast<Instruction>(V)) {
410251662Sdim    // If we have already seen this instruction, bail out. Cycles can happen in
411251662Sdim    // unreachable code after constant propagation.
412251662Sdim    if (!SeenInsts.insert(I))
413251662Sdim      return unknown();
414239462Sdim
415243830Sdim    if (GEPOperator *GEP = dyn_cast<GEPOperator>(V))
416251662Sdim      return visitGEPOperator(*GEP);
417251662Sdim    return visit(*I);
418243830Sdim  }
419239462Sdim  if (Argument *A = dyn_cast<Argument>(V))
420239462Sdim    return visitArgument(*A);
421239462Sdim  if (ConstantPointerNull *P = dyn_cast<ConstantPointerNull>(V))
422239462Sdim    return visitConstantPointerNull(*P);
423249423Sdim  if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
424249423Sdim    return visitGlobalAlias(*GA);
425239462Sdim  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
426239462Sdim    return visitGlobalVariable(*GV);
427239462Sdim  if (UndefValue *UV = dyn_cast<UndefValue>(V))
428239462Sdim    return visitUndefValue(*UV);
429243830Sdim  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
430239462Sdim    if (CE->getOpcode() == Instruction::IntToPtr)
431239462Sdim      return unknown(); // clueless
432251662Sdim    if (CE->getOpcode() == Instruction::GetElementPtr)
433251662Sdim      return visitGEPOperator(cast<GEPOperator>(*CE));
434243830Sdim  }
435239462Sdim
436239462Sdim  DEBUG(dbgs() << "ObjectSizeOffsetVisitor::compute() unhandled value: " << *V
437239462Sdim        << '\n');
438239462Sdim  return unknown();
439239462Sdim}
440239462Sdim
441239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
442239462Sdim  if (!I.getAllocatedType()->isSized())
443239462Sdim    return unknown();
444239462Sdim
445263508Sdim  APInt Size(IntTyBits, DL->getTypeAllocSize(I.getAllocatedType()));
446239462Sdim  if (!I.isArrayAllocation())
447239462Sdim    return std::make_pair(align(Size, I.getAlignment()), Zero);
448239462Sdim
449239462Sdim  Value *ArraySize = I.getArraySize();
450239462Sdim  if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
451239462Sdim    Size *= C->getValue().zextOrSelf(IntTyBits);
452239462Sdim    return std::make_pair(align(Size, I.getAlignment()), Zero);
453239462Sdim  }
454239462Sdim  return unknown();
455239462Sdim}
456239462Sdim
457239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
458239462Sdim  // no interprocedural analysis is done at the moment
459239462Sdim  if (!A.hasByValAttr()) {
460239462Sdim    ++ObjectVisitorArgument;
461239462Sdim    return unknown();
462239462Sdim  }
463239462Sdim  PointerType *PT = cast<PointerType>(A.getType());
464263508Sdim  APInt Size(IntTyBits, DL->getTypeAllocSize(PT->getElementType()));
465239462Sdim  return std::make_pair(align(Size, A.getParamAlignment()), Zero);
466239462Sdim}
467239462Sdim
468239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
469243830Sdim  const AllocFnsTy *FnData = getAllocationData(CS.getInstruction(), AnyAlloc,
470243830Sdim                                               TLI);
471239462Sdim  if (!FnData)
472239462Sdim    return unknown();
473239462Sdim
474239462Sdim  // handle strdup-like functions separately
475239462Sdim  if (FnData->AllocTy == StrDupLike) {
476239462Sdim    APInt Size(IntTyBits, GetStringLength(CS.getArgument(0)));
477239462Sdim    if (!Size)
478239462Sdim      return unknown();
479239462Sdim
480239462Sdim    // strndup limits strlen
481239462Sdim    if (FnData->FstParam > 0) {
482239462Sdim      ConstantInt *Arg= dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
483239462Sdim      if (!Arg)
484239462Sdim        return unknown();
485239462Sdim
486239462Sdim      APInt MaxSize = Arg->getValue().zextOrSelf(IntTyBits);
487239462Sdim      if (Size.ugt(MaxSize))
488239462Sdim        Size = MaxSize + 1;
489239462Sdim    }
490239462Sdim    return std::make_pair(Size, Zero);
491239462Sdim  }
492239462Sdim
493239462Sdim  ConstantInt *Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->FstParam));
494239462Sdim  if (!Arg)
495239462Sdim    return unknown();
496239462Sdim
497239462Sdim  APInt Size = Arg->getValue().zextOrSelf(IntTyBits);
498239462Sdim  // size determined by just 1 parameter
499239462Sdim  if (FnData->SndParam < 0)
500239462Sdim    return std::make_pair(Size, Zero);
501239462Sdim
502239462Sdim  Arg = dyn_cast<ConstantInt>(CS.getArgument(FnData->SndParam));
503239462Sdim  if (!Arg)
504239462Sdim    return unknown();
505239462Sdim
506239462Sdim  Size *= Arg->getValue().zextOrSelf(IntTyBits);
507239462Sdim  return std::make_pair(Size, Zero);
508239462Sdim
509239462Sdim  // TODO: handle more standard functions (+ wchar cousins):
510239462Sdim  // - strdup / strndup
511239462Sdim  // - strcpy / strncpy
512239462Sdim  // - strcat / strncat
513239462Sdim  // - memcpy / memmove
514239462Sdim  // - strcat / strncat
515239462Sdim  // - memset
516239462Sdim}
517239462Sdim
518239462SdimSizeOffsetType
519239462SdimObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) {
520239462Sdim  return std::make_pair(Zero, Zero);
521239462Sdim}
522239462Sdim
523239462SdimSizeOffsetType
524239462SdimObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) {
525239462Sdim  return unknown();
526239462Sdim}
527239462Sdim
528239462SdimSizeOffsetType
529239462SdimObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
530239462Sdim  // Easy cases were already folded by previous passes.
531239462Sdim  return unknown();
532239462Sdim}
533239462Sdim
534239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitGEPOperator(GEPOperator &GEP) {
535239462Sdim  SizeOffsetType PtrData = compute(GEP.getPointerOperand());
536249423Sdim  APInt Offset(IntTyBits, 0);
537263508Sdim  if (!bothKnown(PtrData) || !GEP.accumulateConstantOffset(*DL, Offset))
538239462Sdim    return unknown();
539239462Sdim
540239462Sdim  return std::make_pair(PtrData.first, PtrData.second + Offset);
541239462Sdim}
542239462Sdim
543249423SdimSizeOffsetType ObjectSizeOffsetVisitor::visitGlobalAlias(GlobalAlias &GA) {
544249423Sdim  if (GA.mayBeOverridden())
545249423Sdim    return unknown();
546249423Sdim  return compute(GA.getAliasee());
547249423Sdim}
548249423Sdim
549239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV){
550239462Sdim  if (!GV.hasDefinitiveInitializer())
551239462Sdim    return unknown();
552239462Sdim
553263508Sdim  APInt Size(IntTyBits, DL->getTypeAllocSize(GV.getType()->getElementType()));
554239462Sdim  return std::make_pair(align(Size, GV.getAlignment()), Zero);
555239462Sdim}
556239462Sdim
557239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitIntToPtrInst(IntToPtrInst&) {
558239462Sdim  // clueless
559239462Sdim  return unknown();
560239462Sdim}
561239462Sdim
562239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitLoadInst(LoadInst&) {
563239462Sdim  ++ObjectVisitorLoad;
564239462Sdim  return unknown();
565239462Sdim}
566239462Sdim
567251662SdimSizeOffsetType ObjectSizeOffsetVisitor::visitPHINode(PHINode&) {
568251662Sdim  // too complex to analyze statically.
569251662Sdim  return unknown();
570239462Sdim}
571239462Sdim
572239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitSelectInst(SelectInst &I) {
573239462Sdim  SizeOffsetType TrueSide  = compute(I.getTrueValue());
574239462Sdim  SizeOffsetType FalseSide = compute(I.getFalseValue());
575239462Sdim  if (bothKnown(TrueSide) && bothKnown(FalseSide) && TrueSide == FalseSide)
576239462Sdim    return TrueSide;
577239462Sdim  return unknown();
578239462Sdim}
579239462Sdim
580239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitUndefValue(UndefValue&) {
581239462Sdim  return std::make_pair(Zero, Zero);
582239462Sdim}
583239462Sdim
584239462SdimSizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
585239462Sdim  DEBUG(dbgs() << "ObjectSizeOffsetVisitor unknown instruction:" << I << '\n');
586239462Sdim  return unknown();
587239462Sdim}
588239462Sdim
589263508SdimObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const DataLayout *DL,
590263508Sdim                                                     const TargetLibraryInfo *TLI,
591263508Sdim                                                     LLVMContext &Context,
592263508Sdim                                                     bool RoundToAlign)
593263508Sdim: DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
594263508Sdim  RoundToAlign(RoundToAlign) {
595263508Sdim  IntTy = DL->getIntPtrType(Context);
596239462Sdim  Zero = ConstantInt::get(IntTy, 0);
597239462Sdim}
598239462Sdim
599239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
600239462Sdim  SizeOffsetEvalType Result = compute_(V);
601239462Sdim
602239462Sdim  if (!bothKnown(Result)) {
603239462Sdim    // erase everything that was computed in this iteration from the cache, so
604239462Sdim    // that no dangling references are left behind. We could be a bit smarter if
605239462Sdim    // we kept a dependency graph. It's probably not worth the complexity.
606239462Sdim    for (PtrSetTy::iterator I=SeenVals.begin(), E=SeenVals.end(); I != E; ++I) {
607239462Sdim      CacheMapTy::iterator CacheIt = CacheMap.find(*I);
608239462Sdim      // non-computable results can be safely cached
609239462Sdim      if (CacheIt != CacheMap.end() && anyKnown(CacheIt->second))
610239462Sdim        CacheMap.erase(CacheIt);
611239462Sdim    }
612239462Sdim  }
613239462Sdim
614239462Sdim  SeenVals.clear();
615239462Sdim  return Result;
616239462Sdim}
617239462Sdim
618239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
619263508Sdim  ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, RoundToAlign);
620239462Sdim  SizeOffsetType Const = Visitor.compute(V);
621239462Sdim  if (Visitor.bothKnown(Const))
622239462Sdim    return std::make_pair(ConstantInt::get(Context, Const.first),
623239462Sdim                          ConstantInt::get(Context, Const.second));
624239462Sdim
625239462Sdim  V = V->stripPointerCasts();
626239462Sdim
627239462Sdim  // check cache
628239462Sdim  CacheMapTy::iterator CacheIt = CacheMap.find(V);
629239462Sdim  if (CacheIt != CacheMap.end())
630239462Sdim    return CacheIt->second;
631239462Sdim
632239462Sdim  // always generate code immediately before the instruction being
633239462Sdim  // processed, so that the generated code dominates the same BBs
634239462Sdim  Instruction *PrevInsertPoint = Builder.GetInsertPoint();
635239462Sdim  if (Instruction *I = dyn_cast<Instruction>(V))
636239462Sdim    Builder.SetInsertPoint(I);
637239462Sdim
638239462Sdim  // now compute the size and offset
639239462Sdim  SizeOffsetEvalType Result;
640263508Sdim
641263508Sdim  // Record the pointers that were handled in this run, so that they can be
642263508Sdim  // cleaned later if something fails. We also use this set to break cycles that
643263508Sdim  // can occur in dead code.
644263508Sdim  if (!SeenVals.insert(V)) {
645263508Sdim    Result = unknown();
646263508Sdim  } else if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
647239462Sdim    Result = visitGEPOperator(*GEP);
648239462Sdim  } else if (Instruction *I = dyn_cast<Instruction>(V)) {
649239462Sdim    Result = visit(*I);
650239462Sdim  } else if (isa<Argument>(V) ||
651239462Sdim             (isa<ConstantExpr>(V) &&
652239462Sdim              cast<ConstantExpr>(V)->getOpcode() == Instruction::IntToPtr) ||
653249423Sdim             isa<GlobalAlias>(V) ||
654239462Sdim             isa<GlobalVariable>(V)) {
655239462Sdim    // ignore values where we cannot do more than what ObjectSizeVisitor can
656239462Sdim    Result = unknown();
657239462Sdim  } else {
658239462Sdim    DEBUG(dbgs() << "ObjectSizeOffsetEvaluator::compute() unhandled value: "
659239462Sdim          << *V << '\n');
660239462Sdim    Result = unknown();
661239462Sdim  }
662239462Sdim
663239462Sdim  if (PrevInsertPoint)
664239462Sdim    Builder.SetInsertPoint(PrevInsertPoint);
665239462Sdim
666239462Sdim  // Don't reuse CacheIt since it may be invalid at this point.
667239462Sdim  CacheMap[V] = Result;
668239462Sdim  return Result;
669239462Sdim}
670239462Sdim
671239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
672239462Sdim  if (!I.getAllocatedType()->isSized())
673239462Sdim    return unknown();
674239462Sdim
675239462Sdim  // must be a VLA
676239462Sdim  assert(I.isArrayAllocation());
677239462Sdim  Value *ArraySize = I.getArraySize();
678239462Sdim  Value *Size = ConstantInt::get(ArraySize->getType(),
679263508Sdim                                 DL->getTypeAllocSize(I.getAllocatedType()));
680239462Sdim  Size = Builder.CreateMul(Size, ArraySize);
681239462Sdim  return std::make_pair(Size, Zero);
682239462Sdim}
683239462Sdim
684239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
685243830Sdim  const AllocFnsTy *FnData = getAllocationData(CS.getInstruction(), AnyAlloc,
686243830Sdim                                               TLI);
687239462Sdim  if (!FnData)
688239462Sdim    return unknown();
689239462Sdim
690239462Sdim  // handle strdup-like functions separately
691239462Sdim  if (FnData->AllocTy == StrDupLike) {
692239462Sdim    // TODO
693239462Sdim    return unknown();
694239462Sdim  }
695239462Sdim
696239462Sdim  Value *FirstArg = CS.getArgument(FnData->FstParam);
697239462Sdim  FirstArg = Builder.CreateZExt(FirstArg, IntTy);
698239462Sdim  if (FnData->SndParam < 0)
699239462Sdim    return std::make_pair(FirstArg, Zero);
700239462Sdim
701239462Sdim  Value *SecondArg = CS.getArgument(FnData->SndParam);
702239462Sdim  SecondArg = Builder.CreateZExt(SecondArg, IntTy);
703239462Sdim  Value *Size = Builder.CreateMul(FirstArg, SecondArg);
704239462Sdim  return std::make_pair(Size, Zero);
705239462Sdim
706239462Sdim  // TODO: handle more standard functions (+ wchar cousins):
707239462Sdim  // - strdup / strndup
708239462Sdim  // - strcpy / strncpy
709239462Sdim  // - strcat / strncat
710239462Sdim  // - memcpy / memmove
711239462Sdim  // - strcat / strncat
712239462Sdim  // - memset
713239462Sdim}
714239462Sdim
715239462SdimSizeOffsetEvalType
716239462SdimObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) {
717239462Sdim  return unknown();
718239462Sdim}
719239462Sdim
720239462SdimSizeOffsetEvalType
721239462SdimObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) {
722239462Sdim  return unknown();
723239462Sdim}
724239462Sdim
725239462SdimSizeOffsetEvalType
726239462SdimObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
727239462Sdim  SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());
728239462Sdim  if (!bothKnown(PtrData))
729239462Sdim    return unknown();
730239462Sdim
731263508Sdim  Value *Offset = EmitGEPOffset(&Builder, *DL, &GEP, /*NoAssumptions=*/true);
732239462Sdim  Offset = Builder.CreateAdd(PtrData.second, Offset);
733239462Sdim  return std::make_pair(PtrData.first, Offset);
734239462Sdim}
735239462Sdim
736239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitIntToPtrInst(IntToPtrInst&) {
737239462Sdim  // clueless
738239462Sdim  return unknown();
739239462Sdim}
740239462Sdim
741239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitLoadInst(LoadInst&) {
742239462Sdim  return unknown();
743239462Sdim}
744239462Sdim
745239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitPHINode(PHINode &PHI) {
746239462Sdim  // create 2 PHIs: one for size and another for offset
747239462Sdim  PHINode *SizePHI   = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
748239462Sdim  PHINode *OffsetPHI = Builder.CreatePHI(IntTy, PHI.getNumIncomingValues());
749239462Sdim
750239462Sdim  // insert right away in the cache to handle recursive PHIs
751239462Sdim  CacheMap[&PHI] = std::make_pair(SizePHI, OffsetPHI);
752239462Sdim
753239462Sdim  // compute offset/size for each PHI incoming pointer
754239462Sdim  for (unsigned i = 0, e = PHI.getNumIncomingValues(); i != e; ++i) {
755239462Sdim    Builder.SetInsertPoint(PHI.getIncomingBlock(i)->getFirstInsertionPt());
756239462Sdim    SizeOffsetEvalType EdgeData = compute_(PHI.getIncomingValue(i));
757239462Sdim
758239462Sdim    if (!bothKnown(EdgeData)) {
759239462Sdim      OffsetPHI->replaceAllUsesWith(UndefValue::get(IntTy));
760239462Sdim      OffsetPHI->eraseFromParent();
761239462Sdim      SizePHI->replaceAllUsesWith(UndefValue::get(IntTy));
762239462Sdim      SizePHI->eraseFromParent();
763239462Sdim      return unknown();
764239462Sdim    }
765239462Sdim    SizePHI->addIncoming(EdgeData.first, PHI.getIncomingBlock(i));
766239462Sdim    OffsetPHI->addIncoming(EdgeData.second, PHI.getIncomingBlock(i));
767239462Sdim  }
768239462Sdim
769239462Sdim  Value *Size = SizePHI, *Offset = OffsetPHI, *Tmp;
770239462Sdim  if ((Tmp = SizePHI->hasConstantValue())) {
771239462Sdim    Size = Tmp;
772239462Sdim    SizePHI->replaceAllUsesWith(Size);
773239462Sdim    SizePHI->eraseFromParent();
774239462Sdim  }
775239462Sdim  if ((Tmp = OffsetPHI->hasConstantValue())) {
776239462Sdim    Offset = Tmp;
777239462Sdim    OffsetPHI->replaceAllUsesWith(Offset);
778239462Sdim    OffsetPHI->eraseFromParent();
779239462Sdim  }
780239462Sdim  return std::make_pair(Size, Offset);
781239462Sdim}
782239462Sdim
783239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
784239462Sdim  SizeOffsetEvalType TrueSide  = compute_(I.getTrueValue());
785239462Sdim  SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
786239462Sdim
787239462Sdim  if (!bothKnown(TrueSide) || !bothKnown(FalseSide))
788239462Sdim    return unknown();
789239462Sdim  if (TrueSide == FalseSide)
790239462Sdim    return TrueSide;
791239462Sdim
792239462Sdim  Value *Size = Builder.CreateSelect(I.getCondition(), TrueSide.first,
793239462Sdim                                     FalseSide.first);
794239462Sdim  Value *Offset = Builder.CreateSelect(I.getCondition(), TrueSide.second,
795239462Sdim                                       FalseSide.second);
796239462Sdim  return std::make_pair(Size, Offset);
797239462Sdim}
798239462Sdim
799239462SdimSizeOffsetEvalType ObjectSizeOffsetEvaluator::visitInstruction(Instruction &I) {
800239462Sdim  DEBUG(dbgs() << "ObjectSizeOffsetEvaluator unknown instruction:" << I <<'\n');
801239462Sdim  return unknown();
802239462Sdim}
803