Skip to content

Commit 0e08976

Browse files
committed
SILOptimizer: a new optimization to hoist destroys of memory locations
DestroyHoisting moves destroys of memory locations up the control flow as far as possible. Beside destroy_addr, also "store [assign]" is considered a destroy, because is is equivalent to an destroy_addr + a "store [init]". The main purpose of this optimization is to minimize copy-on-write operations for arrays, etc. Especially if such COW containers are used as enum payloads and modified in-place. E.g. switch e { case .A(var arr): arr.append(x) self = .A(arr) ... In such a case DestroyHoisting can move the destroy of the self-assignment up before the switch and thus let the array buffer only be single-referenced at the time of the append. When we have ownership SIL throughout the pass pipeline this optimization will replace the current destroy hoisting optimization in CopyForwarding. For now, this optimization only runs in the mandatory pipeline (but not for -Onone) where we already have ownership SIL. SR-10605 rdar://problem/50463362
1 parent 34e80b7 commit 0e08976

File tree

7 files changed

+1048
-0
lines changed

7 files changed

+1048
-0
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,9 @@ class LoadInst
32403240
return LoadOwnershipQualifier(
32413241
SILInstruction::Bits.LoadInst.OwnershipQualifier);
32423242
}
3243+
void setOwnershipQualifier(LoadOwnershipQualifier qualifier) {
3244+
SILInstruction::Bits.LoadInst.OwnershipQualifier = unsigned(qualifier);
3245+
}
32433246
};
32443247

32453248
// *NOTE* When serializing, we can only represent up to 4 values here. If more
@@ -3279,6 +3282,9 @@ class StoreInst
32793282
return StoreOwnershipQualifier(
32803283
SILInstruction::Bits.StoreInst.OwnershipQualifier);
32813284
}
3285+
void setOwnershipQualifier(StoreOwnershipQualifier qualifier) {
3286+
SILInstruction::Bits.StoreInst.OwnershipQualifier = unsigned(qualifier);
3287+
}
32823288
};
32833289

32843290
class EndBorrowInst;

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ PASS(DeadObjectElimination, "deadobject-elim",
132132
"Dead Object Elimination for Classes with Trivial Destruction")
133133
PASS(DefiniteInitialization, "definite-init",
134134
"Definite Initialization for Diagnostics")
135+
PASS(DestroyHoisting, "destroy-hoisting",
136+
"Hoisting of value destroys")
135137
PASS(Devirtualizer, "devirtualizer",
136138
"Indirect Call Devirtualization")
137139
PASS(DiagnoseInfiniteRecursion, "diagnose-infinite-recursion",

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ static void addMandatoryOptPipeline(SILPassPipelinePlan &P) {
104104
P.addClosureLifetimeFixup();
105105
if (Options.shouldOptimize()) {
106106
P.addSemanticARCOpts();
107+
P.addDestroyHoisting();
107108
}
108109
if (!Options.StripOwnershipAfterSerialization)
109110
P.addOwnershipModelEliminator();

lib/SILOptimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ silopt_register_sources(
1515
DeadCodeElimination.cpp
1616
DeadObjectElimination.cpp
1717
DeadStoreElimination.cpp
18+
DestroyHoisting.cpp
1819
Devirtualizer.cpp
1920
GenericSpecializer.cpp
2021
MergeCondFail.cpp

0 commit comments

Comments
 (0)