diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 | 
| commit | 06f9d4012fb8acea3e9861d5722b5965dbb724d9 (patch) | |
| tree | ffe0478472eaa0686f11cb02c6df7d257b8719b0 /lib/Analysis/CaptureTracking.cpp | |
| parent | 76e2e0ebfdd3d91b07a75822865ea3e9121a99ce (diff) | |
Notes
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 f615881829c6..a276c64c9a44 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; | 
