Teach IRGen to apply the ARC autorelease optimization implicitly

when working with autoreleased result conventions, and stop
emitting autorelease_return and strong_retain_autoreleased in
SILGen.

The previous representation, in which strong_retain_autoreleased
was divorced from the call site, allowed it to "wander off" and
be cloned.  This would at best would break the optimization, but
it could also lead to broken IR due to some heroic but perhaps
misguided efforts in IRGen to produce the exact required code
pattern despite the representational flaws.

The SIL pattern for an autoreleased result now looks exactly
like the pattern for an owned result in both the caller and
the callee.  This should be fine as long as interprocedural
optimizations are conservative about convention mismatches.
Optimizations that don't wish to be conservative here should
treat a convention mismatch as an autorelease (if the callee
has an autoreleased result) or a retain (if the formal type
of the call has an autoreleased result).

Fixes rdar://23810212, which is an IRGen miscompile after the
optimizer cloned a strong_retain_autoreleased.  There's no
point in adding this test case because the new SIL pattern
inherently prevents this transformation by construction.

The 'autorelease_return' and 'strong_retain_autoreleased'
instructions are now dead, and I will remove them in a
follow-up commit.
This commit is contained in:
John McCall
2015-12-09 00:17:22 -08:00
parent 5d0dc90ac8
commit 23ea72b21e
23 changed files with 51 additions and 64 deletions

View File

@@ -98,7 +98,7 @@ extension NSObject {
// CHECK: [[T0:%.*]] = enum $Optional<NSString>, #Optional.None!enumelt
// CHECK: br bb3([[T0]] : $Optional<NSString>)
// CHECK: bb3([[T0:%.*]] : $Optional<NSString>):
// CHECK: autorelease_return [[T0]] : $Optional<NSString>
// CHECK: return [[T0]] : $Optional<NSString>
// CHECK-LABEL: sil hidden [thunk] @_TToFE14foreign_errorsCSo8NSObject7takeInt{{.*}} : $@convention(objc_method) (Int, AutoreleasingUnsafeMutablePointer<Optional<NSError>>, NSObject) -> Bool
// CHECK: bb0([[I:%[0-9]+]] : $Int, [[ERROR:%[0-9]+]] : $AutoreleasingUnsafeMutablePointer<Optional<NSError>>, [[SELF:%[0-9]+]] : $NSObject)