Skip to content

Commit 7a0a6e7

Browse files
authored
Merge pull request #78616 from meg-gupta/outlinefix6.1
[6.1] Outliner: Do not outline if the BridgedArg value is not available at the BridgedCall
2 parents cae0dfe + 1c12c7b commit 7a0a6e7

File tree

5 files changed

+71
-15
lines changed

5 files changed

+71
-15
lines changed

include/swift/SILOptimizer/Utils/OwnershipOptUtils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ class OwnershipRAUWHelper {
309309
/// specified lexical value.
310310
bool areUsesWithinLexicalValueLifetime(SILValue, ArrayRef<Operand *>);
311311

312+
/// Whether the provided uses lie within the current liveness of the
313+
/// specified value.
314+
bool areUsesWithinValueLifetime(SILValue value, ArrayRef<Operand *> uses,
315+
DeadEndBlocks *deBlocks);
316+
312317
/// A utility composed ontop of OwnershipFixupContext that knows how to replace
313318
/// a single use of a value with another value with a different ownership. We
314319
/// allow for the values to have different types.

lib/SILOptimizer/Transforms/Outliner.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,8 @@ class BridgedArgument {
757757
: BridgeFun(nullptr), BridgeCall(nullptr), OptionalResult(nullptr),
758758
ReleaseAfterBridge(nullptr), ReleaseArgAfterCall(nullptr), Idx(0) {}
759759

760-
static BridgedArgument match(unsigned ArgIdx, SILValue Arg, ApplyInst *AI);
760+
static BridgedArgument match(unsigned ArgIdx, SILValue Arg, ApplyInst *AI,
761+
DeadEndBlocks *deBlocks);
761762

762763
operator bool() const { return BridgeFun != nullptr; }
763764
SILValue bridgedValue() { return BridgedValue; }
@@ -826,7 +827,7 @@ static SILInstruction *findReleaseOf(SILValue releasedValue,
826827
}
827828

828829
BridgedArgument BridgedArgument::match(unsigned ArgIdx, SILValue Arg,
829-
ApplyInst *AI) {
830+
ApplyInst *AI, DeadEndBlocks *deBlocks) {
830831
// Match
831832
// %15 = function_ref @$SSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF
832833
// %16 = apply %15(%14) : $@convention(method) (@guaranteed String) -> @owned NSString
@@ -879,6 +880,7 @@ BridgedArgument BridgedArgument::match(unsigned ArgIdx, SILValue Arg,
879880

880881
if (SILBasicBlock::iterator(BridgeCall) == BridgeCall->getParent()->begin())
881882
return BridgedArgument();
883+
882884
auto *FunRef =
883885
dyn_cast<FunctionRefInst>(std::prev(SILBasicBlock::iterator(BridgeCall)));
884886
if (!FunRef || !FunRef->hasOneUse() || BridgeCall->getCallee() != FunRef)
@@ -912,6 +914,12 @@ BridgedArgument BridgedArgument::match(unsigned ArgIdx, SILValue Arg,
912914
BridgeFun->getName() != bridgeWitness.mangle())
913915
return BridgedArgument();
914916

917+
if (hasOwnership && !BridgedValueRelease) {
918+
SmallVector<Operand *> newUses{&AI->getOperandRef(ArgIdx)};
919+
if (!areUsesWithinValueLifetime(BridgedValue, newUses, deBlocks)) {
920+
return BridgedArgument();
921+
}
922+
}
915923
return BridgedArgument(ArgIdx, FunRef, BridgeCall, Enum, BridgedValueRelease,
916924
ReleaseAfter);
917925
}
@@ -1087,10 +1095,6 @@ ObjCMethodCall::outline(SILModule &M) {
10871095
if (BridgedArgIdx < BridgedArguments.size() &&
10881096
BridgedArguments[BridgedArgIdx].Idx == OrigSigIdx) {
10891097
auto bridgedArgValue = BridgedArguments[BridgedArgIdx].bridgedValue();
1090-
if (bridgedArgValue->getOwnershipKind() == OwnershipKind::Guaranteed) {
1091-
bridgedArgValue = makeGuaranteedValueAvailable(
1092-
bridgedArgValue, BridgedCall, *deBlocks);
1093-
}
10941098
Args.push_back(bridgedArgValue);
10951099
++BridgedArgIdx;
10961100
} else {
@@ -1215,7 +1219,8 @@ bool ObjCMethodCall::matchInstSequence(SILBasicBlock::iterator I) {
12151219
if (Ty.isAnyObject())
12161220
continue;
12171221

1218-
auto BridgedArg = BridgedArgument::match(CurIdx, Param.get(), BridgedCall);
1222+
auto BridgedArg =
1223+
BridgedArgument::match(CurIdx, Param.get(), BridgedCall, deBlocks);
12191224
if (!BridgedArg)
12201225
continue;
12211226

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,30 @@ bool swift::areUsesWithinLexicalValueLifetime(SILValue value,
456456
return false;
457457
}
458458

459+
bool swift::areUsesWithinValueLifetime(SILValue value, ArrayRef<Operand *> uses,
460+
DeadEndBlocks *deBlocks) {
461+
assert(value->getFunction()->hasOwnership());
462+
463+
if (value->getOwnershipKind() == OwnershipKind::None) {
464+
return true;
465+
}
466+
if (value->getOwnershipKind() != OwnershipKind::Guaranteed &&
467+
value->getOwnershipKind() != OwnershipKind::Owned) {
468+
return false;
469+
}
470+
if (value->getOwnershipKind() == OwnershipKind::Guaranteed) {
471+
value = findOwnershipReferenceAggregate(value);
472+
BorrowedValue borrowedValue(value);
473+
if (!borrowedValue.isLocalScope()) {
474+
return true;
475+
}
476+
}
477+
SSAPrunedLiveness liveness(value->getFunction());
478+
liveness.initializeDef(value);
479+
liveness.computeSimple();
480+
return liveness.areUsesWithinBoundary(uses, deBlocks);
481+
}
482+
459483
//===----------------------------------------------------------------------===//
460484
// BorrowedLifetimeExtender
461485
//===----------------------------------------------------------------------===//

test/SILOptimizer/outliner.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %target-swift-frontend -Osize -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked -enable-copy-propagation | %FileCheck %s
22
// RUN: %target-swift-frontend -Osize -g -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked -enable-copy-propagation | %FileCheck %s
33

4+
// RUN: %target-swift-frontend -Osize -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked -enable-copy-propagation -enable-ossa-modules | %FileCheck %s
5+
// RUN: %target-swift-frontend -Osize -g -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked -enable-copy-propagation -enable-ossa-modules | %FileCheck %s
46
// REQUIRES: objc_interop
57
// REQUIRES: optimized_stdlib
68
// REQUIRES: swift_in_compiler

test/SILOptimizer/outliner_ossa.sil

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ bb7(%64 : @owned $Optional<Data>):
7474
return %102 : $()
7575
}
7676

77+
// Not optimized
7778
// CHECK-LABEL: sil [Osize] [ossa] @test2 :
78-
// CHECK: [[FUNC:%.*]] = function_ref @$s4main8MyObjectC4take3arg10Foundation4DataVSgAI_tFZToTembgnn_ :
79-
// CHECK: apply [[FUNC]]
79+
// CHECK: objc_method
8080
// CHECK-LABEL: } // end sil function 'test2'
8181
sil [Osize] [ossa] @test2 : $@convention(thin) (@owned MyObject) -> @owned Optional<NSData> {
8282
bb0(%0: @owned $MyObject):
@@ -96,9 +96,9 @@ bb0(%0: @owned $MyObject):
9696
return %51 : $Optional<NSData>
9797
}
9898

99+
// Not optimized
99100
// CHECK-LABEL: sil [Osize] [ossa] @test3 :
100-
// CHECK: [[FUNC:%.*]] = function_ref @$s4main8MyObjectC4take3arg10Foundation4DataVSgAI_tFZToTembgnn_ :
101-
// CHECK: apply [[FUNC]]
101+
// CHECK: objc_method
102102
// CHECK-LABEL: } // end sil function 'test3'
103103
sil [Osize] [ossa] @test3 : $@convention(thin) (@owned MyObject, @in Data) -> @owned Optional<NSData> {
104104
bb0(%0: @owned $MyObject, %1 : $*Data):
@@ -116,9 +116,9 @@ bb0(%0: @owned $MyObject, %1 : $*Data):
116116
return %51 : $Optional<NSData>
117117
}
118118

119+
// Not optimized
119120
// CHECK-LABEL: sil [Osize] [ossa] @test4 :
120-
// CHECK: [[FUNC:%.*]] = function_ref @$s4main8MyObjectC8take_two4arg14arg210Foundation4DataVSgAJ_AJtFZToTembgbgnn_ :
121-
// CHECK: apply [[FUNC]]
121+
// CHECK: objc_method
122122
// CHECK-LABEL: } // end sil function 'test4'
123123
sil [Osize] [ossa] @test4 : $@convention(thin) (@owned MyObject) -> @owned Optional<NSData> {
124124
bb0(%0: @owned $MyObject):
@@ -177,9 +177,9 @@ bb3:
177177
return %51 : $Optional<NSData>
178178
}
179179

180+
// Not optimized
180181
// CHECK-LABEL: sil [Osize] [ossa] @test6 :
181-
// CHECK: [[FUNC:%.*]] = function_ref @$s4main8MyObjectC4take3arg10Foundation4DataVSgAI_tFZToTembgnn_ :
182-
// CHECK: apply [[FUNC]]
182+
// CHECK: objc_method
183183
// CHECK-LABEL: } // end sil function 'test6'
184184
sil [Osize] [ossa] @test6 : $@convention(thin) (@owned MyObject) -> @owned Optional<NSData> {
185185
bb0(%0: @owned $MyObject):
@@ -305,3 +305,23 @@ sil [Osize] [ossa] @destroy_after_borrow : $@convention(thin) () -> @owned Sub {
305305
apply undef(%162) : $@convention(thin) (Int) -> ()
306306
return %107 : $Sub
307307
}
308+
309+
// CHECK-LABEL: sil [Osize] [ossa] @test_consume :
310+
// CHECK: objc_method
311+
// CHECK-LABEL: } // end sil function 'test_consume'
312+
sil [Osize] [ossa] @test_consume : $@convention(thin) (@owned MyObject) -> @owned Optional<NSData> {
313+
bb0(%0: @owned $MyObject):
314+
%35 = metatype $@objc_metatype MyObject.Type
315+
%41 = function_ref @getData : $@convention(thin) () -> @owned Data
316+
%43 = apply %41() : $@convention(thin) () -> @owned Data
317+
%44 = function_ref @$s10Foundation4DataV19_bridgeToObjectiveCSo6NSDataCyF : $@convention(method) (@guaranteed Data) -> @owned NSData
318+
%45 = apply %44(%43) : $@convention(method) (@guaranteed Data) -> @owned NSData
319+
%46 = enum $Optional<NSData>, #Optional.some!enumelt, %45 : $NSData
320+
destroy_value %0 : $MyObject
321+
%48 = apply undef(%43) : $@convention(method) (@owned Data) -> ()
322+
%50 = objc_method %35 : $@objc_metatype MyObject.Type, #MyObject.take!foreign : (MyObject.Type) -> (Data?) -> Data?, $@convention(objc_method) (Optional<NSData>, @objc_metatype MyObject.Type) -> @autoreleased Optional<NSData>
323+
%51 = apply %50(%46, %35) : $@convention(objc_method) (Optional<NSData>, @objc_metatype MyObject.Type) -> @autoreleased Optional<NSData>
324+
destroy_value %46 : $Optional<NSData>
325+
return %51 : $Optional<NSData>
326+
}
327+

0 commit comments

Comments
 (0)