[PATCH] D153453: (WIP)[MemCpyOpt] implement inter-BB stack-move optimization which unify the lifetime overlapped fully copied allocas, the src is never modified or referenced
Kohei Asano via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 26 09:31:05 PDT 2023
khei4 updated this revision to Diff 534603.
khei4 edited the summary of this revision.
khei4 added a comment.
- check the dest Mod before copying, but more flaw cases might exist.
(still crashed on erasing redundant lifetime.)
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D153453/new/
https://reviews.llvm.org/D153453
Files:
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -1461,9 +1461,24 @@
llvm::PointerMayBeCaptured(SrcAlloca, /* ReturnCaptures=*/true,
/* StoreCaptures= */ true))
return false;
+ // TODO: refine the before memcpy condition for dest alloca
+ // Bailout if any Mod except lifetime intrinsics exists before memcpy on the
+ // dest.
+ auto DestLoc = MemoryLocation(DestAlloca, LocationSize::precise(Size));
+ for (User *U : DestAlloca->users()) {
+ if (auto *I = dyn_cast<Instruction>(U)) {
+ if (!I->comesBefore(Store))
+ continue;
+ if (auto *II = dyn_cast<IntrinsicInst>(I);
+ II && II->isLifetimeStartOrEnd())
+ continue;
+ if (isModSet(AA->getModRefInfo(I, DestLoc)))
+ return false;
+ }
+ }
- // 3. The src has no read and no write except lifetime intrinsics, from after
- // the full copy to the end of the BB.
+ // 3. The src has no read and no write except lifetime intrinsics, from
+ // after the full copy to the end of the BB.
for (auto It = ++Store->getIterator(), E = Store->getParent()->end(); It != E;
++It) {
// See all users of the SrcAlloca, between full copy and end of the BB.
@@ -1485,39 +1500,35 @@
DestAlloca->replaceAllUsesWith(SrcAlloca);
// Erase redundant lifetimes
- // FIXME: currently this doesn't work correctly for lifetime.end
IntrinsicInst *LifetimeStart = nullptr, *LifetimeEnd = nullptr;
- for (auto It = SrcAlloca->user_begin(), E = SrcAlloca->user_end(); It != E;
- ++It) {
- if (auto *II = dyn_cast<IntrinsicInst>(*It);
- II && II->isLifetimeStartOrEnd()) {
+ SmallVector<IntrinsicInst *, 4> LifetimeToErase;
+ for (User *U : SrcAlloca->users()) {
+ if (auto *II = dyn_cast<IntrinsicInst>(U)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
- if (!LifetimeStart) {
+ if (!LifetimeStart)
LifetimeStart = II;
- continue;
- }
- if (II->comesBefore(LifetimeStart)) {
- eraseInstruction(LifetimeStart);
+ else if (II->comesBefore(LifetimeStart)) {
+ LifetimeToErase.push_back(LifetimeStart);
LifetimeStart = II;
- continue;
- }
+ } else
+ LifetimeToErase.push_back(II);
} else if (II->getIntrinsicID() == Intrinsic::lifetime_end) {
- if (!LifetimeEnd) {
+ if (!LifetimeEnd)
LifetimeEnd = II;
- continue;
- }
- if (LifetimeEnd->comesBefore(II)) {
- eraseInstruction(LifetimeEnd);
+ else if (LifetimeEnd->comesBefore(II)) {
+ LifetimeToErase.push_back(LifetimeEnd);
LifetimeEnd = II;
- continue;
- }
+ } else
+ LifetimeToErase.push_back(II);
}
- // FIXME: this is necessary to remove redundant lifetime.end, but breaks
- // for some reasons
- // eraseInstruction(II);
}
}
+ // FIXME: still crash on erase
+ for (auto *II : make_early_inc_range(LifetimeToErase)) {
+ eraseInstruction(II);
+ }
+
// Drop metadata on the source alloca.
SrcAlloca->dropUnknownNonDebugMetadata();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153453.534603.patch
Type: text/x-patch
Size: 3342 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230626/55bc11c9/attachment.bin>
More information about the llvm-commits
mailing list