Skip to content

Commit be7ddc6

Browse files
committed
UnsafeGuaranteedPeephole: Skip debug instructions and ignore retain/release uses
1 parent 76ab68b commit be7ddc6

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed

lib/SILOptimizer/Transforms/UnsafeGuaranteedPeephole.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ getSingleUnsafeGuaranteedValueResult(BuiltinInst *BI) {
5656
auto Failed = std::make_pair(nullptr, nullptr);
5757

5858
for (auto *Operand : getNonDebugUses(BI)) {
59-
auto *TE = dyn_cast<TupleExtractInst>(Operand->getUser());
59+
auto *Usr = Operand->getUser();
60+
if (isa<ReleaseValueInst>(Usr) || isa<RetainValueInst>(Usr))
61+
continue;
62+
63+
auto *TE = dyn_cast<TupleExtractInst>(Usr);
6064
if (!TE || TE->getOperand() != BI)
6165
return Failed;
6266

@@ -97,13 +101,19 @@ findReleaseToMatchUnsafeGuaranteedValue(SILInstruction *UnsafeGuaranteedEndI,
97101
return BB.end();
98102
auto LastReleaseIt = std::prev(UnsafeGuaranteedEndIIt);
99103
while (LastReleaseIt != BB.begin() &&
100-
(isa<StrongReleaseInst>(*LastReleaseIt) ||
101-
isa<ReleaseValueInst>(*LastReleaseIt)) &&
102-
LastReleaseIt->getOperand(0) != UnsafeGuaranteedValue)
104+
(((isa<StrongReleaseInst>(*LastReleaseIt) ||
105+
isa<ReleaseValueInst>(*LastReleaseIt)) &&
106+
LastReleaseIt->getOperand(0) != UnsafeGuaranteedValue &&
107+
LastReleaseIt->getOperand(0) !=
108+
cast<SILInstruction>(UnsafeGuaranteedValue)->getOperand(0)) ||
109+
isa<DebugValueInst>(*LastReleaseIt) ||
110+
isa<DebugValueInst>(*LastReleaseIt)))
103111
--LastReleaseIt;
104112
if ((!isa<StrongReleaseInst>(*LastReleaseIt) &&
105113
!isa<ReleaseValueInst>(*LastReleaseIt)) ||
106-
LastReleaseIt->getOperand(0) != UnsafeGuaranteedValue) {
114+
(LastReleaseIt->getOperand(0) != UnsafeGuaranteedValue &&
115+
LastReleaseIt->getOperand(0) !=
116+
cast<SILInstruction>(UnsafeGuaranteedValue)->getOperand(0))) {
107117
return BB.end();
108118
}
109119
return LastReleaseIt;
@@ -145,7 +155,9 @@ static bool removeGuaranteedRetainReleasePairs(SILFunction &F) {
145155
auto NextInstIter = std::next(SILBasicBlock::iterator(LastRetainInst));
146156
while (NextInstIter != BB.end() && &*NextInstIter != CurInst &&
147157
(isa<RetainValueInst>(*NextInstIter) ||
148-
isa<StrongRetainInst>(*NextInstIter)))
158+
isa<StrongRetainInst>(*NextInstIter) ||
159+
isa<DebugValueInst>(*NextInstIter) ||
160+
isa<DebugValueAddrInst>(*NextInstIter)))
149161
++NextInstIter;
150162
if (&*NextInstIter != CurInst) {
151163
DEBUG(llvm::dbgs() << "Last retain right before match failed\n");
@@ -228,6 +240,7 @@ static bool removeGuaranteedRetainReleasePairs(SILFunction &F) {
228240
UnsafeGuaranteedValue->replaceAllUsesWith(Opd);
229241
UnsafeGuaranteedValue->eraseFromParent();
230242
UnsafeGuaranteedToken->eraseFromParent();
243+
UnsafeGuaranteedI->replaceAllUsesWith(Opd);
231244
UnsafeGuaranteedI->eraseFromParent();
232245

233246
if (RestartAtBeginningOfBlock)

test/SILOptimizer/unsafe_guaranteed_peephole.sil

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class Foo {
99
}
1010

1111
sil @beep : $@convention(thin) () -> ()
12+
sil @beep2 : $@convention(thin) (@owned Foo) -> ()
1213

1314
// CHECK-LABEL: sil @testUnsafeGuaranteed_simple
1415
// CHECK: bb0([[P:%.*]] : $Foo):
@@ -235,3 +236,57 @@ bb3:
235236
%20 = apply %19(%5) : $@convention(method) (@guaranteed Foo) -> ()
236237
br bb2
237238
}
239+
240+
// CHECK-LABEL: sil @testUnsafeGuaranteed_debug_inst
241+
// CHECK: bb0([[P:%.*]] : $Foo):
242+
// CHECK-NOT: retain
243+
// CHECK-NOT: unsafeGuaranteed
244+
// CHECK: [[M:%.*]] = class_method [[P]] : $Foo, #Foo.beep
245+
// CHECK: apply [[M]]([[P]])
246+
// CHECK-NOT: release
247+
// CHECK-NOT: unsafeGuaranteedEnd
248+
// CHECK: [[T:%.*]] = tuple ()
249+
// CHECK: return [[T]]
250+
// CHECK: }
251+
sil @testUnsafeGuaranteed_debug_inst : $@convention(method) (@guaranteed Foo) -> () {
252+
bb0(%0 : $Foo):
253+
strong_retain %0 : $Foo
254+
debug_value %0 : $Foo
255+
%4 = builtin "unsafeGuaranteed"<Foo>(%0 : $Foo) : $(Foo, Builtin.Int8)
256+
%5 = tuple_extract %4 : $(Foo, Builtin.Int8), 0
257+
%6 = tuple_extract %4 : $(Foo, Builtin.Int8), 1
258+
%19 = class_method %5 : $Foo, #Foo.beep!1 : (Foo) -> () -> () , $@convention(method) (@guaranteed Foo) -> ()
259+
%20 = apply %19(%5) : $@convention(method) (@guaranteed Foo) -> ()
260+
strong_release %5 : $Foo
261+
debug_value %5 : $Foo
262+
%16 = builtin "unsafeGuaranteedEnd"(%6 : $Builtin.Int8) : $()
263+
%17 = tuple ()
264+
return %17 : $()
265+
}
266+
267+
// CHECK-LABEL: sil @testUnsafeGuaranteed_retain_release
268+
// CHECK: bb0([[P:%.*]] : $Foo):
269+
// CHECK-NOT: strong_retain
270+
// CHECK-NOT: unsafeGuaranteed
271+
// CHECK: retain_value [[P]]
272+
// CHECK: [[M:%.*]] = function_ref @beep2
273+
// CHECK: apply [[M]]([[P]])
274+
// CHECK-NOT: release
275+
// CHECK-NOT: unsafeGuaranteedEnd
276+
// CHECK: [[T:%.*]] = tuple ()
277+
// CHECK: return [[T]]
278+
// CHECK: }
279+
sil @testUnsafeGuaranteed_retain_release : $@convention(method) (@guaranteed Foo) -> () {
280+
bb0(%0 : $Foo):
281+
strong_retain %0 : $Foo
282+
%4 = builtin "unsafeGuaranteed"<Foo>(%0 : $Foo) : $(Foo, Builtin.Int8)
283+
%5 = tuple_extract %4 : $(Foo, Builtin.Int8), 0
284+
%6 = tuple_extract %4 : $(Foo, Builtin.Int8), 1
285+
retain_value %4 : $(Foo, Builtin.Int8)
286+
%19 = function_ref @beep2 : $@convention(thin) (@owned Foo) -> ()
287+
%20 = apply %19(%5) : $@convention(thin) (@owned Foo) -> ()
288+
release_value %4 : $(Foo, Builtin.Int8)
289+
%16 = builtin "unsafeGuaranteedEnd"(%6 : $Builtin.Int8) : $()
290+
%17 = tuple ()
291+
return %17 : $()
292+
}

0 commit comments

Comments
 (0)