[cfe-commits] r136823 - in /cfe/trunk: lib/CodeGen/CGObjC.cpp test/CodeGenObjC/arc.m

John McCall rjmccall at apple.com
Wed Aug 3 15:24:24 PDT 2011


Author: rjmccall
Date: Wed Aug  3 17:24:24 2011
New Revision: 136823

URL: http://llvm.org/viewvc/llvm-project?rev=136823&view=rev
Log:
Use the general conditional-cleanup framework instead of rolling our
own, incorrectly, for releasing objects at the end of a full-expression.


Modified:
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/test/CodeGenObjC/arc.m

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=136823&r1=136822&r2=136823&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Wed Aug  3 17:24:24 2011
@@ -1273,33 +1273,11 @@
 
 namespace {
   struct CallObjCRelease : EHScopeStack::Cleanup {
-    CallObjCRelease(QualType type, llvm::Value *ptr, llvm::Value *condition)
-      : type(type), ptr(ptr), condition(condition) {}
-    QualType type;
-    llvm::Value *ptr;
-    llvm::Value *condition;
+    CallObjCRelease(llvm::Value *object) : object(object) {}
+    llvm::Value *object;
 
     void Emit(CodeGenFunction &CGF, Flags flags) {
-      llvm::Value *object;
-
-      // If we're in a conditional branch, we had to stash away in an
-      // alloca the pointer to be released.
-      llvm::BasicBlock *cont = 0;
-      if (condition) {
-        llvm::BasicBlock *release = CGF.createBasicBlock("release.yes");
-        cont = CGF.createBasicBlock("release.cont");
-
-        llvm::Value *cond = CGF.Builder.CreateLoad(condition);
-        CGF.Builder.CreateCondBr(cond, release, cont);
-        CGF.EmitBlock(release);
-        object = CGF.Builder.CreateLoad(ptr);
-      } else {
-        object = ptr;
-      }
-
       CGF.EmitARCRelease(object, /*precise*/ true);
-
-      if (cont) CGF.EmitBlock(cont);
     }
   };
 }
@@ -1309,27 +1287,8 @@
 llvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
                                                     llvm::Value *object) {
   // If we're in a conditional branch, we need to make the cleanup
-  // conditional.  FIXME: this really needs to be supported by the
-  // environment.
-  llvm::AllocaInst *cond;
-  llvm::Value *ptr;
-  if (isInConditionalBranch()) {
-    cond = CreateTempAlloca(Builder.getInt1Ty(), "release.cond");
-    ptr = CreateTempAlloca(object->getType(), "release.value");
-
-    // The alloca is false until we get here.
-    // FIXME: er. doesn't this need to be set at the start of the condition?
-    InitTempAlloca(cond, Builder.getFalse());
-
-    // Then it turns true.
-    Builder.CreateStore(Builder.getTrue(), cond);
-    Builder.CreateStore(object, ptr);
-  } else {
-    cond = 0;
-    ptr = object;
-  }
-
-  EHStack.pushCleanup<CallObjCRelease>(getARCCleanupKind(), type, ptr, cond);
+  // conditional.
+  pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object);
   return object;
 }
 

Modified: cfe/trunk/test/CodeGenObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=136823&r1=136822&r2=136823&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc.m Wed Aug  3 17:24:24 2011
@@ -578,18 +578,18 @@
   // CHECK:      define void @test22(
   // CHECK:      [[COND:%.*]] = alloca i8,
   // CHECK-NEXT: [[X:%.*]] = alloca i8*,
-  // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
   // CHECK-NEXT: [[RELVAL:%.*]] = alloca i8*
-  // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
+  // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1
   // CHECK-NEXT: zext
   // CHECK-NEXT: store
   // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]]
   // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
+  // CHECK-NEXT: store i1 false, i1* [[RELCOND]]
   // CHECK-NEXT: br i1 [[T1]],
   // CHECK:      br label
   // CHECK:      [[CALL:%.*]] = call i8* @test22_helper()
-  // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
   // CHECK-NEXT: store i8* [[CALL]], i8** [[RELVAL]]
+  // CHECK-NEXT: store i1 true, i1* [[RELCOND]]
   // CHECK-NEXT: br label
   // CHECK:      [[T0:%.*]] = phi i8* [ null, {{%.*}} ], [ [[CALL]], {{%.*}} ]
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) nounwind
@@ -1790,3 +1790,52 @@
   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
   // CHECK-NEXT: ret void
 }
+
+// rdar://problem/9891815
+void test62(void) {
+  // CHECK:    define void @test62()
+  // CHECK:      [[I:%.*]] = alloca i32, align 4
+  // CHECK-NEXT: [[CLEANUP_VALUE:%.*]] = alloca i8*
+  // CHECK-NEXT: [[CLEANUP_REQUIRED:%.*]] = alloca i1
+  extern id test62_make(void);
+  extern void test62_body(void);
+
+  // CHECK-NEXT: store i32 0, i32* [[I]], align 4
+  // CHECK-NEXT: br label
+
+  // CHECK:      [[T0:%.*]] = load i32* [[I]], align 4
+  // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 20
+  // CHECK-NEXT: br i1 [[T1]],
+
+  for (unsigned i = 0; i != 20; ++i) {
+    // CHECK:      [[T0:%.*]] = load i32* [[I]], align 4
+    // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0
+    // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: br i1 [[T1]],
+    // CHECK:      [[T0:%.*]] = call i8* @test62_make()
+    // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+    // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]]
+    // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null
+    // CHECK-NEXT: br label
+    // CHECK:      [[COND:%.*]] = phi i1 [ false, {{%.*}} ], [ [[T2]], {{%.*}} ]
+    // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_REQUIRED]]
+    // CHECK-NEXT: br i1 [[T0]],
+    // CHECK:      [[T0:%.*]] = load i8** [[CLEANUP_VALUE]]
+    // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+    // CHECK-NEXT: br label
+    // CHECK:      br i1 [[COND]]
+    // CHECK:      call void @test62_body()
+    // CHECK-NEXT: br label
+    // CHECK:      br label
+    if (i != 0 && test62_make() != 0)
+      test62_body();
+  }
+
+  // CHECK:      [[T0:%.*]] = load i32* [[I]], align 4
+  // CHECK-NEXT: [[T1:%.*]] = add i32 [[T0]], 1
+  // CHECK-NEXT: store i32 [[T1]], i32* [[I]]
+  // CHECK-NEXT: br label
+
+  // CHECK:      ret void
+}





More information about the cfe-commits mailing list