diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-24 01:00:08 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-24 01:00:08 +0000 | 
| commit | c7dac04c3480f3c20487f912f77343139fce2d99 (patch) | |
| tree | 21a09bce0171e27bd1e92649db9df797fa097cea /lib/Transforms/Scalar/MemCpyOptimizer.cpp | |
| parent | 044eb2f6afba375a914ac9d8024f8f5142bb912e (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/Scalar/MemCpyOptimizer.cpp')
| -rw-r--r-- | lib/Transforms/Scalar/MemCpyOptimizer.cpp | 56 | 
1 files changed, 46 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 9c870b42a747..6af3fef963dc 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -476,22 +476,33 @@ Instruction *MemCpyOptPass::tryMergingIntoMemset(Instruction *StartInst,        Alignment = DL.getABITypeAlignment(EltType);      } -    AMemSet = -      Builder.CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment); +    // Remember the debug location. +    DebugLoc Loc; +    if (!Range.TheStores.empty()) +      Loc = Range.TheStores[0]->getDebugLoc();      DEBUG(dbgs() << "Replace stores:\n";            for (Instruction *SI : Range.TheStores) -            dbgs() << *SI << '\n'; -          dbgs() << "With: " << *AMemSet << '\n'); - -    if (!Range.TheStores.empty()) -      AMemSet->setDebugLoc(Range.TheStores[0]->getDebugLoc()); +            dbgs() << *SI << '\n');      // Zap all the stores.      for (Instruction *SI : Range.TheStores) {        MD->removeInstruction(SI);        SI->eraseFromParent();      } + +    // Create the memset after removing the stores, so that if there any cached +    // non-local dependencies on the removed instructions in +    // MemoryDependenceAnalysis, the cache entries are updated to "dirty" +    // entries pointing below the memset, so subsequent queries include the +    // memset. +    AMemSet = +      Builder.CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment); +    if (!Range.TheStores.empty()) +      AMemSet->setDebugLoc(Loc); + +    DEBUG(dbgs() << "With: " << *AMemSet << '\n'); +      ++NumMemSetInfer;    } @@ -1031,9 +1042,22 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,    //    // NOTE: This is conservative, it will stop on any read from the source loc,    // not just the defining memcpy. -  MemDepResult SourceDep = -      MD->getPointerDependencyFrom(MemoryLocation::getForSource(MDep), false, -                                   M->getIterator(), M->getParent()); +  MemoryLocation SourceLoc = MemoryLocation::getForSource(MDep); +  MemDepResult SourceDep = MD->getPointerDependencyFrom(SourceLoc, false, +                                                        M->getIterator(), M->getParent()); + +  if (SourceDep.isNonLocal()) { +    SmallVector<NonLocalDepResult, 2> NonLocalDepResults; +    MD->getNonLocalPointerDependencyFrom(M, SourceLoc, /*isLoad=*/false, +                                         NonLocalDepResults); +    if (NonLocalDepResults.size() == 1) { +      SourceDep = NonLocalDepResults[0].getResult(); +      assert((!SourceDep.getInst() || +              LookupDomTree().dominates(SourceDep.getInst(), M)) && +             "when memdep returns exactly one result, it should dominate"); +    } +  } +    if (!SourceDep.isClobber() || SourceDep.getInst() != MDep)      return false; @@ -1235,6 +1259,18 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M) {    MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(        SrcLoc, true, M->getIterator(), M->getParent()); +  if (SrcDepInfo.isNonLocal()) { +    SmallVector<NonLocalDepResult, 2> NonLocalDepResults; +    MD->getNonLocalPointerDependencyFrom(M, SrcLoc, /*isLoad=*/true, +                                         NonLocalDepResults); +    if (NonLocalDepResults.size() == 1) { +      SrcDepInfo = NonLocalDepResults[0].getResult(); +      assert((!SrcDepInfo.getInst() || +              LookupDomTree().dominates(SrcDepInfo.getInst(), M)) && +             "when memdep returns exactly one result, it should dominate"); +    } +  } +    if (SrcDepInfo.isClobber()) {      if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(SrcDepInfo.getInst()))        return processMemCpyMemCpyDependence(M, MDep);  | 
