Skip to content

Commit f5c02dd

Browse files
authored
[MemCpyOpt] Use EarliestEscapeInfo (#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.
1 parent f8373cb commit f5c02dd

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AssumptionCache;
2626
class CallBase;
2727
class CallInst;
2828
class DominatorTree;
29+
class EarliestEscapeInfo;
2930
class Function;
3031
class Instruction;
3132
class LoadInst;
@@ -48,6 +49,7 @@ class MemCpyOptPass : public PassInfoMixin<MemCpyOptPass> {
4849
PostDominatorTree *PDT = nullptr;
4950
MemorySSA *MSSA = nullptr;
5051
MemorySSAUpdater *MSSAU = nullptr;
52+
EarliestEscapeInfo *EEI = nullptr;
5153

5254
public:
5355
MemCpyOptPass() = default;

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
284284

285285
void MemCpyOptPass::eraseInstruction(Instruction *I) {
286286
MSSAU->removeMemoryAccess(I);
287+
EEI->removeInstruction(I);
287288
I->eraseFromParent();
288289
}
289290

@@ -638,7 +639,7 @@ bool MemCpyOptPass::processStoreOfLoad(StoreInst *SI, LoadInst *LI,
638639
if (!LI->isSimple() || !LI->hasOneUse() || LI->getParent() != SI->getParent())
639640
return false;
640641

641-
BatchAAResults BAA(*AA);
642+
BatchAAResults BAA(*AA, EEI);
642643
auto *T = LI->getType();
643644
// Don't introduce calls to memcpy/memmove intrinsics out of thin air if
644645
// the corresponding libcalls are not available.
@@ -1147,14 +1148,14 @@ bool MemCpyOptPass::processMemCpyMemCpyDependence(MemCpyInst *M,
11471148
IRBuilder<> Builder(M);
11481149
auto *CopySource = MDep->getSource();
11491150
Instruction *NewCopySource = nullptr;
1150-
auto CleanupOnRet = llvm::make_scope_exit([&NewCopySource] {
1151+
auto CleanupOnRet = llvm::make_scope_exit([&] {
11511152
if (NewCopySource && NewCopySource->use_empty())
11521153
// Safety: It's safe here because we will only allocate more instructions
11531154
// after finishing all BatchAA queries, but we have to be careful if we
11541155
// want to do something like this in another place. Then we'd probably
11551156
// have to delay instruction removal until all transforms on an
11561157
// instruction finished.
1157-
NewCopySource->eraseFromParent();
1158+
eraseInstruction(NewCopySource);
11581159
});
11591160
MaybeAlign CopySourceAlign = MDep->getSourceAlign();
11601161
// We just need to calculate the actual size of the copy.
@@ -1751,7 +1752,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
17511752
return true;
17521753
}
17531754

1754-
BatchAAResults BAA(*AA);
1755+
BatchAAResults BAA(*AA, EEI);
17551756
// FIXME: Not using getClobberingMemoryAccess() here due to PR54682.
17561757
MemoryAccess *AnyClobber = MA->getDefiningAccess();
17571758
MemoryLocation DestLoc = MemoryLocation::getForDest(M);
@@ -1876,7 +1877,7 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
18761877
if (!CallAccess)
18771878
return false;
18781879
MemCpyInst *MDep = nullptr;
1879-
BatchAAResults BAA(*AA);
1880+
BatchAAResults BAA(*AA, EEI);
18801881
MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
18811882
CallAccess->getDefiningAccess(), Loc, BAA);
18821883
if (auto *MD = dyn_cast<MemoryDef>(Clobber))
@@ -1949,7 +1950,7 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) {
19491950
/// 4. The memcpy src is not modified during the call. (ModRef check shows no
19501951
/// Mod.)
19511952
bool MemCpyOptPass::processImmutArgument(CallBase &CB, unsigned ArgNo) {
1952-
BatchAAResults BAA(*AA);
1953+
BatchAAResults BAA(*AA, EEI);
19531954
Value *ImmutArg = CB.getArgOperand(ArgNo);
19541955

19551956
// 1. Ensure passed argument is immutable during call.
@@ -2117,6 +2118,8 @@ bool MemCpyOptPass::runImpl(Function &F, TargetLibraryInfo *TLI_,
21172118
MSSA = MSSA_;
21182119
MemorySSAUpdater MSSAU_(MSSA_);
21192120
MSSAU = &MSSAU_;
2121+
EarliestEscapeInfo EEI_(*DT);
2122+
EEI = &EEI_;
21202123

21212124
while (true) {
21222125
if (!iterateOnFunction(F))

llvm/test/Transforms/MemCpyOpt/memcpy.ll

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ define void @memcpy_memcpy_escape_after1(ptr noalias %P, ptr noalias %Q) {
837837
; CHECK-NEXT: [[MEMTMP:%.*]] = alloca [32 x i8], align 16
838838
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[MEMTMP]], ptr align 16 [[P:%.*]], i32 32, i1 false)
839839
; CHECK-NEXT: call void @do_something()
840-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[MEMTMP]], i32 32, i1 false)
840+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[P]], i32 32, i1 false)
841841
; CHECK-NEXT: call void @capture(ptr [[MEMTMP]])
842842
; CHECK-NEXT: ret void
843843
;
@@ -851,10 +851,8 @@ define void @memcpy_memcpy_escape_after1(ptr noalias %P, ptr noalias %Q) {
851851

852852
define void @memcpy_memcpy_escape_after2(ptr noalias %P, ptr noalias %Q) {
853853
; CHECK-LABEL: @memcpy_memcpy_escape_after2(
854-
; CHECK-NEXT: [[MEMTMP:%.*]] = alloca [32 x i8], align 16
855-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[MEMTMP]], ptr align 16 [[P:%.*]], i32 32, i1 false)
856854
; CHECK-NEXT: call void @do_something()
857-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[MEMTMP]], i32 32, i1 false)
855+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 16 [[Q:%.*]], ptr align 16 [[P:%.*]], i32 32, i1 false)
858856
; CHECK-NEXT: call void @capture(ptr [[P]])
859857
; CHECK-NEXT: ret void
860858
;
@@ -868,10 +866,8 @@ define void @memcpy_memcpy_escape_after2(ptr noalias %P, ptr noalias %Q) {
868866

869867
define void @memcpy_byval_escape_after(ptr noalias %P) {
870868
; CHECK-LABEL: @memcpy_byval_escape_after(
871-
; CHECK-NEXT: [[A:%.*]] = alloca [8 x i8], align 1
872-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[A]], ptr align 4 [[P:%.*]], i64 8, i1 false)
873869
; CHECK-NEXT: call void @do_something()
874-
; CHECK-NEXT: call void @test4a(ptr byval(i8) align 1 [[A]])
870+
; CHECK-NEXT: call void @test4a(ptr byval(i8) align 1 [[P:%.*]])
875871
; CHECK-NEXT: call void @capture(ptr [[P]])
876872
; CHECK-NEXT: ret void
877873
;
@@ -885,10 +881,8 @@ define void @memcpy_byval_escape_after(ptr noalias %P) {
885881

886882
define void @memcpy_immut_escape_after(ptr align 4 noalias %val) {
887883
; CHECK-LABEL: @memcpy_immut_escape_after(
888-
; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
889-
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
890884
; CHECK-NEXT: call void @do_something()
891-
; CHECK-NEXT: call void @f(ptr noalias nocapture readonly align 4 [[VAL1]])
885+
; CHECK-NEXT: call void @f(ptr noalias nocapture readonly align 4 [[VAL:%.*]])
892886
; CHECK-NEXT: call void @capture(ptr [[VAL]])
893887
; CHECK-NEXT: ret void
894888
;

0 commit comments

Comments
 (0)