mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 08:29:43 +00:00
Promote aggregate store to memset when possible
Summary: As per title. This will allow the optimizer to pick up on it. Reviewers: craig.topper, spatel, dexonsmith, Prazek, chandlerc, joker.eph, majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D15923 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256969 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e218641673
commit
bb81476a28
@ -627,13 +627,39 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
|
||||
// Ensure that the value being stored is something that can be memset'able a
|
||||
// byte at a time like "0" or "-1" or any width, as well as things like
|
||||
// 0xA0A0A0A0 and 0.0.
|
||||
if (Value *ByteVal = isBytewiseValue(SI->getOperand(0)))
|
||||
auto *V = SI->getOperand(0);
|
||||
if (Value *ByteVal = isBytewiseValue(V)) {
|
||||
if (Instruction *I = tryMergingIntoMemset(SI, SI->getPointerOperand(),
|
||||
ByteVal)) {
|
||||
BBI = I->getIterator(); // Don't invalidate iterator.
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have an aggregate, we try to promote it to memset regardless
|
||||
// of opportunity for merging as it can expose optimization opportunities
|
||||
// in subsequent passes.
|
||||
auto *T = V->getType();
|
||||
if (T->isAggregateType()) {
|
||||
uint64_t Size = DL.getTypeStoreSize(T);
|
||||
unsigned Align = SI->getAlignment();
|
||||
if (!Align)
|
||||
Align = DL.getABITypeAlignment(T);
|
||||
IRBuilder<> Builder(SI);
|
||||
auto *M = Builder.CreateMemSet(SI->getPointerOperand(), ByteVal,
|
||||
Size, Align, SI->isVolatile());
|
||||
|
||||
DEBUG(dbgs() << "Promoting " << *SI << " to " << *M << "\n");
|
||||
|
||||
MD->removeInstruction(SI);
|
||||
SI->eraseFromParent();
|
||||
NumMemSetInfer++;
|
||||
|
||||
// Make sure we do not invalidate the iterator.
|
||||
BBI = M->getIterator();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
target datalayout = "e-i64:64-f80:128-n8:16:32:64"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
%S = type { i8*, i32 }
|
||||
%S = type { i8*, i8, i32 }
|
||||
|
||||
define void @copy(%S* %src, %S* %dst) {
|
||||
; CHECK-LABEL: copy
|
||||
@ -37,8 +37,10 @@ define void @noaliasdst(%S* %src, %S* noalias %dst) {
|
||||
|
||||
define void @destroysrc(%S* %src, %S* %dst) {
|
||||
; CHECK-LABEL: destroysrc
|
||||
; CHECK-NOT: call
|
||||
; CHECK: ret void
|
||||
; CHECK: load %S, %S* %src
|
||||
; CHECK: call void @llvm.memset.p0i8.i64
|
||||
; CHECK-NEXT: store %S %1, %S* %dst
|
||||
; CHECK-NEXT: ret void
|
||||
%1 = load %S, %S* %src
|
||||
store %S zeroinitializer, %S* %src
|
||||
store %S %1, %S* %dst
|
||||
@ -49,7 +51,7 @@ define void @destroynoaliassrc(%S* noalias %src, %S* %dst) {
|
||||
; CHECK-LABEL: destroynoaliassrc
|
||||
; CHECK-NOT: load
|
||||
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
|
||||
; CHECK-NEXT: store %S zeroinitializer, %S* %src
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64
|
||||
; CHECK-NEXT: ret void
|
||||
%1 = load %S, %S* %src
|
||||
store %S zeroinitializer, %S* %src
|
||||
|
Loading…
Reference in New Issue
Block a user