Skip to content

Commit 015e077

Browse files
committed
remove walk
1 parent feaa5fa commit 015e077

File tree

2 files changed

+41
-65
lines changed

2 files changed

+41
-65
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,80 +1366,56 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
13661366

13671367
/// Determine whether the pointer V had only undefined content (due to Def) up
13681368
/// to the given Size, either because it was freshly alloca'd or started its
1369-
/// lifetime by walking the MSSA graph.
1370-
static bool hadUndefContentsBefore(MemorySSA *MSSA, BatchAAResults &BAA,
1371-
Value *V, MemoryAccess *Clobber,
1372-
MemoryLocation Loc, Value *Size) {
1373-
Value *VBase = getUnderlyingObject(V);
1374-
while (1) {
1375-
Clobber = MSSA->getWalker()->getClobberingMemoryAccess(Clobber, Loc, BAA);
1376-
MemoryDef *Def = dyn_cast<MemoryDef>(Clobber);
1377-
if (!Def)
1378-
return false;
1379-
1380-
if (MSSA->isLiveOnEntryDef(Def))
1381-
return isa<AllocaInst>(VBase);
1382-
1383-
if (auto *II = dyn_cast_or_null<IntrinsicInst>(Def->getMemoryInst())) {
1384-
if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
1385-
auto *LTSize = cast<ConstantInt>(II->getArgOperand(0));
1386-
1387-
// Check if the SSA Walk ended early due to heuristics or actually
1388-
// reached a lifetime instruction for this pointer.
1389-
Value *IIBase = getUnderlyingObject(II->getArgOperand(1));
1390-
if (VBase != IIBase)
1391-
return false;
1369+
/// lifetime.
1370+
static bool hasUndefContents(MemorySSA *MSSA, BatchAAResults &AA, Value *V,
1371+
MemoryDef *Def, Value *Size) {
1372+
if (MSSA->isLiveOnEntryDef(Def))
1373+
return isa<AllocaInst>(getUnderlyingObject(V));
1374+
1375+
if (auto *II = dyn_cast_or_null<IntrinsicInst>(Def->getMemoryInst())) {
1376+
if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
1377+
auto *LTSize = cast<ConstantInt>(II->getArgOperand(0));
1378+
1379+
if (auto *CSize = dyn_cast<ConstantInt>(Size)) {
1380+
if (AA.isMustAlias(V, II->getArgOperand(1)) &&
1381+
LTSize->getZExtValue() >= CSize->getZExtValue())
1382+
return true;
1383+
}
13921384

1393-
if (Size)
1394-
if (auto CSize = dyn_cast<ConstantInt>(Size))
1395-
if (BAA.isMustAlias(V, II->getArgOperand(1)) &&
1396-
LTSize->getZExtValue() >= CSize->getZExtValue())
1385+
// If the lifetime.start covers a whole alloca (as it almost always
1386+
// does) and we're querying a pointer based on that alloca, then we know
1387+
// the memory is definitely undef, regardless of how exactly we alias.
1388+
// The size also doesn't matter, as an out-of-bounds access would be UB.
1389+
if (auto *Alloca = dyn_cast<AllocaInst>(getUnderlyingObject(V))) {
1390+
if (getUnderlyingObject(II->getArgOperand(1)) == Alloca) {
1391+
const DataLayout &DL = Alloca->getDataLayout();
1392+
if (std::optional<TypeSize> AllocaSize =
1393+
Alloca->getAllocationSize(DL))
1394+
if (*AllocaSize == LTSize->getValue())
13971395
return true;
1398-
1399-
// If the lifetime.start covers a whole alloca (as it almost always
1400-
// does) and we're querying a pointer based on that alloca, then we know
1401-
// the memory is definitely undef, regardless of how exactly we alias.
1402-
// The size also doesn't matter, as an out-of-bounds access would be UB.
1403-
if (auto *Alloca = dyn_cast<AllocaInst>(VBase)) {
1404-
if (IIBase == Alloca) {
1405-
const DataLayout &DL = Alloca->getDataLayout();
1406-
if (std::optional<TypeSize> AllocaSize =
1407-
Alloca->getAllocationSize(DL))
1408-
if (*AllocaSize == LTSize->getValue())
1409-
return true;
1410-
}
14111396
}
1412-
Clobber = Def->getDefiningAccess();
1413-
continue;
1414-
} else if (II->getIntrinsicID() == Intrinsic::lifetime_end) {
1415-
// Check if the SSA Walk ended early due to heuristics or actually
1416-
// reached a lifetime instruction for this pointer.
1417-
Value *IIBase = getUnderlyingObject(II->getArgOperand(1));
1418-
if (VBase != IIBase)
1419-
return false;
1420-
Clobber = Def->getDefiningAccess();
1421-
continue;
14221397
}
14231398
}
1424-
1425-
return false;
14261399
}
1400+
1401+
return false;
14271402
}
14281403

14291404
// If the memcpy is larger than the previous, but the memory was undef prior to
14301405
// that, we can just ignore the tail. Technically we're only interested in the
14311406
// bytes from 0..MemSrcOffset and MemSrcLength+MemSrcOffset..CopySize here, but
1432-
// as we can't easily represent this location (hadUndefContentsBefore uses
1433-
// mustAlias which cannot deal with offsets), we use the full 0..CopySize range.
1407+
// as we can't easily represent this location (hasUndefContents uses mustAlias
1408+
// which cannot deal with offsets), we use the full 0..CopySize range.
14341409
static bool overreadUndefContents(MemorySSA *MSSA, MemCpyInst *MemCpy,
14351410
MemIntrinsic *MemSrc, BatchAAResults &BAA) {
14361411
Value *CopySize = MemCpy->getLength();
1437-
MemoryLocation LoadLoc = MemoryLocation::getForSource(MemCpy);
1438-
MemoryAccess *MemSrcAccess =
1439-
MSSA->getMemoryAccess(MemSrc)->getDefiningAccess();
1440-
if (hadUndefContentsBefore(MSSA, BAA, MemCpy->getSource(), MemSrcAccess,
1441-
LoadLoc, CopySize))
1442-
return true;
1412+
MemoryLocation MemCpyLoc = MemoryLocation::getForSource(MemCpy);
1413+
MemoryUseOrDef *MemSrcAccess = MSSA->getMemoryAccess(MemSrc);
1414+
MemoryAccess *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(
1415+
MemSrcAccess->getDefiningAccess(), MemCpyLoc, BAA);
1416+
if (auto *MD = dyn_cast<MemoryDef>(Clobber))
1417+
if (hasUndefContents(MSSA, BAA, MemCpy->getSource(), MD, CopySize))
1418+
return true;
14431419
return false;
14441420
}
14451421

@@ -1805,9 +1781,8 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
18051781
if (processMemSetMemCpyDependence(M, MDep, BAA))
18061782
return true;
18071783

1808-
MemoryLocation SrcLoc = MemoryLocation::getForSource(M);
1809-
MemoryAccess *SrcClobber =
1810-
MSSA->getWalker()->getClobberingMemoryAccess(AnyClobber, SrcLoc, BAA);
1784+
MemoryAccess *SrcClobber = MSSA->getWalker()->getClobberingMemoryAccess(
1785+
AnyClobber, MemoryLocation::getForSource(M), BAA);
18111786

18121787
// There are five possible optimizations we can do for memcpy:
18131788
// a) memcpy-memcpy xform which exposes redundance for DSE.
@@ -1847,8 +1822,7 @@ bool MemCpyOptPass::processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI) {
18471822
}
18481823
}
18491824

1850-
if (hadUndefContentsBefore(MSSA, BAA, M->getSource(), AnyClobber, SrcLoc,
1851-
M->getLength())) {
1825+
if (hasUndefContents(MSSA, BAA, M->getSource(), MD, M->getLength())) {
18521826
LLVM_DEBUG(dbgs() << "Removed memcpy from undef\n");
18531827
eraseInstruction(M);
18541828
++NumMemCpyInstr;

llvm/test/Transforms/MemCpyOpt/memcpy-undef.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ define void @test_lifetime_partial_alias_3(ptr noalias %dst) {
9696
; CHECK-NEXT: [[A:%.*]] = alloca [16 x i8], align 1
9797
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 12, ptr [[A]])
9898
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 8
99+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[GEP]], i64 4, i1 false)
99100
; CHECK-NEXT: ret void
100101
;
101102
%a = alloca [16 x i8]
@@ -111,6 +112,7 @@ define void @test_lifetime_partial_alias_4(ptr noalias %dst) {
111112
; CHECK-NEXT: [[A:%.*]] = alloca [16 x i8], align 1
112113
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 12, ptr [[A]])
113114
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 8
115+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[GEP]], i64 8, i1 false)
114116
; CHECK-NEXT: ret void
115117
;
116118
%a = alloca [16 x i8]

0 commit comments

Comments
 (0)