diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 4 |
3 files changed, 30 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index b8d69f41c2a..66bb4397c3a 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -79,7 +79,12 @@ static bool isKnownNonNull(const Value *V) { static bool isNonEscapingLocalObject(const Value *V) { // If this is a local allocation, check to see if it escapes. if (isa<AllocaInst>(V) || isNoAliasCall(V)) - return !PointerMayBeCaptured(V, false); + // 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. + return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); // 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 @@ -89,7 +94,7 @@ static bool isNonEscapingLocalObject(const Value *V) { // Don't bother analyzing arguments already known not to escape. if (A->hasNoCaptureAttr()) return true; - return !PointerMayBeCaptured(V, false); + return !PointerMayBeCaptured(V, false, /*StoreCaptures=*/true); } return false; } @@ -683,15 +688,19 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, unsigned V1Size, (V2Size != ~0U && isObjectSmallerThan(O1, V2Size, *TD))) return NoAlias; - // If one pointer is the result of a call/invoke and the other is a + // If one pointer is the result of a call/invoke or load and the other is a // non-escaping local object, then we know the object couldn't escape to a - // point where the call could return it. - if ((isa<CallInst>(O1) || isa<InvokeInst>(O1)) && - isNonEscapingLocalObject(O2) && O1 != O2) - return NoAlias; - if ((isa<CallInst>(O2) || isa<InvokeInst>(O2)) && - isNonEscapingLocalObject(O1) && O1 != O2) - return NoAlias; + // point where the call could return it. The load case works because + // isNonEscapingLocalObject considers all stores to be escapes (it + // passes true for the StoreCaptures argument to PointerMayBeCaptured). + if (O1 != O2) { + if ((isa<CallInst>(O1) || isa<InvokeInst>(O1) || isa<LoadInst>(O1)) && + isNonEscapingLocalObject(O2)) + return NoAlias; + if ((isa<CallInst>(O2) || isa<InvokeInst>(O2) || isa<LoadInst>(O2)) && + isNonEscapingLocalObject(O1)) + return NoAlias; + } if (!isa<GEPOperator>(V1) && isa<GEPOperator>(V2)) { std::swap(V1, V2); diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp index 7cd055dcd89..ae0766b237c 100644 --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -28,8 +28,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; @@ -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; diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index b3a832f12d0..a16d335ef50 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -212,7 +212,7 @@ bool FunctionAttrs::AddNoCaptureAttrs(const std::vector<CallGraphNode *> &SCC) { for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A!=E; ++A) if (isa<PointerType>(A->getType()) && !A->hasNoCaptureAttr() && - !PointerMayBeCaptured(A, true)) { + !PointerMayBeCaptured(A, true, /*StoreCaptures=*/false)) { A->addAttr(Attribute::NoCapture); ++NumNoCapture; Changed = true; @@ -280,7 +280,7 @@ bool FunctionAttrs::IsFunctionMallocLike(Function *F, return false; // Did not come from an allocation. } - if (PointerMayBeCaptured(RetVal, false)) + if (PointerMayBeCaptured(RetVal, false, /*StoreCaptures=*/false)) return false; } |