diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 9c8882decc6..91f80419304 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -468,6 +468,22 @@ namespace { CGF.EmitCall(FnInfo, CleanupFn, ReturnValueSlot(), Args); } }; + + /// A cleanup to call @llvm.lifetime.end. + class CallLifetimeEnd : public EHScopeStack::Cleanup { + llvm::Value *Addr; + llvm::Value *Size; + public: + CallLifetimeEnd(llvm::Value *addr, llvm::Value *size) + : 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(); + } + }; } /// EmitAutoVarWithLifetime - Does the setup required for an automatic @@ -786,9 +802,10 @@ static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init, } /// Should we use the LLVM lifetime intrinsics for the given local variable? -bool CodeGenFunction::shouldUseLifetimeMarkers(unsigned Size) const { +static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D, + unsigned Size) { // For now, only in optimized builds. - if (CGM.getCodeGenOpts().OptimizationLevel == 0) + if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) return false; // Limit the size of marked objects to 32 bytes. We don't want to increase @@ -798,6 +815,7 @@ bool CodeGenFunction::shouldUseLifetimeMarkers(unsigned Size) const { 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. @@ -807,18 +825,6 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) { EmitAutoVarCleanups(emission); } -void CodeGenFunction::EmitLifetimeStart(llvm::Value *Size, llvm::Value *Addr) { - llvm::Value *castAddr = Builder.CreateBitCast(Addr, Int8PtrTy); - Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), Size, castAddr) - ->setDoesNotThrow(); -} - -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 @@ -914,11 +920,13 @@ 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(size)) { + if (HaveInsertPoint() && shouldUseLifetimeMarkers(*this, D, size)) { llvm::Value *sizeV = llvm::ConstantInt::get(Int64Ty, size); emission.SizeForLifetimeMarkers = sizeV; - EmitLifetimeStart(sizeV, Alloc); + llvm::Value *castAddr = Builder.CreateBitCast(Alloc, Int8PtrTy); + Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), sizeV, castAddr) + ->setDoesNotThrow(); } else { assert(!emission.useLifetimeMarkers()); } |