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