Skip to content

Commit 956acc1

Browse files
authored
Merge pull request #70243 from meg-gupta/enableedgecase
Handle `unchecked_ref_cast` in ObjectOutliner
2 parents 38e2422 + a228a88 commit 956acc1

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ private func findEndCOWMutation(of object: Value) -> EndCOWMutationInst? {
8585
if let ecm = findEndCOWMutation(of: uci) {
8686
return ecm
8787
}
88+
case let urci as UncheckedRefCastInst:
89+
if let ecm = findEndCOWMutation(of: urci) {
90+
return ecm
91+
}
8892
case let mv as MoveValueInst:
8993
if let ecm = findEndCOWMutation(of: mv) {
9094
return ecm
@@ -134,6 +138,10 @@ private func findInitStores(of object: Value,
134138
if !findInitStores(of: uci, &fieldStores, &tailStores) {
135139
return false
136140
}
141+
case let urci as UncheckedRefCastInst:
142+
if !findInitStores(of: urci, &fieldStores, &tailStores) {
143+
return false
144+
}
137145
case let mvi as MoveValueInst:
138146
if !findInitStores(of: mvi, &fieldStores, &tailStores) {
139147
return false
@@ -342,6 +350,8 @@ private func rewriteUses(of startValue: Value, _ context: FunctionPassContext) {
342350
context.erase(instruction: endMutation)
343351
case let upCast as UpcastInst:
344352
worklist.pushIfNotVisited(usersOf: upCast)
353+
case let refCast as UncheckedRefCastInst:
354+
worklist.pushIfNotVisited(usersOf: refCast)
345355
case let moveValue as MoveValueInst:
346356
worklist.pushIfNotVisited(usersOf: moveValue)
347357
case is DeallocRefInst, is DeallocStackRefInst:

lib/SILOptimizer/Transforms/COWOpts.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ static SILValue skipStructAndExtract(SILValue value) {
119119
}
120120

121121
bool COWOptsPass::optimizeBeginCOW(BeginCOWMutationInst *BCM) {
122+
LLVM_DEBUG(llvm::dbgs() << "Looking at: ");
123+
LLVM_DEBUG(BCM->dump());
124+
122125
SILFunction *function = BCM->getFunction();
123126
StackList<EndCOWMutationInst *> endCOWMutationInsts(function);
124127
InstructionSet endCOWMutationsFound(function);
@@ -187,14 +190,20 @@ bool COWOptsPass::optimizeBeginCOW(BeginCOWMutationInst *BCM) {
187190
// Don't immediately bail on a store instruction. Instead, remember
188191
// it and check if it interferes with any (potential) load.
189192
if (storeAddrsFound.insert(store->getDest())) {
193+
LLVM_DEBUG(llvm::dbgs() << "Found store escape, record: ");
194+
LLVM_DEBUG(inst->dump());
190195
storeAddrs.push_back(store->getDest());
191196
numStoresFound += 1;
192197
}
193198
} else {
199+
LLVM_DEBUG(llvm::dbgs() << "Found non-store escape, bailing out: ");
200+
LLVM_DEBUG(inst->dump());
194201
return false;
195202
}
196203
}
197204
if (inst->mayReadFromMemory()) {
205+
LLVM_DEBUG(llvm::dbgs() << "Found a may read inst, record: ");
206+
LLVM_DEBUG(inst->dump());
198207
potentialLoadInsts.push_back(inst);
199208
numLoadsFound += 1;
200209
}
@@ -225,8 +234,12 @@ bool COWOptsPass::optimizeBeginCOW(BeginCOWMutationInst *BCM) {
225234
return false;
226235
for (SILInstruction *load : potentialLoadInsts) {
227236
for (SILValue storeAddr : storeAddrs) {
228-
if (!AA || AA->mayReadFromMemory(load, storeAddr))
237+
if (!AA || AA->mayReadFromMemory(load, storeAddr)) {
238+
LLVM_DEBUG(llvm::dbgs() << "Found a store address aliasing with a load:");
239+
LLVM_DEBUG(load->dump());
240+
LLVM_DEBUG(storeAddr->dump());
229241
return false;
242+
}
230243
}
231244
}
232245
}

test/SILOptimizer/objectoutliner.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,24 @@ bb0:
127127
return %r : $()
128128
}
129129

130+
// CHECK-LABEL: sil @outline_global_with_uncheckedrefcast :
131+
// CHECK: global_value
132+
// CHECK: } // end sil function 'outline_global_with_uncheckedrefcast'
133+
sil @outline_global_with_uncheckedrefcast : $@convention(thin) () -> () {
134+
bb0:
135+
%0 = integer_literal $Builtin.Word, 0
136+
%1 = integer_literal $Builtin.Int64, 1
137+
%4 = struct $Int64 (%1 : $Builtin.Int64)
138+
%7 = alloc_ref [tail_elems $Int64 * %0 : $Builtin.Word] $Obj
139+
%9 = ref_element_addr %7 : $Obj, #Obj.value
140+
store %4 to %9 : $*Int64
141+
%10 = unchecked_ref_cast %7 : $Obj to $Base
142+
%11 = end_cow_mutation %10 : $Base
143+
%12 = begin_dealloc_ref %11 : $Base of %7 : $Obj
144+
dealloc_ref %12 : $Base
145+
%r = tuple ()
146+
return %r : $()
147+
}
130148

131149
// CHECK-LABEL: sil @outline_global_tailelems
132150
// CHECK: [[G:%[0-9]+]] = global_value @outline_global_tailelemsTv_ : $Obj

0 commit comments

Comments
 (0)