aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-01-08 21:19:19 +0000
committerChris Lattner <sabre@nondot.org>2011-01-08 21:19:19 +0000
commitd90a192279c8580c4e80d1ee102d1317ce2aaffa (patch)
tree164ef7aa26f4beef9bc64e8f7c5adb4d217b1c92 /lib/Transforms
parent9fa11e94b5a7709cf05396420b3b3eaad6fb8e37 (diff)
Merge memsets followed by neighboring memsets and other stores into
larger memsets. Among other things, this fixes rdar://8760394 and allows us to handle "Example 2" from http://blog.regehr.org/archives/320, compiling it into a single 4096-byte memset: _mad_synth_mute: ## @mad_synth_mute ## BB#0: ## %entry pushq %rax movl $4096, %esi ## imm = 0x1000 callq ___bzero popq %rax ret git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123089 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index c2844375c4..4210f0d9b7 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -322,6 +322,7 @@ namespace {
// Helper fuctions
bool processStore(StoreInst *SI, BasicBlock::iterator &BBI);
+ bool processMemSet(MemSetInst *SI, BasicBlock::iterator &BBI);
bool processMemCpy(MemCpyInst *M);
bool processMemMove(MemMoveInst *M);
bool performCallSlotOptzn(Instruction *cpy, Value *cpyDst, Value *cpySrc,
@@ -511,6 +512,17 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
return false;
}
+bool MemCpyOpt::processMemSet(MemSetInst *MSI, BasicBlock::iterator &BBI) {
+ // See if there is another memset or store neighboring this memset which
+ // allows us to widen out the memset to do a single larger store.
+ if (Instruction *I = tryMergingIntoMemset(MSI, MSI->getDest(),
+ MSI->getValue())) {
+ BBI = I; // Don't invalidate iterator.
+ return true;
+ }
+ return false;
+}
+
/// performCallSlotOptzn - takes a memcpy and a call that it depends on,
/// and checks for the possibility of a call slot optimization by having
@@ -775,6 +787,7 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) {
return true;
}
}
+
return false;
}
@@ -884,11 +897,13 @@ bool MemCpyOpt::iterateOnFunction(Function &F) {
if (StoreInst *SI = dyn_cast<StoreInst>(I))
MadeChange |= processStore(SI, BI);
- else if (MemCpyInst *M = dyn_cast<MemCpyInst>(I)) {
+ else if (MemSetInst *M = dyn_cast<MemSetInst>(I))
+ RepeatInstruction = processMemSet(M, BI);
+ else if (MemCpyInst *M = dyn_cast<MemCpyInst>(I))
RepeatInstruction = processMemCpy(M);
- } else if (MemMoveInst *M = dyn_cast<MemMoveInst>(I)) {
+ else if (MemMoveInst *M = dyn_cast<MemMoveInst>(I))
RepeatInstruction = processMemMove(M);
- } else if (CallSite CS = (Value*)I) {
+ else if (CallSite CS = (Value*)I) {
for (unsigned i = 0, e = CS.arg_size(); i != e; ++i)
if (CS.paramHasAttr(i+1, Attribute::ByVal))
MadeChange |= processByValArgument(CS, i);