diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4225,9 +4225,10 @@ return V; } -void llvm::getUnderlyingObjects(const Value *V, - SmallVectorImpl &Objects, - LoopInfo *LI, unsigned MaxLookup) { +template +static void findUnderlyingObjects(const Value *V, F OnObj, + LoopInfo *LI = nullptr, + unsigned MaxLookup = 6) { SmallPtrSet Visited; SmallVector Worklist; Worklist.push_back(V); @@ -4262,10 +4263,35 @@ continue; } - Objects.push_back(P); + if (!OnObj(P)) + return; } while (!Worklist.empty()); } +void llvm::getUnderlyingObjects(const Value *V, + SmallVectorImpl &Objects, + LoopInfo *LI, unsigned MaxLookup) { + findUnderlyingObjects( + V, + [&Objects](const Value *V) { + Objects.push_back(V); + return true; + }, + LI, MaxLookup); +} + +AllocaInst *llvm::findAllocaForValue(Value *V) { + const AllocaInst *A = nullptr; + findUnderlyingObjects(V, [&A](const Value *V) -> bool { + if (!A) + A = dyn_cast(V); + else if (A != V) + A = nullptr; + return A; + }); + return const_cast(A); +} + /// This is the function that does the work of looking through basic /// ptrtoint+arithmetic+inttoptr sequences. static const Value *getUnderlyingObjectFromInt(const Value *V) { @@ -4330,45 +4356,6 @@ return true; } -static AllocaInst * -findAllocaForValue(Value *V, DenseMap &AllocaForValue) { - if (AllocaInst *AI = dyn_cast(V)) - return AI; - // See if we've already calculated (or started to calculate) alloca for a - // given value. - auto I = AllocaForValue.find(V); - if (I != AllocaForValue.end()) - return I->second; - // Store 0 while we're calculating alloca for value V to avoid - // infinite recursion if the value references itself. - AllocaForValue[V] = nullptr; - AllocaInst *Res = nullptr; - if (CastInst *CI = dyn_cast(V)) - Res = findAllocaForValue(CI->getOperand(0), AllocaForValue); - else if (PHINode *PN = dyn_cast(V)) { - for (Value *IncValue : PN->incoming_values()) { - // Allow self-referencing phi-nodes. - if (IncValue == PN) - continue; - AllocaInst *IncValueAI = findAllocaForValue(IncValue, AllocaForValue); - // AI for incoming values should exist and should all be equal. - if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) - return nullptr; - Res = IncValueAI; - } - } else if (GetElementPtrInst *EP = dyn_cast(V)) { - Res = findAllocaForValue(EP->getPointerOperand(), AllocaForValue); - } - if (Res) - AllocaForValue[V] = Res; - return Res; -} - -AllocaInst *llvm::findAllocaForValue(Value *V) { - DenseMap AllocaForValue; - return ::findAllocaForValue(V, AllocaForValue); -} - static bool onlyUsedByLifetimeMarkersOrDroppableInstsHelper( const Value *V, bool AllowLifetime, bool AllowDroppable) { for (const User *U : V->users()) {