diff options
author | Arnaud A. de Grandmaison <arnaud.degrandmaison@arm.com> | 2014-07-21 18:54:21 +0000 |
---|---|---|
committer | Arnaud A. de Grandmaison <arnaud.degrandmaison@arm.com> | 2014-07-21 18:54:21 +0000 |
commit | 17a83cf4b6dbba6ab6e96608ecf77c8c87019f3f (patch) | |
tree | 824f2e20aa824f2b17a9f10cd5eadf030a7521b2 /clang/lib/CodeGen/CGExpr.cpp | |
parent | 0fb2f5d0f954d51df5a3f7414a8cfb9ad19fa4e1 (diff) | |
download | bcm5719-llvm-17a83cf4b6dbba6ab6e96608ecf77c8c87019f3f.tar.gz bcm5719-llvm-17a83cf4b6dbba6ab6e96608ecf77c8c87019f3f.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.
llvm-svn: 213576
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 512b323ba10..2c9c2f130e8 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -353,6 +353,17 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr( // Create and initialize the reference temporary. llvm::Value *Object = createReferenceTemporary(*this, M, E); + + uint64_t size = + CGM.getDataLayout().getTypeStoreSize(ConvertTypeForMem(E->getType())); + llvm::Value *sizeV = nullptr; + llvm::AllocaInst *Alloca = dyn_cast<llvm::AllocaInst>(Object); + bool useLifetimeMarkers = Alloca && shouldUseLifetimeMarkers(size); + if (useLifetimeMarkers) { + sizeV = llvm::ConstantInt::get(Int64Ty, size); + EmitLifetimeStart(sizeV, Object); + } + 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,6 +374,20 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr( } else { EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true); } + + if (useLifetimeMarkers) + switch (M->getStorageDuration()) { + case SD_FullExpression: + EHStack.pushCleanup<CallLifetimeEnd>(NormalAndEHCleanup, Object, sizeV); + break; + case SD_Automatic: + pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalAndEHCleanup, Object, + sizeV); + break; + default: + llvm_unreachable("unexpected storage duration for Lifetime markers"); + } + pushTemporaryCleanup(*this, M, E, Object); // Perform derived-to-base casts and/or field accesses, to get from the |