Mercurial > hg > CbC > CbC_llvm
comparison lib/Analysis/MemoryBuiltins.cpp @ 100:7d135dc70f03 LLVM 3.9
LLVM 3.9
author | Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 26 Jan 2016 22:53:40 +0900 |
parents | afa8332a0e37 |
children | 1172e4bd9c6f |
comparison
equal
deleted
inserted
replaced
96:6418606d0ead | 100:7d135dc70f03 |
---|---|
29 #include "llvm/Transforms/Utils/Local.h" | 29 #include "llvm/Transforms/Utils/Local.h" |
30 using namespace llvm; | 30 using namespace llvm; |
31 | 31 |
32 #define DEBUG_TYPE "memory-builtins" | 32 #define DEBUG_TYPE "memory-builtins" |
33 | 33 |
34 enum AllocType { | 34 enum AllocType : uint8_t { |
35 OpNewLike = 1<<0, // allocates; never returns null | 35 OpNewLike = 1<<0, // allocates; never returns null |
36 MallocLike = 1<<1 | OpNewLike, // allocates; may return null | 36 MallocLike = 1<<1 | OpNewLike, // allocates; may return null |
37 CallocLike = 1<<2, // allocates + bzero | 37 CallocLike = 1<<2, // allocates + bzero |
38 ReallocLike = 1<<3, // reallocates | 38 ReallocLike = 1<<3, // reallocates |
39 StrDupLike = 1<<4, | 39 StrDupLike = 1<<4, |
60 {LibFunc::ZnwmRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new(unsigned long, nothrow) | 60 {LibFunc::ZnwmRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new(unsigned long, nothrow) |
61 {LibFunc::Znaj, OpNewLike, 1, 0, -1}, // new[](unsigned int) | 61 {LibFunc::Znaj, OpNewLike, 1, 0, -1}, // new[](unsigned int) |
62 {LibFunc::ZnajRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) | 62 {LibFunc::ZnajRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) |
63 {LibFunc::Znam, OpNewLike, 1, 0, -1}, // new[](unsigned long) | 63 {LibFunc::Znam, OpNewLike, 1, 0, -1}, // new[](unsigned long) |
64 {LibFunc::ZnamRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned long, nothrow) | 64 {LibFunc::ZnamRKSt9nothrow_t, MallocLike, 2, 0, -1}, // new[](unsigned long, nothrow) |
65 {LibFunc::msvc_new_int, OpNewLike, 1, 0, -1}, // new(unsigned int) | |
66 {LibFunc::msvc_new_int_nothrow, MallocLike, 2, 0, -1}, // new(unsigned int, nothrow) | |
67 {LibFunc::msvc_new_longlong, OpNewLike, 1, 0, -1}, // new(unsigned long long) | |
68 {LibFunc::msvc_new_longlong_nothrow, MallocLike, 2, 0, -1}, // new(unsigned long long, nothrow) | |
69 {LibFunc::msvc_new_array_int, OpNewLike, 1, 0, -1}, // new[](unsigned int) | |
70 {LibFunc::msvc_new_array_int_nothrow, MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow) | |
71 {LibFunc::msvc_new_array_longlong, OpNewLike, 1, 0, -1}, // new[](unsigned long long) | |
72 {LibFunc::msvc_new_array_longlong_nothrow, MallocLike, 2, 0, -1}, // new[](unsigned long long, nothrow) | |
65 {LibFunc::calloc, CallocLike, 2, 0, 1}, | 73 {LibFunc::calloc, CallocLike, 2, 0, 1}, |
66 {LibFunc::realloc, ReallocLike, 2, 1, -1}, | 74 {LibFunc::realloc, ReallocLike, 2, 1, -1}, |
67 {LibFunc::reallocf, ReallocLike, 2, 1, -1}, | 75 {LibFunc::reallocf, ReallocLike, 2, 1, -1}, |
68 {LibFunc::strdup, StrDupLike, 1, -1, -1}, | 76 {LibFunc::strdup, StrDupLike, 1, -1, -1}, |
69 {LibFunc::strndup, StrDupLike, 2, 1, -1} | 77 {LibFunc::strndup, StrDupLike, 2, 1, -1} |
105 StringRef FnName = Callee->getName(); | 113 StringRef FnName = Callee->getName(); |
106 LibFunc::Func TLIFn; | 114 LibFunc::Func TLIFn; |
107 if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) | 115 if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn)) |
108 return nullptr; | 116 return nullptr; |
109 | 117 |
110 unsigned i = 0; | 118 const AllocFnsTy *FnData = |
111 bool found = false; | 119 std::find_if(std::begin(AllocationFnData), std::end(AllocationFnData), |
112 for ( ; i < array_lengthof(AllocationFnData); ++i) { | 120 [TLIFn](const AllocFnsTy &Fn) { return Fn.Func == TLIFn; }); |
113 if (AllocationFnData[i].Func == TLIFn) { | 121 |
114 found = true; | 122 if (FnData == std::end(AllocationFnData)) |
115 break; | 123 return nullptr; |
116 } | 124 |
117 } | |
118 if (!found) | |
119 return nullptr; | |
120 | |
121 const AllocFnsTy *FnData = &AllocationFnData[i]; | |
122 if ((FnData->AllocTy & AllocTy) != FnData->AllocTy) | 125 if ((FnData->AllocTy & AllocTy) != FnData->AllocTy) |
123 return nullptr; | 126 return nullptr; |
124 | 127 |
125 // Check function prototype. | 128 // Check function prototype. |
126 int FstParam = FnData->FstParam; | 129 int FstParam = FnData->FstParam; |
182 bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, | 185 bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, |
183 bool LookThroughBitCast) { | 186 bool LookThroughBitCast) { |
184 return getAllocationData(V, AllocLike, TLI, LookThroughBitCast); | 187 return getAllocationData(V, AllocLike, TLI, LookThroughBitCast); |
185 } | 188 } |
186 | 189 |
187 /// \brief Tests if a value is a call or invoke to a library function that | |
188 /// reallocates memory (such as realloc). | |
189 bool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, | |
190 bool LookThroughBitCast) { | |
191 return getAllocationData(V, ReallocLike, TLI, LookThroughBitCast); | |
192 } | |
193 | |
194 /// \brief Tests if a value is a call or invoke to a library function that | |
195 /// allocates memory and never returns null (such as operator new). | |
196 bool llvm::isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI, | |
197 bool LookThroughBitCast) { | |
198 return getAllocationData(V, OpNewLike, TLI, LookThroughBitCast); | |
199 } | |
200 | |
201 /// extractMallocCall - Returns the corresponding CallInst if the instruction | 190 /// extractMallocCall - Returns the corresponding CallInst if the instruction |
202 /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we | 191 /// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we |
203 /// ignore InvokeInst here. | 192 /// ignore InvokeInst here. |
204 const CallInst *llvm::extractMallocCall(const Value *I, | 193 const CallInst *llvm::extractMallocCall(const Value *I, |
205 const TargetLibraryInfo *TLI) { | 194 const TargetLibraryInfo *TLI) { |
311 return nullptr; | 300 return nullptr; |
312 | 301 |
313 unsigned ExpectedNumParams; | 302 unsigned ExpectedNumParams; |
314 if (TLIFn == LibFunc::free || | 303 if (TLIFn == LibFunc::free || |
315 TLIFn == LibFunc::ZdlPv || // operator delete(void*) | 304 TLIFn == LibFunc::ZdlPv || // operator delete(void*) |
316 TLIFn == LibFunc::ZdaPv) // operator delete[](void*) | 305 TLIFn == LibFunc::ZdaPv || // operator delete[](void*) |
306 TLIFn == LibFunc::msvc_delete_ptr32 || // operator delete(void*) | |
307 TLIFn == LibFunc::msvc_delete_ptr64 || // operator delete(void*) | |
308 TLIFn == LibFunc::msvc_delete_array_ptr32 || // operator delete[](void*) | |
309 TLIFn == LibFunc::msvc_delete_array_ptr64) // operator delete[](void*) | |
317 ExpectedNumParams = 1; | 310 ExpectedNumParams = 1; |
318 else if (TLIFn == LibFunc::ZdlPvj || // delete(void*, uint) | 311 else if (TLIFn == LibFunc::ZdlPvj || // delete(void*, uint) |
319 TLIFn == LibFunc::ZdlPvm || // delete(void*, ulong) | 312 TLIFn == LibFunc::ZdlPvm || // delete(void*, ulong) |
320 TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) | 313 TLIFn == LibFunc::ZdlPvRKSt9nothrow_t || // delete(void*, nothrow) |
321 TLIFn == LibFunc::ZdaPvj || // delete[](void*, uint) | 314 TLIFn == LibFunc::ZdaPvj || // delete[](void*, uint) |
322 TLIFn == LibFunc::ZdaPvm || // delete[](void*, ulong) | 315 TLIFn == LibFunc::ZdaPvm || // delete[](void*, ulong) |
323 TLIFn == LibFunc::ZdaPvRKSt9nothrow_t) // delete[](void*, nothrow) | 316 TLIFn == LibFunc::ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow) |
317 TLIFn == LibFunc::msvc_delete_ptr32_int || // delete(void*, uint) | |
318 TLIFn == LibFunc::msvc_delete_ptr64_longlong || // delete(void*, ulonglong) | |
319 TLIFn == LibFunc::msvc_delete_ptr32_nothrow || // delete(void*, nothrow) | |
320 TLIFn == LibFunc::msvc_delete_ptr64_nothrow || // delete(void*, nothrow) | |
321 TLIFn == LibFunc::msvc_delete_array_ptr32_int || // delete[](void*, uint) | |
322 TLIFn == LibFunc::msvc_delete_array_ptr64_longlong || // delete[](void*, ulonglong) | |
323 TLIFn == LibFunc::msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow) | |
324 TLIFn == LibFunc::msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow) | |
324 ExpectedNumParams = 2; | 325 ExpectedNumParams = 2; |
325 else | 326 else |
326 return nullptr; | 327 return nullptr; |
327 | 328 |
328 // Check free prototype. | 329 // Check free prototype. |
373 "Number of load instructions with unsolved size and offset"); | 374 "Number of load instructions with unsolved size and offset"); |
374 | 375 |
375 | 376 |
376 APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) { | 377 APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) { |
377 if (RoundToAlign && Align) | 378 if (RoundToAlign && Align) |
378 return APInt(IntTyBits, RoundUpToAlignment(Size.getZExtValue(), Align)); | 379 return APInt(IntTyBits, alignTo(Size.getZExtValue(), Align)); |
379 return Size; | 380 return Size; |
380 } | 381 } |
381 | 382 |
382 ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL, | 383 ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL, |
383 const TargetLibraryInfo *TLI, | 384 const TargetLibraryInfo *TLI, |