diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 |
commit | e7908924d847e63b02bc82bfaa1709ab9c774dcd (patch) | |
tree | ffe0478472eaa0686f11cb02c6df7d257b8719b0 /lib/Analysis/CaptureTracking.cpp | |
parent | bf68f1ea49e39c4194f339ddd4421b0c3a31988b (diff) | |
download | FreeBSD-src-e7908924d847e63b02bc82bfaa1709ab9c774dcd.zip FreeBSD-src-e7908924d847e63b02bc82bfaa1709ab9c774dcd.tar.gz |
Update LLVM to r90226.
Diffstat (limited to 'lib/Analysis/CaptureTracking.cpp')
-rw-r--r-- | lib/Analysis/CaptureTracking.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp index f615881..a276c64 100644 --- a/lib/Analysis/CaptureTracking.cpp +++ b/lib/Analysis/CaptureTracking.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Instructions.h" #include "llvm/Value.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CallSite.h" @@ -28,8 +29,11 @@ using namespace llvm; /// by the enclosing function (which is required to exist). This routine can /// be expensive, so consider caching the results. The boolean ReturnCaptures /// specifies whether returning the value (or part of it) from the function +/// counts as capturing it or not. The boolean StoreCaptures specified whether +/// storing the value (or part of it) into memory anywhere automatically /// counts as capturing it or not. -bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { +bool llvm::PointerMayBeCaptured(const Value *V, + bool ReturnCaptures, bool StoreCaptures) { assert(isa<PointerType>(V->getType()) && "Capture is for pointers only!"); SmallVector<Use*, 16> Worklist; SmallSet<Use*, 16> Visited; @@ -53,8 +57,7 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { // Not captured if the callee is readonly, doesn't return a copy through // its return value and doesn't unwind (a readonly function can leak bits // by throwing an exception or not depending on the input value). - if (CS.onlyReadsMemory() && CS.doesNotThrow() && - I->getType() == Type::getVoidTy(V->getContext())) + if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy()) break; // Not captured if only passed via 'nocapture' arguments. Note that @@ -82,7 +85,11 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { break; case Instruction::Store: if (V == I->getOperand(0)) - // Stored the pointer - it may be captured. + // Stored the pointer - conservatively assume it may be captured. + // TODO: If StoreCaptures is not true, we could do Fancy analysis + // to determine whether this store is not actually an escape point. + // In that case, BasicAliasAnalysis should be updated as well to + // take advantage of this. return true; // Storing to the pointee does not cause the pointer to be captured. break; @@ -98,6 +105,18 @@ bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures) { Worklist.push_back(U); } break; + case Instruction::ICmp: + // Don't count comparisons of a no-alias return value against null as + // captures. This allows us to ignore comparisons of malloc results + // with null, for example. + if (isNoAliasCall(V->stripPointerCasts())) + if (ConstantPointerNull *CPN = + dyn_cast<ConstantPointerNull>(I->getOperand(1))) + if (CPN->getType()->getAddressSpace() == 0) + break; + // Otherwise, be conservative. There are crazy ways to capture pointers + // using comparisons. + return true; default: // Something else - be conservative and say it is captured. return true; |