diff options
Diffstat (limited to 'llvm/lib/Analysis/CaptureTracking.cpp')
| -rw-r--r-- | llvm/lib/Analysis/CaptureTracking.cpp | 80 |
1 files changed, 14 insertions, 66 deletions
diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp index b2fc6e603f9e..5fe4f9befc86 100644 --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -68,8 +68,8 @@ bool CaptureTracker::isDereferenceableOrNull(Value *O, const DataLayout &DL) { if (auto *GEP = dyn_cast<GetElementPtrInst>(O)) if (GEP->isInBounds()) return true; - bool CanBeNull; - return O->getPointerDereferenceableBytes(DL, CanBeNull); + bool CanBeNull, CanBeFreed; + return O->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); } namespace { @@ -106,67 +106,29 @@ namespace { void tooManyUses() override { Captured = true; } bool isSafeToPrune(Instruction *I) { - BasicBlock *BB = I->getParent(); + if (BeforeHere == I) + return !IncludeI; + // We explore this usage only if the usage can reach "BeforeHere". // If use is not reachable from entry, there is no need to explore. - if (BeforeHere != I && !DT->isReachableFromEntry(BB)) + if (!DT->isReachableFromEntry(I->getParent())) return true; - // Compute the case where both instructions are inside the same basic - // block. - if (BB == BeforeHere->getParent()) { - // 'I' dominates 'BeforeHere' => not safe to prune. - // - // The value defined by an invoke dominates an instruction only - // if it dominates every instruction in UseBB. A PHI is dominated only - // if the instruction dominates every possible use in the UseBB. Since - // UseBB == BB, avoid pruning. - if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I == BeforeHere) - return false; - if (!BeforeHere->comesBefore(I)) - return false; - - // 'BeforeHere' comes before 'I', it's safe to prune if we also - // guarantee that 'I' never reaches 'BeforeHere' through a back-edge or - // by its successors, i.e, prune if: - // - // (1) BB is an entry block or have no successors. - // (2) There's no path coming back through BB successors. - if (BB == &BB->getParent()->getEntryBlock() || - !BB->getTerminator()->getNumSuccessors()) - return true; - - SmallVector<BasicBlock*, 32> Worklist; - Worklist.append(succ_begin(BB), succ_end(BB)); - return !isPotentiallyReachableFromMany(Worklist, BB, nullptr, DT); - } - - // If the value is defined in the same basic block as use and BeforeHere, - // there is no need to explore the use if BeforeHere dominates use. // Check whether there is a path from I to BeforeHere. - if (BeforeHere != I && DT->dominates(BeforeHere, I) && - !isPotentiallyReachable(I, BeforeHere, nullptr, DT)) - return true; - - return false; + return !isPotentiallyReachable(I, BeforeHere, nullptr, DT); } - bool shouldExplore(const Use *U) override { + bool captured(const Use *U) override { Instruction *I = cast<Instruction>(U->getUser()); - - if (BeforeHere == I && !IncludeI) + if (isa<ReturnInst>(I) && !ReturnCaptures) return false; + // Check isSafeToPrune() here rather than in shouldExplore() to avoid + // an expensive reachability query for every instruction we look at. + // Instead we only do one for actual capturing candidates. if (isSafeToPrune(I)) return false; - return true; - } - - bool captured(const Use *U) override { - if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures) - return false; - Captured = true; return true; } @@ -423,8 +385,8 @@ bool llvm::isNonEscapingLocalObject( return CacheIt->second; } - // If this is a local allocation, check to see if it escapes. - if (isa<AllocaInst>(V) || isNoAliasCall(V)) { + // If this is an identified function-local object, check to see if it escapes. + if (isIdentifiedFunctionLocal(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 @@ -436,19 +398,5 @@ bool llvm::isNonEscapingLocalObject( 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; } |
