diff options
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 636206b..8e53e7c 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -224,6 +224,51 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL, } //===----------------------------------------------------------------------===// +// CaptureInfo implementations +//===----------------------------------------------------------------------===// + +CaptureInfo::~CaptureInfo() = default; + +bool SimpleCaptureInfo::isNotCapturedBeforeOrAt(const Value *Object, + const Instruction *I) { + return isNonEscapingLocalObject(Object, &IsCapturedCache); +} + +bool EarliestEscapeInfo::isNotCapturedBeforeOrAt(const Value *Object, + const Instruction *I) { + if (!isIdentifiedFunctionLocal(Object)) + return false; + + auto Iter = EarliestEscapes.insert({Object, nullptr}); + if (Iter.second) { + Instruction *EarliestCapture = FindEarliestCapture( + Object, *const_cast<Function *>(I->getFunction()), + /*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT); + if (EarliestCapture) { + auto Ins = Inst2Obj.insert({EarliestCapture, {}}); + Ins.first->second.push_back(Object); + } + Iter.first->second = EarliestCapture; + } + + // No capturing instruction. + if (!Iter.first->second) + return true; + + return I != Iter.first->second && + !isPotentiallyReachable(Iter.first->second, I, nullptr, &DT, &LI); +} + +void EarliestEscapeInfo::removeInstruction(Instruction *I) { + auto Iter = Inst2Obj.find(I); + if (Iter != Inst2Obj.end()) { + for (const Value *Obj : Iter->second) + EarliestEscapes.erase(Obj); + Inst2Obj.erase(I); + } +} + +//===----------------------------------------------------------------------===// // GetElementPtr Instruction Decomposition and Analysis //===----------------------------------------------------------------------===// @@ -835,7 +880,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call, // then the call can not mod/ref the pointer unless the call takes the pointer // as an argument, and itself doesn't capture it. if (!isa<Constant>(Object) && Call != Object && - isNonEscapingLocalObject(Object, &AAQI.IsCapturedCache)) { + AAQI.CI->isNotCapturedBeforeOrAt(Object, Call)) { // Optimistically assume that call doesn't touch Object and check this // assumption in the following loop. @@ -1514,10 +1559,10 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size, // location if that memory location doesn't escape. Or it may pass a // nocapture value to other functions as long as they don't capture it. if (isEscapeSource(O1) && - isNonEscapingLocalObject(O2, &AAQI.IsCapturedCache)) + AAQI.CI->isNotCapturedBeforeOrAt(O2, cast<Instruction>(O1))) return AliasResult::NoAlias; if (isEscapeSource(O2) && - isNonEscapingLocalObject(O1, &AAQI.IsCapturedCache)) + AAQI.CI->isNotCapturedBeforeOrAt(O1, cast<Instruction>(O2))) return AliasResult::NoAlias; } |