summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp66
1 files changed, 52 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index a9c2da8befb..7f6b2966369 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -476,12 +476,10 @@ namespace {
: Addr(addr), Size(size) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
- llvm::Value *castAddr = CGF.Builder.CreateBitCast(Addr, CGF.Int8PtrTy);
- CGF.Builder.CreateCall2(CGF.CGM.getLLVMLifetimeEndFn(),
- Size, castAddr)
- ->setDoesNotThrow();
+ CGF.EmitLifetimeEnd(Size, Addr);
}
};
+
}
/// EmitAutoVarWithLifetime - Does the setup required for an automatic
@@ -800,8 +798,7 @@ static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init,
}
/// Should we use the LLVM lifetime intrinsics for the given local variable?
-static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
- unsigned Size) {
+static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, uint64_t Size) {
// For now, only in optimized builds.
if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
return false;
@@ -813,7 +810,6 @@ static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
return Size > SizeThreshold;
}
-
/// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
/// variable declaration with auto, register, or no storage class specifier.
/// These turn into simple stack objects, or GlobalValues depending on target.
@@ -823,6 +819,27 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
EmitAutoVarCleanups(emission);
}
+/// Emit a lifetime.begin marker if some criteria are satisfied.
+/// \return a pointer to the temporary size Value if a marker was emitted, null
+/// otherwise
+llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
+ llvm::Value *Addr) {
+ if (!shouldUseLifetimeMarkers(*this, Size))
+ return nullptr;
+
+ llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
+ llvm::Value *CastAddr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), SizeV, CastAddr)
+ ->setDoesNotThrow();
+ return SizeV;
+}
+
+void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
+ llvm::Value *CastAddr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Builder.CreateCall2(CGM.getLLVMLifetimeEndFn(), Size, CastAddr)
+ ->setDoesNotThrow();
+}
+
/// EmitAutoVarAlloca - Emit the alloca and debug information for a
/// local variable. Does not emit initialization or destruction.
CodeGenFunction::AutoVarEmission
@@ -918,13 +935,8 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// Emit a lifetime intrinsic if meaningful. There's no point
// in doing this if we don't have a valid insertion point (?).
uint64_t size = CGM.getDataLayout().getTypeAllocSize(LTy);
- if (HaveInsertPoint() && shouldUseLifetimeMarkers(*this, D, size)) {
- llvm::Value *sizeV = llvm::ConstantInt::get(Int64Ty, size);
-
- emission.SizeForLifetimeMarkers = sizeV;
- llvm::Value *castAddr = Builder.CreateBitCast(Alloc, Int8PtrTy);
- Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), sizeV, castAddr)
- ->setDoesNotThrow();
+ if (HaveInsertPoint() && EmitLifetimeStart(size, Alloc)) {
+ emission.SizeForLifetimeMarkers = llvm::ConstantInt::get(Int64Ty, size);
} else {
assert(!emission.useLifetimeMarkers());
}
@@ -1366,6 +1378,32 @@ void CodeGenFunction::pushLifetimeExtendedDestroy(
cleanupKind, addr, type, destroyer, useEHCleanupForArray);
}
+void
+CodeGenFunction::pushLifetimeEndMarker(StorageDuration SD,
+ llvm::Value *ReferenceTemporary,
+ llvm::Value *SizeForLifeTimeMarkers) {
+ // SizeForLifeTimeMarkers is null in case no corresponding
+ // @llvm.lifetime.start was emitted: there is nothing to do then.
+ if (!SizeForLifeTimeMarkers)
+ return;
+
+ switch (SD) {
+ case SD_FullExpression:
+ pushFullExprCleanup<CallLifetimeEnd>(NormalAndEHCleanup, ReferenceTemporary,
+ SizeForLifeTimeMarkers);
+ return;
+ case SD_Automatic:
+ EHStack.pushCleanup<CallLifetimeEnd>(static_cast<CleanupKind>(EHCleanup),
+ ReferenceTemporary,
+ SizeForLifeTimeMarkers);
+ pushCleanupAfterFullExpr<CallLifetimeEnd>(
+ NormalAndEHCleanup, ReferenceTemporary, SizeForLifeTimeMarkers);
+ return;
+ default:
+ llvm_unreachable("unexpected storage duration for Lifetime markers");
+ }
+}
+
/// emitDestroy - Immediately perform the destruction of the given
/// object.
///
OpenPOWER on IntegriCloud