summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/MemoryBuiltins.cpp
diff options
context:
space:
mode:
authorBrian Homerding <homerdin@gmail.com>2019-07-08 15:57:56 +0000
committerBrian Homerding <homerdin@gmail.com>2019-07-08 15:57:56 +0000
commitb4b21d807e4f47f1f87b05fddf6bb3167b14476e (patch)
tree2ca1fdfcf72d73e5d6245cbd845c3f372e0a9dc9 /llvm/lib/Analysis/MemoryBuiltins.cpp
parentb52a0c0cc88f0d66ae8ea770f92ed3448aee88a7 (diff)
downloadbcm5719-llvm-b4b21d807e4f47f1f87b05fddf6bb3167b14476e.tar.gz
bcm5719-llvm-b4b21d807e4f47f1f87b05fddf6bb3167b14476e.zip
Add, and infer, a nofree function attribute
This patch adds a function attribute, nofree, to indicate that a function does not, directly or indirectly, call a memory-deallocation function (e.g., free, C++'s operator delete). Reviewers: jdoerfert Differential Revision: https://reviews.llvm.org/D49165 llvm-svn: 365336
Diffstat (limited to 'llvm/lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp55
1 files changed, 37 insertions, 18 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 08254266482..d73419fad6a 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -263,6 +263,19 @@ bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
return getAllocationData(V, AllocLike, TLI, LookThroughBitCast).hasValue();
}
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast) {
+ return getAllocationData(V, ReallocLike, TLI, LookThroughBitCast).hasValue();
+}
+
+/// Tests if a functions is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool llvm::isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI) {
+ return getAllocationDataForFunction(F, ReallocLike, TLI).hasValue();
+}
+
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
@@ -358,19 +371,8 @@ const CallInst *llvm::extractCallocCall(const Value *I,
return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr;
}
-/// isFreeCall - Returns non-null if the value is a call to the builtin free()
-const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
- bool IsNoBuiltinCall;
- const Function *Callee =
- getCalledFunction(I, /*LookThroughBitCast=*/false, IsNoBuiltinCall);
- if (Callee == nullptr || IsNoBuiltinCall)
- return nullptr;
-
- StringRef FnName = Callee->getName();
- LibFunc TLIFn;
- if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
- return nullptr;
-
+/// isLibFreeFunction - Returns true if the function is a builtin free()
+bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
unsigned ExpectedNumParams;
if (TLIFn == LibFunc_free ||
TLIFn == LibFunc_ZdlPv || // operator delete(void*)
@@ -401,22 +403,39 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
ExpectedNumParams = 3;
else
- return nullptr;
+ return false;
// Check free prototype.
// FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
// attribute will exist.
- FunctionType *FTy = Callee->getFunctionType();
+ FunctionType *FTy = F->getFunctionType();
if (!FTy->getReturnType()->isVoidTy())
- return nullptr;
+ return false;
if (FTy->getNumParams() != ExpectedNumParams)
+ return false;
+ if (FTy->getParamType(0) != Type::getInt8PtrTy(F->getContext()))
+ return false;
+
+ return true;
+}
+
+/// isFreeCall - Returns non-null if the value is a call to the builtin free()
+const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
+ bool IsNoBuiltinCall;
+ const Function *Callee =
+ getCalledFunction(I, /*LookThroughBitCast=*/false, IsNoBuiltinCall);
+ if (Callee == nullptr || IsNoBuiltinCall)
return nullptr;
- if (FTy->getParamType(0) != Type::getInt8PtrTy(Callee->getContext()))
+
+ StringRef FnName = Callee->getName();
+ LibFunc TLIFn;
+ if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
return nullptr;
- return dyn_cast<CallInst>(I);
+ return isLibFreeFunction(Callee, TLIFn) ? dyn_cast<CallInst>(I) : nullptr;
}
+
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
OpenPOWER on IntegriCloud