diff options
author | Anh Tuyen Tran <anhtuyen@ca.ibm.com> | 2020-10-15 18:37:29 +0000 |
---|---|---|
committer | Anh Tuyen Tran <anhtuyen@ca.ibm.com> | 2020-10-15 18:37:29 +0000 |
commit | 224fd6ff48e26840f11f870faf2bde124dc2d261 (patch) | |
tree | 19f0cef4e2a6431a557bad5929c2c0701ba35aba | |
parent | 67f189e93ce3c25db74697551a77831a72b34929 (diff) | |
download | llvm-224fd6ff48e26840f11f870faf2bde124dc2d261.zip llvm-224fd6ff48e26840f11f870faf2bde124dc2d261.tar.gz llvm-224fd6ff48e26840f11f870faf2bde124dc2d261.tar.bz2 |
[NFC][CaptureTracking] Move static function isNonEscapingLocalObject to llvm namespace
Function isNonEscapingLocalObject is a static one within BasicAliasAnalysis.cpp.
It wraps around PointerMayBeCaptured of CaptureTracking, checking whether a pointer
is to a function-local object, which never escapes from the function.
Although at the moment, isNonEscapingLocalObject is used only by BasicAliasAnalysis,
its functionality can be used by other pass(es), one of which I will put up for review
very soon. Instead of copying the contents of this static function, I move it to llvm
scope, and place it amongst other functions with similar functionality in CaptureTracking.
The rationale for the location are:
- Pointer escape and pointer being captured are actually two sides of the same coin
- isNonEscapingLocalObject is wrapping around another function in CaptureTracking
Reviewed By: jdoerfert (Johannes Doerfert)
Differential Revision: https://reviews.llvm.org/D89465
-rw-r--r-- | llvm/include/llvm/Analysis/CaptureTracking.h | 8 | ||||
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 41 |
3 files changed, 49 insertions, 44 deletions
diff --git a/llvm/include/llvm/Analysis/CaptureTracking.h b/llvm/include/llvm/Analysis/CaptureTracking.h index e68675b..9da5f18 100644 --- a/llvm/include/llvm/Analysis/CaptureTracking.h +++ b/llvm/include/llvm/Analysis/CaptureTracking.h @@ -13,6 +13,8 @@ #ifndef LLVM_ANALYSIS_CAPTURETRACKING_H #define LLVM_ANALYSIS_CAPTURETRACKING_H +#include "llvm/ADT/DenseMap.h" + namespace llvm { class Value; @@ -94,6 +96,12 @@ namespace llvm { /// is zero, a default value is assumed. void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, unsigned MaxUsesToExplore = 0); + + /// Returns true if the pointer is to a function-local object that never + /// escapes from the function. + bool isNonEscapingLocalObject( + const Value *V, + SmallDenseMap<const Value *, bool, 8> *IsCapturedCache = nullptr); } // end namespace llvm #endif diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index ca043b4..72ea8d0 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -115,50 +115,6 @@ bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA, // Useful predicates //===----------------------------------------------------------------------===// -/// Returns true if the pointer is to a function-local object that never -/// escapes from the function. -static bool isNonEscapingLocalObject( - const Value *V, - SmallDenseMap<const Value *, bool, 8> *IsCapturedCache = nullptr) { - SmallDenseMap<const Value *, bool, 8>::iterator CacheIt; - if (IsCapturedCache) { - bool Inserted; - std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false}); - if (!Inserted) - // Found cached result, return it! - return CacheIt->second; - } - - // If this is a local allocation, check to see if it escapes. - if (isa<AllocaInst>(V) || isNoAliasCall(V)) { - // Set StoreCaptures to True so that we can assume in our callers that the - // pointer is not the result of a load instruction. Currently - // PointerMayBeCaptured doesn't have any special analysis for the - // StoreCaptures=false case; if it did, our callers could be refined to be - // more precise. - auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); - if (IsCapturedCache) - CacheIt->second = Ret; - return Ret; - } - - // If this is an argument that corresponds to a byval or noalias argument, - // then it has not escaped before entering the function. Check if it escapes - // inside the function. - if (const Argument *A = dyn_cast<Argument>(V)) - if (A->hasByValAttr() || A->hasNoAliasAttr()) { - // Note even if the argument is marked nocapture, we still need to check - // for copies made inside the function. The nocapture attribute only - // specifies that there are no copies made that outlive the function. - auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); - if (IsCapturedCache) - CacheIt->second = Ret; - return Ret; - } - - return false; -} - /// Returns true if the pointer is one which would have been considered an /// escape by isNonEscapingLocalObject. static bool isEscapeSource(const Value *V) { diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp index 6de6aaa..06a3b81e 100644 --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -395,3 +395,44 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker, // All uses examined. } + +bool llvm::isNonEscapingLocalObject( + const Value *V, SmallDenseMap<const Value *, bool, 8> *IsCapturedCache) { + SmallDenseMap<const Value *, bool, 8>::iterator CacheIt; + if (IsCapturedCache) { + bool Inserted; + std::tie(CacheIt, Inserted) = IsCapturedCache->insert({V, false}); + if (!Inserted) + // Found cached result, return it! + return CacheIt->second; + } + + // If this is a local allocation, check to see if it escapes. + if (isa<AllocaInst>(V) || isNoAliasCall(V)) { + // Set StoreCaptures to True so that we can assume in our callers that the + // pointer is not the result of a load instruction. Currently + // PointerMayBeCaptured doesn't have any special analysis for the + // StoreCaptures=false case; if it did, our callers could be refined to be + // more precise. + auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); + if (IsCapturedCache) + CacheIt->second = Ret; + return Ret; + } + + // If this is an argument that corresponds to a byval or noalias argument, + // then it has not escaped before entering the function. Check if it escapes + // inside the function. + if (const Argument *A = dyn_cast<Argument>(V)) + if (A->hasByValAttr() || A->hasNoAliasAttr()) { + // Note even if the argument is marked nocapture, we still need to check + // for copies made inside the function. The nocapture attribute only + // specifies that there are no copies made that outlive the function. + auto Ret = !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); + if (IsCapturedCache) + CacheIt->second = Ret; + return Ret; + } + + return false; +} |