[llvm] [MemCpyOpt] Use EarliestEscapeInfo (PR #110280)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 27 08:03:34 PDT 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/110280
Pass EarliestEscapeInfo to BatchAA in MemCpyOpt. This allows memcpy elimination in cases where one of the involved pointers is captured after the relevant memcpy/call.
>From 9736bcf546005645d7f6d2e2e2492abd8521a0af Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 27 Sep 2024 16:12:50 +0200
Subject: [PATCH] [MemCpyOpt] Use EarliestEscapeInfo
Pass EarliestEscapeInfo to BatchAA in MemCpyOpt. This allows
memcpy elimination in cases where one of the involved pointers
is captured after the relevant memcpy/call.
---
.../llvm/Transforms/Scalar/MemCpyOptimizer.h | 2 ++
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 11 +++++++----
llvm/test/Transforms/MemCpyOpt/memcpy.ll | 14 ++++----------
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
index 8ed03d7f3ddbff..e5f78ac2286833 100644
--- a/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
+++ b/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
@@ -26,6 +26,7 @@ class AssumptionCache;
class CallBase;
class CallInst;
class DominatorTree;
+class EarliestEscapeInfo;
class Function;
class Instruction;
class LoadInst;
@@ -48,6 +49,7 @@ class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
PostDominatorTree *PDT = nullptr;
MemorySSA *MSSA = nullptr;
MemorySSAUpdater *MSSAU = nullptr;
+ EarliestEscapeInfo *EEI = nullptr;
public:
MemCpyOptPass() = default;
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index e9f212fb482c39..5f7dac14c1deeb 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -284,6 +284,7 @@ static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
void MemCpyOptPass::eraseInstruction(Instruction *I) {
MSSAU->removeMemoryAccess(I);
+ EEI->removeInstruction(I);
I->eraseFromParent();
}
@@ -638,7 +639,7 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI,
if (!LI->isSimple() || !LI->hasOneUse() || LI->getParent() != SI->getParent())
return false;
- BatchAAResults BAA(*AA);
+ BatchAAResults BAA(*AA, EEI);
auto *T = LI->getType();
// Don't introduce calls to memcpy/memmove intrinsics out of thin air if
// the corresponding libcalls are not available.
@@ -1751,7 +1752,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
return true;
}
- BatchAAResults BAA(*AA);
+ BatchAAResults BAA(*AA, EEI);
// FIXME: Not using getClobberingMemoryAccess() here due to PR54682.
MemoryAccess *AnyClobber = MA->getDefiningAccess();
MemoryLocation DestLoc = MemoryLocation::getForDest(M);
@@ -1876,7 +1877,7 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
if (!CallAccess)
return false;
MemCpyInst *MDep = nullptr;
- BatchAAResults BAA(*AA);
+ BatchAAResults BAA(*AA, EEI);
MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
CallAccess->getDefiningAccess(), Loc, BAA);
if (auto *MD = dyn_cast<MemoryDef>(Clobber))
@@ -1949,7 +1950,7 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
/// 4. The memcpy src is not modified during the call. (ModRef check shows no
/// Mod.)
bool MemCpyOptPass::processImmutArgument(CallBase &CB, unsigned ArgNo) {
- BatchAAResults BAA(*AA);
+ BatchAAResults BAA(*AA, EEI);
Value *ImmutArg = CB.getArgOperand(ArgNo);
// 1. Ensure passed argument is immutable during call.
@@ -2117,6 +2118,8 @@ bool MemCpyOptPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
MSSA = MSSA_;
MemorySSAUpdater MSSAU_(MSSA_);
MSSAU = &MSSAU_;
+ EarliestEscapeInfo EEI_(*DT);
+ EEI = &EEI_;
while (true) {
if (!iterateOnFunction(F))
diff --git a/llvm/test/Transforms/MemCpyOpt/memcpy.ll b/llvm/test/Transforms/MemCpyOpt/memcpy.ll
index 0114b9c2443582..39b90adc74ef38 100644
--- a/llvm/test/Transforms/MemCpyOpt/memcpy.ll
+++ b/llvm/test/Transforms/MemCpyOpt/memcpy.ll
@@ -837,7 +837,7 @@ define void @memcpy_memcpy_escape_after1(ptr noalias %P, ptr noalias %Q) {
; CHECK-NEXT: [[MEMTMP:%.*]] = alloca [32 x i8], align 16
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[MEMTMP]], ptr align 16 [[P:%.*]], i32 32, i1 false)
; CHECK-NEXT: call void @do_something()
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[MEMTMP]], i32 32, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[P]], i32 32, i1 false)
; CHECK-NEXT: call void @capture(ptr [[MEMTMP]])
; CHECK-NEXT: ret void
;
@@ -851,10 +851,8 @@ define void @memcpy_memcpy_escape_after1(ptr noalias %P, ptr noalias %Q) {
define void @memcpy_memcpy_escape_after2(ptr noalias %P, ptr noalias %Q) {
; CHECK-LABEL: @memcpy_memcpy_escape_after2(
-; CHECK-NEXT: [[MEMTMP:%.*]] = alloca [32 x i8], align 16
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[MEMTMP]], ptr align 16 [[P:%.*]], i32 32, i1 false)
; CHECK-NEXT: call void @do_something()
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[MEMTMP]], i32 32, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[P:%.*]], i32 32, i1 false)
; CHECK-NEXT: call void @capture(ptr [[P]])
; CHECK-NEXT: ret void
;
@@ -868,10 +866,8 @@ define void @memcpy_memcpy_escape_after2(ptr noalias %P, ptr noalias %Q) {
define void @memcpy_byval_escape_after(ptr noalias %P) {
; CHECK-LABEL: @memcpy_byval_escape_after(
-; CHECK-NEXT: [[A:%.*]] = alloca [8 x i8], align 1
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[A]], ptr align 4 [[P:%.*]], i64 8, i1 false)
; CHECK-NEXT: call void @do_something()
-; CHECK-NEXT: call void @test4a(ptr byval(i8) align 1 [[A]])
+; CHECK-NEXT: call void @test4a(ptr byval(i8) align 1 [[P:%.*]])
; CHECK-NEXT: call void @capture(ptr [[P]])
; CHECK-NEXT: ret void
;
@@ -885,10 +881,8 @@ define void @memcpy_byval_escape_after(ptr noalias %P) {
define void @memcpy_immut_escape_after(ptr align 4 noalias %val) {
; CHECK-LABEL: @memcpy_immut_escape_after(
-; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
; CHECK-NEXT: call void @do_something()
-; CHECK-NEXT: call void @f(ptr noalias nocapture readonly align 4 [[VAL1]])
+; CHECK-NEXT: call void @f(ptr noalias nocapture readonly align 4 [[VAL:%.*]])
; CHECK-NEXT: call void @capture(ptr [[VAL]])
; CHECK-NEXT: ret void
;
More information about the llvm-commits
mailing list