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 | 154a2fd3cb187a40481548dc7e21c29a7416b029 (patch) | |
tree | 5bd0d6fc12e1913d561c3937723a60b898603103 /clang/lib/CodeGen/CGObjC.cpp | |
parent | cd267f7e0dd653fee205dd0d1d1375d3bbb85856 (diff) | |
download | bcm5719-llvm-154a2fd3cb187a40481548dc7e21c29a7416b029.tar.gz bcm5719-llvm-154a2fd3cb187a40481548dc7e21c29a7416b029.zip |
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.
llvm-svn: 138789
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 179dc75b31d..f8f19285b35 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/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(); |