]> granicus.if.org Git - clang/commitdiff
Revert "Emit lifetime.start / lifetime.end markers for unnamed temporary objects."
authorArnaud A. de Grandmaison <arnaud.degrandmaison@arm.com>
Mon, 21 Jul 2014 19:47:02 +0000 (19:47 +0000)
committerArnaud A. de Grandmaison <arnaud.degrandmaison@arm.com>
Mon, 21 Jul 2014 19:47:02 +0000 (19:47 +0000)
This commit did break the sanitizer-x86 bot. Revert it while
investigating.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213579 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/unnamed-object-lifetime.cpp [deleted file]

index 9c8882decc6aec12a4771cfd2e21b0c9666c5cdb..91f804193049eda1f50dcb386de6b2e0f3e36cb9 100644 (file)
@@ -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());
       }
index 2c9c2f130e874995bff46e5ba83096911aa6682a..512b323ba1091be10e21c7092f72dcba67118138 100644 (file)
@@ -353,17 +353,6 @@ 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.
@@ -374,20 +363,6 @@ 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
index cd668e05afeb641279133dbd1e06321e6cad9113..59cc30da42c518fb6e83382557e1b4f297eb5f0e 100644 (file)
@@ -436,23 +436,6 @@ public:
     new (Buffer + sizeof(Header)) T(a0, a1, a2, a3);
   }
 
-  /// \brief Queue a cleanup to be pushed after finishing the current
-  /// full-expression.
-  template <class T, class A0, class A1>
-  void pushCleanupAfterFullExpr(CleanupKind Kind, A0 a0, A1 a1) {
-    assert(!isInConditionalBranch() && "can't defer conditional cleanup");
-
-    LifetimeExtendedCleanupHeader Header = { sizeof(T), Kind };
-
-    size_t OldSize = LifetimeExtendedCleanupStack.size();
-    LifetimeExtendedCleanupStack.resize(
-        LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size);
-
-    char *Buffer = &LifetimeExtendedCleanupStack[OldSize];
-    new (Buffer) LifetimeExtendedCleanupHeader(Header);
-    new (Buffer + sizeof(Header)) T(a0, a1);
-  }
-
   /// Set up the last cleaup that was pushed as a conditional
   /// full-expression cleanup.
   void initFullExprCleanup();
@@ -1007,23 +990,6 @@ private:
   void EmitOpenCLKernelMetadata(const FunctionDecl *FD, 
                                 llvm::Function *Fn);
 
-  /// Should we use the LLVM lifetime intrinsics for a local variable of the
-  /// given size in bytes ?
-  bool shouldUseLifetimeMarkers(unsigned Size) const;
-
-  /// 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 {
-      CGF.EmitLifetimeEnd(Size, Addr);
-    }
-  };
-
 public:
   CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
   ~CodeGenFunction();
@@ -1707,9 +1673,6 @@ public:
   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
                         llvm::Value *Ptr);
 
-  void EmitLifetimeStart(llvm::Value *Size, llvm::Value *Addr);
-  void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
-
   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
 
diff --git a/test/CodeGenCXX/unnamed-object-lifetime.cpp b/test/CodeGenCXX/unnamed-object-lifetime.cpp
deleted file mode 100644 (file)
index c1422bc..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -O1 -fcxx-exceptions -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
-
-// Test lifetime marker generation for unnamed temporary objects.
-
-struct X {
-  X();
-  ~X();
-  char t[33]; // make the class big enough so that lifetime markers get inserted
-};
-
-extern void useX(const X &);
-
-// CHECK-LABEL: define void @_Z6simplev
-// CHECK-EH-LABEL: define void @_Z6simplev
-void simple() {
-  // CHECK: [[ALLOCA:%.*]] = alloca %struct.X
-  // CHECK: [[PTR:%.*]] = getelementptr inbounds %struct.X* [[ALLOCA]], i32 0, i32 0, i32 0
-  // CHECK: call void @llvm.lifetime.start(i64 33, i8* [[PTR]])
-  // CHECK-NEXT: call void @_ZN1XC1Ev
-  // CHECK-NEXT: call void @_Z4useXRK1X
-  // CHECK-NEXT: call void @_ZN1XD1Ev
-  // CHECK-NEXT: call void @llvm.lifetime.end(i64 33, i8* [[PTR]])
-  //
-  // CHECK-EH: [[ALLOCA:%.*]] = alloca %struct.X
-  // CHECK-EH: [[PTR:%.*]] = getelementptr inbounds %struct.X* [[ALLOCA]], i32 0, i32 0, i32 0
-  // CHECK-EH: call void @llvm.lifetime.start(i64 33, i8* [[PTR]])
-  // CHECK-EH-NEXT: call void @_ZN1XC1Ev
-  // CHECK-EH: invoke void @_Z4useXRK1X
-  // CHECK-EH: invoke void @_ZN1XD1Ev
-  // CHECK-EH: call void @llvm.lifetime.end(i64 33, i8* [[PTR]])
-  // CHECK-EH: call void @llvm.lifetime.end(i64 33, i8* [[PTR]])
-  useX(X());
-}
-
-struct Y {
-  Y(){}
-  ~Y(){}
-  char t[34]; // make the class big enough so that lifetime markers get inserted
-};
-
-extern void useY(const Y &);
-
-// Check lifetime markers are inserted, despite Y's trivial constructor & destructor
-// CHECK-LABEL: define void @_Z7trivialv
-// CHECK-EH-LABEL: define void @_Z7trivialv
-void trivial() {
-  // CHECK: [[ALLOCA:%.*]] = alloca %struct.Y
-  // CHECK: [[PTR:%.*]] = getelementptr inbounds %struct.Y* [[ALLOCA]], i32 0, i32 0, i32 0
-  // CHECK: call void @llvm.lifetime.start(i64 34, i8* [[PTR]])
-  // CHECK-NEXT: call void @_Z4useYRK1Y
-  // CHECK-NEXT: call void @llvm.lifetime.end(i64 34, i8* [[PTR]])
-  //
-  // CHECK-EH: [[ALLOCA:%.*]] = alloca %struct.Y
-  // CHECK-EH: [[PTR:%.*]] = getelementptr inbounds %struct.Y* [[ALLOCA]], i32 0, i32 0, i32 0
-  // CHECK-EH: call void @llvm.lifetime.start(i64 34, i8* [[PTR]])
-  // CHECK-EH-NEXT: invoke void @_Z4useYRK1Y
-  // CHECK-EH: call void @llvm.lifetime.end(i64 34, i8* [[PTR]])
-  // CHECK-EH: call void @llvm.lifetime.end(i64 34, i8* [[PTR]])
-  useY(Y());
-}
-
-struct Z {
-  Z();
-  ~Z();
-  char t;
-};
-
-extern void useZ(const Z &);
-
-// Check lifetime markers are not inserted if the unnamed object is too small
-// CHECK-LABEL: define void @_Z8tooSmallv
-// CHECK-EH-LABEL: define void @_Z8tooSmallv
-void tooSmall() {
-  // CHECK-NOT: call void @llvm.lifetime.start
-  // CHECK: call void @_Z4useZRK1Z
-  // CHECK-NOT: call void @llvm.lifetime.end
-  // CHECK: ret
-  //
-  // CHECK-EH-NOT: call void @llvm.lifetime.start
-  // CHECK-EH: invoke void @_Z4useZRK1Z
-  // CHECK-EH-NOT: call void @llvm.lifetime.end
-  // CHECK-EH: ret
-  useZ(Z());
-}
-
-// Check the lifetime are inserted at the right place in their respective scope
-// CHECK-LABEL: define void @_Z6scopesv
-void scopes() {
-  // CHECK: alloca %struct
-  // CHECK: alloca %struct
-  // CHECK: call void @llvm.lifetime.start(i64 33, i8* [[X:%.*]])
-  // CHECK: call void @llvm.lifetime.end(i64 33, i8* [[X]])
-  // CHECK: call void @llvm.lifetime.start(i64 34, i8* [[Y:%.*]])
-  // CHECK: call void @llvm.lifetime.end(i64 34, i8* [[Y]])
-  useX(X());
-  useY(Y());
-}
-
-struct L {
-  L(int);
-  ~L();
-  char t[33];
-};
-
-// Check the lifetime-extended case
-// CHECK-LABEL: define void @_Z16extendedLifetimev
-void extendedLifetime() {
-  extern void useL(const L&);
-
-  // CHECK: [[A:%.*]] = alloca %struct.L
-  // CHECK: [[P:%.*]] = getelementptr inbounds %struct.L* [[A]], i32 0, i32 0, i32 0
-  // CHECK: call void @llvm.lifetime.start(i64 33, i8* [[P]])
-  // CHECK: call void @_ZN1LC1Ei(%struct.L* [[A]], i32 2)
-  // CHECK-NOT: call void @llvm.lifetime.end(i64 33, i8* [[P]])
-  // CHECK: call void @_Z4useLRK1L(%struct.L* dereferenceable(33) [[A]])
-  // CHECK: call void @_ZN1LD1Ev(%struct.L* [[A]])
-  // CHECK-NEXT: call void @llvm.lifetime.end(i64 33, i8* [[P]])
-  //
-  // CHECK-EH: [[A:%.*]] = alloca %struct.L
-  // CHECK-EH: [[P:%.*]] = getelementptr inbounds %struct.L* [[A]], i32 0, i32 0, i32 0
-  // CHECK-EH: call void @llvm.lifetime.start(i64 33, i8* [[P]])
-  // CHECK-EH: call void @_ZN1LC1Ei(%struct.L* [[A]], i32 2)
-  // CHECK-EH-NOT: call void @llvm.lifetime.end(i64 33, i8* [[P]])
-  // CHECK-EH: invoke void @_Z4useLRK1L(%struct.L* dereferenceable(33) [[A]])
-  // CHECK-EH: invoke void @_ZN1LD1Ev(%struct.L* [[A]])
-  // CHECK-EH: call void @llvm.lifetime.end(i64 33, i8* [[P]])
-  // CHECK-EH: invoke void @_ZN1LD1Ev(%struct.L* [[A]])
-  // CHECK-EH: call void @llvm.lifetime.end(i64 33, i8* [[P]])
-  const L &l = 2;
-  useL(l);
-}