summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorArnaud A. de Grandmaison <arnaud.degrandmaison@arm.com>2014-10-02 12:19:51 +0000
committerArnaud A. de Grandmaison <arnaud.degrandmaison@arm.com>2014-10-02 12:19:51 +0000
commit42d314d1ba7fd02da1784c2a2e26e7a91a6ef1b4 (patch)
tree210dca4280865c7a7848760ce67e68e2559eb43e /clang/lib/CodeGen/CGExpr.cpp
parent4ae7f2e839957dbb1f7bc38f524adf6c6d4b416a (diff)
downloadbcm5719-llvm-42d314d1ba7fd02da1784c2a2e26e7a91a6ef1b4.tar.gz
bcm5719-llvm-42d314d1ba7fd02da1784c2a2e26e7a91a6ef1b4.zip
Emit lifetime.start / lifetime.end markers for unnamed temporary objects.
This will give more information to the optimizers so that they can reuse stack slots and reduce stack usage. llvm-svn: 218865
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4fe37546b60..7b26009a65e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -173,9 +173,10 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
llvm_unreachable("bad evaluation kind");
}
-static void
-pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
- const Expr *E, llvm::Value *ReferenceTemporary) {
+static void pushTemporaryCleanup(CodeGenFunction &CGF,
+ const MaterializeTemporaryExpr *M,
+ const Expr *E, llvm::Value *ReferenceTemporary,
+ llvm::Value *SizeForLifeTimeMarkers) {
// Objective-C++ ARC:
// If we are binding a reference to a temporary that has ownership, we
// need to perform retain/release operations on the temporary.
@@ -242,6 +243,10 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
}
}
+ // Call @llvm.lifetime.end marker for the temporary.
+ CGF.pushLifetimeEndMarker(M->getStorageDuration(), ReferenceTemporary,
+ SizeForLifeTimeMarkers);
+
CXXDestructorDecl *ReferenceTemporaryDtor = nullptr;
if (const RecordType *RT =
E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
@@ -296,11 +301,18 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
static llvm::Value *
createReferenceTemporary(CodeGenFunction &CGF,
- const MaterializeTemporaryExpr *M, const Expr *Inner) {
+ const MaterializeTemporaryExpr *M, const Expr *Inner,
+ llvm::Value *&SizeForLifeTimeMarkers) {
+ SizeForLifeTimeMarkers = nullptr;
switch (M->getStorageDuration()) {
case SD_FullExpression:
- case SD_Automatic:
- return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
+ case SD_Automatic: {
+ llvm::Value *RefTemp = CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
+ uint64_t TempSize = CGF.CGM.getDataLayout().getTypeStoreSize(
+ CGF.ConvertTypeForMem(Inner->getType()));
+ SizeForLifeTimeMarkers = CGF.EmitLifetimeStart(TempSize, RefTemp);
+ return RefTemp;
+ }
case SD_Thread:
case SD_Static:
@@ -321,7 +333,8 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
M->getType().getObjCLifetime() != Qualifiers::OCL_None &&
M->getType().getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
// FIXME: Fold this into the general case below.
- llvm::Value *Object = createReferenceTemporary(*this, M, E);
+ llvm::Value *ObjectSize;
+ llvm::Value *Object = createReferenceTemporary(*this, M, E, ObjectSize);
LValue RefTempDst = MakeAddrLValue(Object, M->getType());
if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
@@ -333,7 +346,7 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
- pushTemporaryCleanup(*this, M, E, Object);
+ pushTemporaryCleanup(*this, M, E, Object, ObjectSize);
return RefTempDst;
}
@@ -351,8 +364,10 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
}
}
- // Create and initialize the reference temporary.
- llvm::Value *Object = createReferenceTemporary(*this, M, E);
+ // Create and initialize the reference temporary and get the temporary size
+ llvm::Value *ObjectSize;
+ llvm::Value *Object = createReferenceTemporary(*this, M, E, ObjectSize);
+
if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
// If the temporary is a global and has a constant initializer, we may
// have already initialized it.
@@ -363,7 +378,8 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
} else {
EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
}
- pushTemporaryCleanup(*this, M, E, Object);
+
+ pushTemporaryCleanup(*this, M, E, Object, ObjectSize);
// Perform derived-to-base casts and/or field accesses, to get from the
// temporary object we created (and, potentially, for which we extended
OpenPOWER on IntegriCloud