diff options
author | John McCall <rjmccall@apple.com> | 2012-10-17 02:28:37 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-10-17 02:28:37 +0000 |
commit | 015f33b6741ffceba3a71ee2d71d46418a7dc34c (patch) | |
tree | fe2a0c3d3a8b66f0282ef93a379d5eca01f38a4b /lib/CodeGen/CGObjC.cpp | |
parent | 5708c18904304ed4e39abed8131fcad5e2fc0896 (diff) |
At -O0, prefer objc_storeStrong with a null new value to the
combination of a load+objc_release; this is generally better
for tools that try to track why values are retained and
released. Also use objc_storeStrong when copying a block
(again, only at -O0), which requires us to do a preliminary
store of null in order to compensate for objc_storeStrong's
assign semantics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166085 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 0fa70e7d3d..a47c56f67c 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -1949,6 +1949,28 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) { } } +/// Destroy a __strong variable. +/// +/// At -O0, emit a call to store 'null' into the address; +/// instrumenting tools prefer this because the address is exposed, +/// but it's relatively cumbersome to optimize. +/// +/// At -O1 and above, just load and call objc_release. +/// +/// call void \@objc_storeStrong(i8** %addr, i8* null) +void CodeGenFunction::EmitARCDestroyStrong(llvm::Value *addr, bool precise) { + if (CGM.getCodeGenOpts().OptimizationLevel == 0) { + llvm::PointerType *addrTy = cast<llvm::PointerType>(addr->getType()); + llvm::Value *null = llvm::ConstantPointerNull::get( + cast<llvm::PointerType>(addrTy->getElementType())); + EmitARCStoreStrongCall(addr, null, /*ignored*/ true); + return; + } + + llvm::Value *value = Builder.CreateLoad(addr); + EmitARCRelease(value, precise); +} + /// Store into a strong object. Always calls this: /// call void \@objc_storeStrong(i8** %addr, i8* %value) llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr, @@ -2222,15 +2244,13 @@ void CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) { void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF, llvm::Value *addr, QualType type) { - llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy"); - CGF.EmitARCRelease(ptr, /*precise*/ true); + CGF.EmitARCDestroyStrong(addr, /*precise*/ true); } void CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF, llvm::Value *addr, QualType type) { - llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy"); - CGF.EmitARCRelease(ptr, /*precise*/ false); + CGF.EmitARCDestroyStrong(addr, /*precise*/ false); } void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF, |