diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h index f2c564f72912..2a9cd75ee78d 100644 --- a/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -153,12 +153,14 @@ typedef std::pair SizeOffsetType; class ObjectSizeOffsetVisitor : public InstVisitor { + typedef DenseMap CacheMapTy; + const DataLayout *TD; const TargetLibraryInfo *TLI; bool RoundToAlign; unsigned IntTyBits; APInt Zero; - SmallPtrSet SeenInsts; + CacheMapTy CacheMap; APInt align(APInt Size, uint64_t Align); diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp index f88affb74496..1d27a83d935e 100644 --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -387,17 +387,19 @@ SizeOffsetType ObjectSizeOffsetVisitor::compute(Value *V) { V = V->stripPointerCasts(); if (isa(V) || isa(V)) { - // If we have already seen this instruction, bail out. - if (!SeenInsts.insert(V)) - return unknown(); + // return cached value or insert unknown in cache if size of V was not + // computed yet in order to avoid recursions in PHis + std::pair CacheVal = + CacheMap.insert(std::make_pair(V, unknown())); + if (!CacheVal.second) + return CacheVal.first->second; - SizeOffsetType Ret; + SizeOffsetType Result; if (GEPOperator *GEP = dyn_cast(V)) - Ret = visitGEPOperator(*GEP); + Result = visitGEPOperator(*GEP); else - Ret = visit(cast(*V)); - SeenInsts.erase(V); - return Ret; + Result = visit(cast(*V)); + return CacheMap[V] = Result; } if (Argument *A = dyn_cast(V))