[PATCH] D123686: [DSE] Revisit pointers that may no longer escape after removing another store
Arthur Eubanks via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 13 09:39:07 PDT 2022
aeubanks created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
aeubanks requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
In dependent-capture, previously we'd see that %tmp4 is captured due to
the first store. We'd cache this info in CapturedBeforeReturn and
InvisibleToCallerAfterRet. Then the first store is then removed, causing
the cached values to be wrong.
We also need to revisit everything because normally we work backwards
when removing stores at the end of the function, but in this case
removing an earlier store causes a later store to be removable.
No compile time impact:
https://llvm-compile-time-tracker.com/compare.php?from=32f3633171aa9d7352e9507c12d219efb48899a0&to=f1dc620e55635a69250d011c1a9950c45a364264&stat=instructions
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D123686
Files:
llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
llvm/test/Transforms/DeadStoreElimination/dependent-capture.ll
Index: llvm/test/Transforms/DeadStoreElimination/dependent-capture.ll
===================================================================
--- llvm/test/Transforms/DeadStoreElimination/dependent-capture.ll
+++ llvm/test/Transforms/DeadStoreElimination/dependent-capture.ll
@@ -5,7 +5,6 @@
; CHECK-LABEL: @f(
; CHECK-NEXT: [[TMP1:%.*]] = call noalias ptr @_Znwm()
; CHECK-NEXT: [[TMP4:%.*]] = call noalias ptr @_Znwm()
-; CHECK-NEXT: store i8 0, ptr [[TMP4]], align 1
; CHECK-NEXT: ret void
;
%tmp1 = call noalias ptr @_Znwm()
Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1597,6 +1597,13 @@
if (MemoryAccess *MA = MSSA.getMemoryAccess(DeadInst)) {
if (MemoryDef *MD = dyn_cast<MemoryDef>(MA)) {
SkipStores.insert(MD);
+ if (auto *SI = dyn_cast<StoreInst>(MD->getMemoryInst())) {
+ if (SI->getValueOperand()->getType()->isPointerTy()) {
+ const Value *UO = getUnderlyingObject(SI->getValueOperand());
+ CapturedBeforeReturn.erase(UO);
+ InvisibleToCallerAfterRet.erase(UO);
+ }
+ }
}
Updater.removeMemoryAccess(MA);
@@ -1667,36 +1674,41 @@
/// accessed before returning from the function.
bool eliminateDeadWritesAtEndOfFunction() {
bool MadeChange = false;
+ bool MadeChangeThisIteration;
LLVM_DEBUG(
dbgs()
<< "Trying to eliminate MemoryDefs at the end of the function\n");
- for (MemoryDef *Def : llvm::reverse(MemDefs)) {
- if (SkipStores.contains(Def))
- continue;
+ do {
+ MadeChangeThisIteration = false;
+ for (MemoryDef *Def : llvm::reverse(MemDefs)) {
+ if (SkipStores.contains(Def))
+ continue;
- Instruction *DefI = Def->getMemoryInst();
- auto DefLoc = getLocForWrite(DefI);
- if (!DefLoc || !isRemovable(DefI))
- continue;
+ Instruction *DefI = Def->getMemoryInst();
+ auto DefLoc = getLocForWrite(DefI);
+ if (!DefLoc || !isRemovable(DefI))
+ continue;
- // NOTE: Currently eliminating writes at the end of a function is limited
- // to MemoryDefs with a single underlying object, to save compile-time. In
- // practice it appears the case with multiple underlying objects is very
- // uncommon. If it turns out to be important, we can use
- // getUnderlyingObjects here instead.
- const Value *UO = getUnderlyingObject(DefLoc->Ptr);
- if (!isInvisibleToCallerAfterRet(UO))
- continue;
+ // NOTE: Currently eliminating writes at the end of a function is
+ // limited to MemoryDefs with a single underlying object, to save
+ // compile-time. In practice it appears the case with multiple
+ // underlying objects is very uncommon. If it turns out to be important,
+ // we can use getUnderlyingObjects here instead.
+ const Value *UO = getUnderlyingObject(DefLoc->Ptr);
+ if (!isInvisibleToCallerAfterRet(UO))
+ continue;
- if (isWriteAtEndOfFunction(Def)) {
- // See through pointer-to-pointer bitcasts
- LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
- "of the function\n");
- deleteDeadInstruction(DefI);
- ++NumFastStores;
- MadeChange = true;
+ if (isWriteAtEndOfFunction(Def)) {
+ // See through pointer-to-pointer bitcasts
+ LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
+ "of the function\n");
+ deleteDeadInstruction(DefI);
+ ++NumFastStores;
+ MadeChange = true;
+ MadeChangeThisIteration = true;
+ }
}
- }
+ } while (MadeChangeThisIteration);
return MadeChange;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D123686.422538.patch
Type: text/x-patch
Size: 4005 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220413/37614219/attachment.bin>
More information about the llvm-commits
mailing list