From 237a8287454389a5b940e18c1efb2201fc443208 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 30 Nov 2008 01:39:32 +0000 Subject: [PATCH] Fix a fixme by making memdep's handling of allocations more logical. If we see that a load depends on the allocation of its memory with no intervening stores, we now return a 'None' depedency instead of "Normal". This tweaks GVN to do its optimization with the new result. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60267 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/MemoryDependenceAnalysis.cpp | 30 ++++++++--------------- lib/Transforms/Scalar/GVN.cpp | 27 +++++++++----------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 94a3d1ba789..e135f1160e9 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -159,29 +159,19 @@ getDependencyFromInternal(Instruction *QueryInst, BasicBlock::iterator ScanIt, continue; return DepResultTy(Inst, Normal); } - - // FIXME: This claims that an access depends on the allocation. This may - // make sense, but is dubious at best. It would be better to fix GVN to - // handle a 'None' Query. + + // If this is an allocation, and if we know that the accessed pointer is to + // the allocation, return None. This means that there is no dependence and + // the access can be optimized based on that. For example, a load could + // turn into undef. if (AllocationInst *AI = dyn_cast(Inst)) { - Value *Pointer = AI; - uint64_t PointerSize; - if (ConstantInt *C = dyn_cast(AI->getArraySize())) - // Use ABI size (size between elements), not store size (size of one - // element without padding). - PointerSize = C->getZExtValue() * - TD.getABITypeSize(AI->getAllocatedType()); - else - PointerSize = ~0UL; + Value *AccessPtr = MemPtr->getUnderlyingObject(); - AliasAnalysis::AliasResult R = - AA.alias(Pointer, PointerSize, MemPtr, MemSize); - - if (R == AliasAnalysis::NoAlias) - continue; - return DepResultTy(Inst, Normal); + if (AccessPtr == AI || + AA.alias(AI, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) + return DepResultTy(0, None); + continue; } - // See if this instruction mod/ref's the pointer. AliasAnalysis::ModRefResult MRR = AA.getModRefInfo(Inst, MemPtr, MemSize); diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 1522dbab47d..fe4c03a7518 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1004,27 +1004,24 @@ bool GVN::processLoad(LoadInst *L, DenseMap &lastLoad, toErase.push_back(L); deletedLoad = true; NumGVNLoad++; - break; } else { dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent()); } } - if (AllocationInst *DepAI = dyn_cast_or_null(dep.getInst())) { - // Check that this load is actually from the - // allocation we found - if (L->getOperand(0)->getUnderlyingObject() == DepAI) { - // If this load depends directly on an allocation, there isn't - // anything stored there; therefore, we can optimize this load - // to undef. - MD.removeInstruction(L); - - L->replaceAllUsesWith(UndefValue::get(L->getType())); - toErase.push_back(L); - deletedLoad = true; - NumGVNLoad++; - } + // If this load really doesn't depend on anything, then we must be loading an + // undef value. This can happen when loading for a fresh allocation with no + // intervening stores, for example. + if (dep.isNone()) { + // If this load depends directly on an allocation, there isn't + // anything stored there; therefore, we can optimize this load + // to undef. + MD.removeInstruction(L); + L->replaceAllUsesWith(UndefValue::get(L->getType())); + toErase.push_back(L); + deletedLoad = true; + NumGVNLoad++; } if (!deletedLoad) -- 2.34.1