forked from OSchip/llvm-project
[DSE] Support redundant stores eliminated by memset.
This patch adds support to remove stores that write the same value as earlier memesets. It uses isOverwrite to check that a memset completely overwrites a later store. The candidate store must store the same bytewise value as the byte stored by the memset. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D112321
This commit is contained in:
parent
e6b323379e
commit
274a9b0f0b
|
@ -1955,10 +1955,32 @@ struct DSEState {
|
|||
auto *UpperDef = dyn_cast<MemoryDef>(Def->getDefiningAccess());
|
||||
if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef))
|
||||
continue;
|
||||
auto *DefInst = Def->getMemoryInst();
|
||||
auto *UpperInst = UpperDef->getMemoryInst();
|
||||
|
||||
Instruction *DefInst = Def->getMemoryInst();
|
||||
Instruction *UpperInst = UpperDef->getMemoryInst();
|
||||
auto IsRedundantStore = [this, DefInst,
|
||||
UpperInst](MemoryLocation UpperLoc) {
|
||||
if (DefInst->isIdenticalTo(UpperInst))
|
||||
return true;
|
||||
if (auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
|
||||
if (auto *SI = dyn_cast<StoreInst>(DefInst)) {
|
||||
auto MaybeDefLoc = getLocForWriteEx(DefInst);
|
||||
if (!MaybeDefLoc)
|
||||
return false;
|
||||
int64_t InstWriteOffset = 0;
|
||||
int64_t DepWriteOffset = 0;
|
||||
auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc,
|
||||
InstWriteOffset, DepWriteOffset);
|
||||
Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL);
|
||||
return StoredByte && StoredByte == MemSetI->getOperand(1) &&
|
||||
OR == OW_Complete;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto MaybeUpperLoc = getLocForWriteEx(UpperInst);
|
||||
if (!MaybeUpperLoc || !DefInst->isIdenticalTo(UpperInst) ||
|
||||
if (!MaybeUpperLoc || !IsRedundantStore(*MaybeUpperLoc) ||
|
||||
isReadClobber(*MaybeUpperLoc, DefInst))
|
||||
continue;
|
||||
LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *DefInst
|
||||
|
|
|
@ -403,8 +403,6 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
|||
define void @test12_memset_simple(i8* %ptr) {
|
||||
; CHECK-LABEL: @test12_memset_simple(
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
|
||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
||||
; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)
|
||||
|
|
Loading…
Reference in New Issue