diff options
author | John McCall <rjmccall@apple.com> | 2011-08-30 00:57:29 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-30 00:57:29 +0000 |
commit | 2148011bffc011f8e5f5b6dc1e312fa4afbc10a9 (patch) | |
tree | 0ebdb72742b2fda4b6b07cee2a3390729a2b103c /lib/CodeGen/CGObjC.cpp | |
parent | dad879a783f7cf055dd532883cd5efe12bcfd926 (diff) |
Be sure to emit lvalue-to-rvalue casts for loads from x-values.
Doing this happens to disrupt the pattern that ARC was looking for
for move optimizations, so we need to fix that simultaneously.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138789 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 179dc75b31..f8f19285b3 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -1879,6 +1879,24 @@ static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, e = e->IgnoreParens(); QualType type = e->getType(); + // If we're loading retained from a __strong xvalue, we can avoid + // an extra retain/release pair by zeroing out the source of this + // "move" operation. + if (e->isXValue() && + !type.isConstQualified() && + type.getObjCLifetime() == Qualifiers::OCL_Strong) { + // Emit the lvalue. + LValue lv = CGF.EmitLValue(e); + + // Load the object pointer. + llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal(); + + // Set the source pointer to NULL. + CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv); + + return TryEmitResult(result, true); + } + // As a very special optimization, in ARC++, if the l-value is the // result of a non-volatile assignment, do a simple retain of the // result of the call to objc_storeWeak instead of reloading. @@ -1953,30 +1971,6 @@ tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) { // ultimate opaque expression. llvm::Type *resultType = 0; - // If we're loading retained from a __strong xvalue, we can avoid - // an extra retain/release pair by zeroing out the source of this - // "move" operation. - if (e->isXValue() && !e->getType().isConstQualified() && - e->getType().getObjCLifetime() == Qualifiers::OCL_Strong) { - // Emit the lvalue - LValue lv = CGF.EmitLValue(e); - - // Load the object pointer and cast it to the appropriate type. - QualType exprType = e->getType(); - llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal(); - - if (resultType) - result = CGF.Builder.CreateBitCast(result, resultType); - - // Set the source pointer to NULL. - llvm::Value *null - = llvm::ConstantPointerNull::get( - cast<llvm::PointerType>(CGF.ConvertType(exprType))); - CGF.EmitStoreOfScalar(null, lv); - - return TryEmitResult(result, true); - } - while (true) { e = e->IgnoreParens(); |