diff options
author | Sergey Kachkov <109674256+skachkov-sc@users.noreply.github.com> | 2023-10-10 19:22:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-10 19:22:00 +0300 |
commit | 9f12f655c44faf47e5c42c016b543cc431b66af8 (patch) | |
tree | 475d2c2f945142111f6caf1418057a3a374c03fc /llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | |
parent | 9ce8103e87397578137daf893bfc410b3a7db1dc (diff) | |
download | llvm-9f12f655c44faf47e5c42c016b543cc431b66af8.zip llvm-9f12f655c44faf47e5c42c016b543cc431b66af8.tar.gz llvm-9f12f655c44faf47e5c42c016b543cc431b66af8.tar.bz2 |
[GVN] Drop Clobber dependency if store may overwrite only the same value (#68322)
In some cases clobbering store can be safely skipped if it can only must
or no alias with memory location and it writes the same value. This
patch supports simple case when the value from memory location was
loaded in the same basic block before the store and there are no
modifications between them.
Diffstat (limited to 'llvm/lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 071ecdb..49a31a5 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -360,11 +360,43 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI, return MemDepResult::getNonLocal(); } +// Check if SI that may alias with MemLoc can be safely skipped. This is +// possible in case if SI can only must alias or no alias with MemLoc (no +// partial overlapping possible) and it writes the same value that MemLoc +// contains now (it was loaded before this store and was not modified in +// between). +static bool canSkipClobberingStore(const StoreInst *SI, + const MemoryLocation &MemLoc, + Align MemLocAlign, BatchAAResults &BatchAA, + unsigned ScanLimit) { + if (!MemLoc.Size.hasValue()) + return false; + if (MemoryLocation::get(SI).Size != MemLoc.Size) + return false; + if (std::min(MemLocAlign, SI->getAlign()).value() < MemLoc.Size.getValue()) + return false; + + auto *LI = dyn_cast<LoadInst>(SI->getValueOperand()); + if (!LI || LI->getParent() != SI->getParent()) + return false; + if (BatchAA.alias(MemoryLocation::get(LI), MemLoc) != AliasResult::MustAlias) + return false; + unsigned NumVisitedInsts = 0; + for (const Instruction *I = LI; I != SI; I = I->getNextNonDebugInstruction()) + if (++NumVisitedInsts > ScanLimit || + isModSet(BatchAA.getModRefInfo(I, MemLoc))) + return false; + + return true; +} + MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom( const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst, unsigned *Limit, BatchAAResults &BatchAA) { bool isInvariantLoad = false; + Align MemLocAlign = + MemLoc.Ptr->getPointerAlignment(BB->getModule()->getDataLayout()); unsigned DefaultLimit = getDefaultBlockScanLimit(); if (!Limit) @@ -402,11 +434,12 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom( // do want to respect mustalias results since defs are useful for value // forwarding, but any mayalias write can be assumed to be noalias. // Arguably, this logic should be pushed inside AliasAnalysis itself. - if (isLoad && QueryInst) { - LoadInst *LI = dyn_cast<LoadInst>(QueryInst); - if (LI && LI->hasMetadata(LLVMContext::MD_invariant_load)) - isInvariantLoad = true; - } + if (isLoad && QueryInst) + if (LoadInst *LI = dyn_cast<LoadInst>(QueryInst)) { + if (LI->hasMetadata(LLVMContext::MD_invariant_load)) + isInvariantLoad = true; + MemLocAlign = LI->getAlign(); + } // True for volatile instruction. // For Load/Store return true if atomic ordering is stronger than AO, @@ -577,6 +610,8 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom( return MemDepResult::getDef(Inst); if (isInvariantLoad) continue; + if (canSkipClobberingStore(SI, MemLoc, MemLocAlign, BatchAA, *Limit)) + continue; return MemDepResult::getClobber(Inst); } |