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
This commit is contained in:
Chris Lattner 2008-11-30 01:39:32 +00:00
parent 73ec3cdd71
commit 237a828745
2 changed files with 22 additions and 35 deletions

View File

@ -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<AllocationInst>(Inst)) {
Value *Pointer = AI;
uint64_t PointerSize;
if (ConstantInt *C = dyn_cast<ConstantInt>(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);

View File

@ -1004,27 +1004,24 @@ bool GVN::processLoad(LoadInst *L, DenseMap<Value*, LoadInst*> &lastLoad,
toErase.push_back(L);
deletedLoad = true;
NumGVNLoad++;
break;
} else {
dep = MD.getDependencyFrom(L, DepInst, DepInst->getParent());
}
}
if (AllocationInst *DepAI = dyn_cast_or_null<AllocationInst>(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)