diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 27 | 
2 files changed, 22 insertions, 35 deletions
| diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 94a3d1ba789..e135f1160e9 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/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<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); diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 1522dbab47d..fe4c03a7518 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -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) | 

