r250916 - In ARC, peephole the initialization of a __weak variable with

John McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 21 11:06:32 PDT 2015


Author: rjmccall
Date: Wed Oct 21 13:06:31 2015
New Revision: 250916

URL: http://llvm.org/viewvc/llvm-project?rev=250916&view=rev
Log:
In ARC, peephole the initialization of a __weak variable with
a value loaded from a __weak variable into a call to
objc_copyWeak or objc_moveWeak.

Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/test/CodeGenObjC/arc-blocks.m
    cfe/trunk/test/CodeGenObjC/arc-foreach.m
    cfe/trunk/test/CodeGenObjCXX/arc.mm

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=250916&r1=250915&r2=250916&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Oct 21 13:06:31 2015
@@ -597,6 +597,47 @@ static bool isAccessedBy(const ValueDecl
   return isAccessedBy(*var, e);
 }
 
+static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
+                                   const LValue &destLV, const Expr *init) {
+  while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) {
+    switch (castExpr->getCastKind()) {
+    // Look through casts that don't require representation changes.
+    case CK_NoOp:
+    case CK_BitCast:
+    case CK_BlockPointerToObjCPointerCast:
+      break;
+
+    // If we find an l-value to r-value cast from a __weak variable,
+    // emit this operation as a copy or move.
+    case CK_LValueToRValue: {
+      const Expr *srcExpr = castExpr->getSubExpr();
+      if (srcExpr->getType().getObjCLifetime() != Qualifiers::OCL_Weak)
+        return false;
+
+      // Emit the source l-value.
+      LValue srcLV = CGF.EmitLValue(srcExpr);
+
+      // If it was an l-value, use objc_copyWeak.
+      if (srcExpr->getValueKind() == VK_LValue) {
+        CGF.EmitARCCopyWeak(destLV.getAddress(), srcLV.getAddress());
+      } else {
+        assert(srcExpr->getValueKind() == VK_XValue);
+        CGF.EmitARCMoveWeak(destLV.getAddress(), srcLV.getAddress());
+      }
+      return true;
+    }
+
+    // Stop at anything else.
+    default:
+      return false;
+    }
+
+    init = castExpr->getSubExpr();
+    continue;
+  }
+  return false;
+}
+
 static void drillIntoBlockVariable(CodeGenFunction &CGF,
                                    LValue &lvalue,
                                    const VarDecl *var) {
@@ -673,6 +714,12 @@ void CodeGenFunction::EmitScalarInit(con
   }
 
   case Qualifiers::OCL_Weak: {
+    // If it's not accessed by the initializer, try to emit the
+    // initialization with a copy or move.
+    if (!accessedByInit && tryEmitARCCopyWeakInit(*this, lvalue, init)) {
+      return;
+    }
+
     // No way to optimize a producing initializer into this.  It's not
     // worth optimizing for, because the value will immediately
     // disappear in the common case.

Modified: cfe/trunk/test/CodeGenObjC/arc-blocks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=250916&r1=250915&r2=250916&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-blocks.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-blocks.m Wed Oct 21 13:06:31 2015
@@ -263,8 +263,7 @@ void test7(void) {
   // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
   // CHECK:      store i32 -1040187392,
   // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[VAR]])
-  // CHECK-NEXT: call i8* @objc_initWeak(i8** [[SLOT]], i8* [[T0]])
+  // CHECK-NEXT: call void @objc_copyWeak(i8** [[SLOT]], i8** [[VAR]])
   // CHECK:      call void @test7_helper(
   // CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}})
   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])

Modified: cfe/trunk/test/CodeGenObjC/arc-foreach.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-foreach.m?rev=250916&r1=250915&r2=250916&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-foreach.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-foreach.m Wed Oct 21 13:06:31 2015
@@ -110,9 +110,7 @@ void test1(NSArray *array) {
 
 // CHECK-LP64:      [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
 // CHECK-LP64:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_loadWeakRetained(i8** [[X]])
-// CHECK-LP64-NEXT: call i8* @objc_initWeak(i8** [[T0]], i8* [[T1]])
-// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]]) 
+// CHECK-LP64-NEXT: call void @objc_copyWeak(i8** [[T0]], i8** [[X]])
 // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
 // CHECK-LP64: call void @use_block
 // CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[D0]])

Modified: cfe/trunk/test/CodeGenObjCXX/arc.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc.mm?rev=250916&r1=250915&r2=250916&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc.mm Wed Oct 21 13:06:31 2015
@@ -324,3 +324,13 @@ template void test40_helper<int>();
 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[TEMP]]
 // CHECK-NEXT: call i8* @objc_retain(i8* [[T0]])
 
+// Check that moves out of __weak variables are compiled to use objc_moveWeak.
+void test41(__weak id &&x) {
+  __weak id y = static_cast<__weak id &&>(x);
+}
+// CHECK-LABEL: define void @_Z6test41OU6__weakP11objc_object
+// CHECK:      [[X:%.*]] = alloca i8**
+// CHECK:      [[Y:%.*]] = alloca i8*
+// CHECK:      [[T0:%.*]] = load i8**, i8*** [[X]]
+// CHECK-NEXT: call void @objc_moveWeak(i8** [[Y]], i8** [[T0]])
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[Y]])




More information about the cfe-commits mailing list