[PATCH] Optionally extend alloca lifetimes to allow for callslot optimization to happen
Björn Steinbrink
bsteinbr at gmail.com
Sun Mar 1 07:49:44 PST 2015
Currently, memcpy callslot optimization doesn't happen if the memcpy's
destination starts its lifetime between the call and the memcpy. We can
make the optimization happen by extending the allocas lifetime to start
before the call, but we must only do that if the callslot optimization
succeeds, because otherwise we might lose some opportunities for stack
slot sharing
http://reviews.llvm.org/D7984
Files:
lib/Transforms/Scalar/MemCpyOptimizer.cpp
test/Transforms/MemCpyOpt/extend-lifetime.ll
Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp
===================================================================
--- lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -884,22 +884,40 @@
// c) memcpy from freshly alloca'd space or space that has just started its
// lifetime copies undefined data, and we can therefore eliminate the
// memcpy in favor of the data that was already at the destination.
- MemDepResult DepInfo = MD->getDependency(M);
+ AliasAnalysis::Location SrcLoc = AliasAnalysis::getLocationForSource(M);
+ MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(SrcLoc, true,
+ M, M->getParent());
+ AliasAnalysis::Location DstLoc = AliasAnalysis::getLocationForDest(M);
+ MemDepResult DstDepInfo = MD->getPointerDependencyFrom(DstLoc, true,
+ M, M->getParent());
+
+ // If the destination just started its lifetime, pretend that the lifetime
+ // start isn't present, try the callslot optimization and if it succeeds,
+ // extend the lifetime accordingly
+ IntrinsicInst *LT = dyn_cast_or_null<IntrinsicInst>(DstDepInfo.getInst());
+ if (LT && LT->getIntrinsicID() != Intrinsic::lifetime_start)
+ LT = nullptr;
+
+ MemDepResult DepInfo = LT ? SrcDepInfo : MD->getDependency(M);
if (DepInfo.isClobber()) {
if (CallInst *C = dyn_cast<CallInst>(DepInfo.getInst())) {
if (performCallSlotOptzn(M, M->getDest(), M->getSource(),
CopySize->getZExtValue(), M->getAlignment(),
C)) {
+ if (LT) {
+ IRBuilder<> Builder(SrcDepInfo.getInst());
+ Builder.CreateLifetimeStart(M->getDest(),
+ cast<ConstantInt>(LT->getArgOperand(0)));
+ MD->removeInstruction(LT);
+ LT->eraseFromParent();
+ }
+
MD->removeInstruction(M);
M->eraseFromParent();
return true;
}
}
}
-
- AliasAnalysis::Location SrcLoc = AliasAnalysis::getLocationForSource(M);
- MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(SrcLoc, true,
- M, M->getParent());
if (SrcDepInfo.isClobber()) {
if (MemCpyInst *MDep = dyn_cast<MemCpyInst>(SrcDepInfo.getInst()))
return processMemCpyMemCpyDependence(M, MDep, CopySize->getZExtValue());
Index: test/Transforms/MemCpyOpt/extend-lifetime.ll
===================================================================
--- /dev/null
+++ test/Transforms/MemCpyOpt/extend-lifetime.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -basicaa -memcpyopt -S | FileCheck %s
+target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+
+declare void @foo([100000 x i32]*)
+
+declare void @llvm.lifetime.start(i64, i8* nocapture)
+declare void @llvm.lifetime.end(i64, i8* nocapture)
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
+
+; Function Attrs: nounwind uwtable
+define void @testfunc() {
+ %src = alloca [100000 x i32], align 4
+ %dst = alloca [100000 x i32], align 4
+ %1 = bitcast [100000 x i32]* %src to i8*
+ call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 400000, i32 4, i1 false)
+ %2 = bitcast [100000 x i32]* %dst to i8*
+ call void @llvm.lifetime.start(i64 400000, i8* %2)
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %1, i64 400000, i32 4, i1 false)
+ call void @foo([100000 x i32]* %dst)
+ call void @llvm.lifetime.end(i64 400000, i8* %2)
+ ret void
+; CHECK-LABEL: @testfunc
+; CHECK-NOT: memcpy
+; CHECK: lifetime.start
+; CHECK: memset
+}
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7984.20959.patch
Type: text/x-patch
Size: 3793 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150301/a4e08a71/attachment.bin>
More information about the llvm-commits
mailing list