Revert "Revert r234581, it might have caused a few miscompiles in Chromium."
This reverts commit r234700. It turns out that the lifetime markers
were not the cause of Chromium failing but a bug which was uncovered by
optimizations exposed by the markers.
llvm-svn: 235553
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f1ccb09..29c6315 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
+#include "CGCleanup.h"
#include "CGDebugInfo.h"
#include "CGOpenCLRuntime.h"
#include "CodeGenModule.h"
@@ -516,10 +517,7 @@
: 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);
}
};
}
@@ -840,21 +838,6 @@
canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
}
-/// Should we use the LLVM lifetime intrinsics for the given local variable?
-static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
- unsigned Size) {
- // For now, only in optimized builds.
- if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
- return false;
-
- // Limit the size of marked objects to 32 bytes. We don't want to increase
- // compile time by marking tiny objects.
- unsigned SizeThreshold = 32;
-
- 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.
@@ -864,6 +847,33 @@
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) {
+ // For now, only in optimized builds.
+ if (CGM.getCodeGenOpts().OptimizationLevel == 0)
+ return nullptr;
+
+ llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
+ llvm::Value *Args[] = {
+ SizeV,
+ new llvm::BitCastInst(Addr, Int8PtrTy, "", Builder.GetInsertBlock())};
+ llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeStartFn(), Args,
+ "", Builder.GetInsertBlock());
+ C->setDoesNotThrow();
+ return SizeV;
+}
+
+void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
+ llvm::Value *Args[] = {Size, new llvm::BitCastInst(Addr, Int8PtrTy, "",
+ Builder.GetInsertBlock())};
+ llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeEndFn(), Args,
+ "", Builder.GetInsertBlock());
+ C->setDoesNotThrow();
+}
+
/// EmitAutoVarAlloca - Emit the alloca and debug information for a
/// local variable. Does not emit initialization or destruction.
CodeGenFunction::AutoVarEmission
@@ -959,13 +969,8 @@
// 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()) {
+ emission.SizeForLifetimeMarkers = EmitLifetimeStart(size, Alloc);
} else {
assert(!emission.useLifetimeMarkers());
}
@@ -1311,6 +1316,8 @@
EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup,
emission.getAllocatedAddress(),
emission.getSizeForLifetimeMarkers());
+ EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());
+ cleanup.setLifetimeMarker();
}
// Check the type for a cleanup.