Skip to content

Commit 5d2454f

Browse files
authored
Merge pull request #68180 from meg-gupta/lowerb4inline
Lower OwnershipModelEliminator to just before inlining
2 parents 02094d1 + ad170b6 commit 5d2454f

File tree

13 files changed

+53
-57
lines changed

13 files changed

+53
-57
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,7 @@ private func isValidUseOfObject(_ use: Operand) -> Bool {
298298
is UpcastInst,
299299
is BeginDeallocRefInst,
300300
is RefTailAddrInst,
301-
is RefElementAddrInst,
302-
is StructInst,
303-
is PointerToAddressInst,
304-
is IndexAddrInst:
301+
is RefElementAddrInst:
305302
for instUse in (inst as! SingleValueInstruction).uses {
306303
if !isValidUseOfObject(instUse) {
307304
return false

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,6 @@ private func shouldInline(apply: FullApplySite, callee: Function, alreadyInlined
167167
return true
168168
}
169169

170-
if apply.parentFunction.hasOwnership && !callee.hasOwnership {
171-
// Cannot inline a non-ossa function into an ossa function
172-
return false
173-
}
174-
175170
if apply is BeginApplyInst {
176171
// Avoid co-routines because they might allocate (their context).
177172
return true

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,14 @@ extension FullApplySite {
510510
!calleeFunction.isSerialized {
511511
return false
512512
}
513+
514+
// Cannot inline a non-ossa function into an ossa function
515+
if parentFunction.hasOwnership,
516+
let calleeFunction = referencedFunction,
517+
!calleeFunction.hasOwnership {
518+
return false
519+
}
520+
513521
return true
514522
}
515523

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,6 @@ static llvm::cl::opt<bool> SILViewSILGenCFG(
6161
"sil-view-silgen-cfg", llvm::cl::init(false),
6262
llvm::cl::desc("Enable the sil cfg viewer pass before diagnostics"));
6363

64-
65-
llvm::cl::opt<bool> SILDisableLateOMEByDefault(
66-
"sil-disable-late-ome-by-default", llvm::cl::init(false),
67-
llvm::cl::desc(
68-
"Disable late OME for non-transparent functions by default"));
69-
7064
llvm::cl::opt<bool>
7165
EnableDestroyHoisting("enable-destroy-hoisting", llvm::cl::init(false),
7266
llvm::cl::desc("Enable the DestroyHoisting pass."));
@@ -452,16 +446,6 @@ void addFunctionPasses(SILPassPipelinePlan &P,
452446
// Cleanup, which is important if the inliner has restarted the pass pipeline.
453447
P.addPerformanceConstantPropagation();
454448

455-
if (!P.getOptions().EnableOSSAModules && !SILDisableLateOMEByDefault) {
456-
if (P.getOptions().StopOptimizationBeforeLoweringOwnership)
457-
return;
458-
459-
if (SILPrintFinalOSSAModule) {
460-
addModulePrinterPipeline(P, "SIL Print Final OSSA Module");
461-
}
462-
P.addNonTransparentFunctionOwnershipModelEliminator();
463-
}
464-
465449
addSimplifyCFGSILCombinePasses(P);
466450

467451
P.addArrayElementPropagation();
@@ -506,13 +490,21 @@ void addFunctionPasses(SILPassPipelinePlan &P,
506490
}
507491
P.addARCSequenceOpts();
508492

509-
if (P.getOptions().EnableOSSAModules) {
510-
// We earlier eliminated ownership if we are not compiling the stdlib. Now
511-
// handle the stdlib functions, re-simplifying, eliminating ARC as we do.
512-
if (P.getOptions().CopyPropagation != CopyPropagationOption::Off) {
513-
P.addCopyPropagation();
493+
// We earlier eliminated ownership if we are not compiling the stdlib. Now
494+
// handle the stdlib functions, re-simplifying, eliminating ARC as we do.
495+
if (P.getOptions().CopyPropagation != CopyPropagationOption::Off) {
496+
P.addCopyPropagation();
497+
}
498+
P.addSemanticARCOpts();
499+
500+
if (!P.getOptions().EnableOSSAModules) {
501+
if (P.getOptions().StopOptimizationBeforeLoweringOwnership)
502+
return;
503+
504+
if (SILPrintFinalOSSAModule) {
505+
addModulePrinterPipeline(P, "SIL Print Final OSSA Module");
514506
}
515-
P.addSemanticARCOpts();
507+
P.addNonTransparentFunctionOwnershipModelEliminator();
516508
}
517509

518510
switch (OpLevel) {
@@ -641,16 +633,6 @@ static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
641633
// not blocked by any other passes' optimizations, so do it early.
642634
P.addDifferentiabilityWitnessDevirtualizer();
643635

644-
if (!P.getOptions().EnableOSSAModules && SILDisableLateOMEByDefault) {
645-
if (P.getOptions().StopOptimizationBeforeLoweringOwnership)
646-
return;
647-
648-
if (SILPrintFinalOSSAModule) {
649-
addModulePrinterPipeline(P, "SIL Print Final OSSA Module");
650-
}
651-
P.addNonTransparentFunctionOwnershipModelEliminator();
652-
}
653-
654636
// Start by linking in referenced functions from other modules.
655637
P.addPerformanceSILLinker();
656638

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,8 @@ bool SimplifyCFG::simplifyUnreachableBlock(UnreachableInst *UI) {
23192319
case SILInstructionKind::StrongReleaseInst:
23202320
case SILInstructionKind::RetainValueInst:
23212321
case SILInstructionKind::ReleaseValueInst:
2322+
case SILInstructionKind::DestroyValueInst:
2323+
case SILInstructionKind::EndBorrowInst:
23222324
break;
23232325
// We can only ignore a dealloc_stack instruction if we can ignore all
23242326
// instructions in the block.

lib/SILOptimizer/Utils/InstructionDeleter.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,28 @@ static bool isScopeAffectingInstructionDead(SILInstruction *inst,
6262
return false;
6363
}
6464

65-
// If inst has any owned move-only value as a result, deleting it may shorten
66-
// that value's lifetime which is illegal according to language rules.
67-
//
68-
// In particular, this check is needed before returning true when
69-
// getSingleValueCopyOrCast returns true. That function returns true for
70-
// move_value instructions. And `move_value %moveOnlyValue` must not be
71-
// deleted.
7265
for (auto result : inst->getResults()) {
66+
// If inst has any owned move-only value as a result, deleting it may
67+
// shorten that value's lifetime which is illegal according to language
68+
// rules.
69+
//
70+
// In particular, this check is needed before returning true when
71+
// getSingleValueCopyOrCast returns true. That function returns true for
72+
// move_value instructions. And `move_value %moveOnlyValue` must not be
73+
// deleted.
7374
if (result->getType().getASTType()->isNoncopyable() &&
7475
result->getOwnershipKind() == OwnershipKind::Owned) {
7576
return false;
7677
}
78+
79+
// If result was lexical, lifetime shortening maybe observed, return.
80+
if (result->isLexical()) {
81+
auto resultTy = result->getType().getAs<SILFunctionType>();
82+
// Allow deleted dead lexical values when they are trivial no escape types.
83+
if (!resultTy || !resultTy->isTrivialNoEscape()) {
84+
return false;
85+
}
86+
}
7787
}
7888

7989
// If inst is a copy or beginning of scope, inst is dead, since we know that

lib/SILOptimizer/Utils/OwnershipOptUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ bool OwnershipRAUWHelper::hasValidRAUWOwnership(SILValue oldValue,
386386
if (m->getStage() == SILStage::Raw)
387387
return false;
388388

389+
// OSSA rauw can create copies. Bail out if we have move only values.
390+
if (newValue->getType().isMoveOnly()) {
391+
return false;
392+
}
393+
389394
return true;
390395
}
391396

test/Interpreter/moveonly_linkedlist.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-run-simple-swift(-Xfrontend -sil-verify-all)
22
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all)
3+
// RUN: %target-run-simple-swift(-O -Xfrontend -sil-verify-all -Xfrontend -enable-ossa-modules)
34

45
// REQUIRES: executable_test
56

test/SILOptimizer/consuming_parameter.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ public func async_dead_arg_call(o: consuming AnyObject) async {
1818

1919
// CHECK-LABEL: sil [ossa] @async_dead_arg_call_lexical : {{.*}} {
2020
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @noImplicitCopy @_lexical @owned
21-
// CHECK: [[MOVE:%[^,]+]] = move_value [lexical] [[INSTANCE]]
2221
// CHECK: [[EXECUTOR:%[^,]+]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
2322
// CHECK: [[CALLEE:%[^,]+]] = function_ref @async_callee
2423
// CHECK: apply [[CALLEE]]()
2524
// CHECK: hop_to_executor [[EXECUTOR]]
26-
// CHECK: destroy_value [[MOVE]]
25+
// CHECK: destroy_value [[INSTANCE]]
2726
// CHECK-LABEL: } // end sil function 'async_dead_arg_call_lexical'
2827
@_silgen_name("async_dead_arg_call_lexical")
2928
public func async_dead_arg_call_lexical(@_noEagerMove o: consuming AnyObject) async {

test/SILOptimizer/pre_specialize_layouts.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public func usePrespecializedThrowsEntryPoints() throws {
213213
// OPT-macosx: [[R9:%.*]] = unchecked_addr_cast [[R7]] : $*Array<Int> to $*Builtin.BridgeObject
214214
// OPT-macosx: [[A3:%.*]] = unchecked_bitwise_cast [[P4]] : $Array<Int> to $Builtin.BridgeObject
215215
// OPT-macosx: [[A4:%.*]] = unchecked_bitwise_cast [[P5]] : $Array<Float> to $Builtin.BridgeObject
216-
// OPT-macosx: [[F2]]([[R8]], [[R9]], [[A3]], [[A4]], [[P3]]) : $@convention(thin) (@guaranteed Builtin.BridgeObject, @guaranteed Builtin.BridgeObject, Int64) -> (@out Builtin.BridgeObject, Int64, @out Builtin.BridgeObject) // user: %38
216+
// OPT-macosx: [[F2]]([[R8]], [[R9]], [[A3]], [[A4]], [[P3]]) : $@convention(thin) (@guaranteed Builtin.BridgeObject, @guaranteed Builtin.BridgeObject, Int64) -> (@out Builtin.BridgeObject, Int64, @out Builtin.BridgeObject)
217217
// OPT: } // end sil function '$s22pre_specialize_layouts40usePresepcializedMultipleIndirectResults___2xs2ysy0a20_specialized_module_C09SomeClassC_AA0m5OtherN0Cs5Int64VSaySiGSaySfGtF'
218218
public final class SomeOtherClass {}
219219
public func usePresepcializedMultipleIndirectResults(_ c: SomeClass, _ d: SomeOtherClass, _ x: Int64, xs: [Int], ys: [Float]) {

test/SILOptimizer/sil_combine_protocol_conf.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ public class Other {
124124
// CHECK: [[W1:%.*]] = witness_method $@opened("{{.*}}", any DerivedProtocol) Self, #DerivedProtocol.foo : <Self where Self : DerivedProtocol> (Self) -> () -> Int, [[O1]] : $*@opened("{{.*}}", any DerivedProtocol) Self : $@convention(witness_method: DerivedProtocol) <τ_0_0 where τ_0_0 : DerivedProtocol> (@in_guaranteed τ_0_0) -> Int
125125
// CHECK: apply [[W1]]<@opened("{{.*}}", any DerivedProtocol) Self>([[O1]]) : $@convention(witness_method: DerivedProtocol) <τ_0_0 where τ_0_0 : DerivedProtocol> (@in_guaranteed τ_0_0) -> Int
126126
// CHECK: struct_extract
127-
// CHECK: integer_literal
128127
// CHECK: builtin
129128
// CHECK: tuple_extract
130129
// CHECK: tuple_extract

test/stdlib/move_function.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ tests.test("simpleVarTest") {
9191
expectTrue(_isUnique_native(&x))
9292

9393
var y = x
94-
expectFalse(_isUnique_native(&x))
9594
let _ = consume y
9695
expectTrue(_isUnique_native(&x))
9796
y = Klass()
@@ -101,7 +100,6 @@ tests.test("simpleVarTest") {
101100
tests.test("simpleInoutVarTest") {
102101
func inOutTest(_ x: inout Klass) {
103102
var y = x
104-
expectFalse(_isUnique_native(&x))
105103
let _ = consume y
106104
expectTrue(_isUnique_native(&x))
107105
y = Klass()

validation-test/SILOptimizer/lexical-lifetimes.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DataWrapper {
2929
var pointer: UnsafeMutableRawBufferPointer
3030

3131
init(count: Int) {
32-
pointer = UnsafeMutableRawBufferPointer.allocate(byteCount: count, alignment: MemoryLayout<Int>.alignment)
32+
pointer = UnsafeMutableRawBufferPointer.allocate(byteCount: count * MemoryLayout<Int>.stride, alignment: MemoryLayout<Int>.alignment)
3333
}
3434

3535
var bytes: UnsafeMutableRawBufferPointer { return pointer }
@@ -43,7 +43,7 @@ var fileHandleMap: [Int32 : String] = [:]
4343

4444
func openTheFile(_ path: String) -> Int32 {
4545
let fd: Int32 = 42
46-
assert(fileHandleMap[fd] == nil)
46+
precondition(fileHandleMap[fd] == nil)
4747
fileHandleMap[fd] = path
4848
return fd
4949
}
@@ -53,7 +53,7 @@ func closeTheFile(_ fd: Int32) {
5353
}
5454

5555
func writeToTheFile(_ fd: Int32) {
56-
assert(fileHandleMap[fd] != nil)
56+
precondition(fileHandleMap[fd] != nil)
5757
}
5858

5959
class FileHandleWrapper {

0 commit comments

Comments
 (0)