Skip to content

Commit 96b774f

Browse files
authored
Recommit #31595 with fixes (#31732)
Add new pattern in SILCombine to optimize redundant thick to objc metatype conversions Add pattern to catch the following redundant conversion: %tmp1 = thick_to_objc_metatype %x %tmp2 = objc_to_thick_metatype %tmp1 ... %tmp3 = <sil operation> %tmp2 to: %tmp3 = <sil operation> %x Similarly add pattern for redundant conversion of objc_to_thick_metatype followed by thick_to_objc_metatype. Fixes rdar://62932799
1 parent fcd5def commit 96b774f

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,11 @@ SILCombiner::visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCMI) {
440440
if (TTOCMI->getFunction()->hasOwnership())
441441
return nullptr;
442442

443+
if (auto *OCTTMI = dyn_cast<ObjCToThickMetatypeInst>(TTOCMI->getOperand())) {
444+
TTOCMI->replaceAllUsesWith(OCTTMI->getOperand());
445+
return eraseInstFromFunction(*TTOCMI);
446+
}
447+
443448
// Perform the following transformations:
444449
// (thick_to_objc_metatype (metatype @thick)) ->
445450
// (metatype @objc_metatype)
@@ -460,6 +465,11 @@ SILCombiner::visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *OCTTMI) {
460465
if (OCTTMI->getFunction()->hasOwnership())
461466
return nullptr;
462467

468+
if (auto *TTOCMI = dyn_cast<ThickToObjCMetatypeInst>(OCTTMI->getOperand())) {
469+
OCTTMI->replaceAllUsesWith(TTOCMI->getOperand());
470+
return eraseInstFromFunction(*OCTTMI);
471+
}
472+
463473
// Perform the following transformations:
464474
// (objc_to_thick_metatype (metatype @objc_metatype)) ->
465475
// (metatype @thick)

test/SILOptimizer/peephole_thick_to_objc_metatype.sil

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import Builtin
88
import Swift
99
import SwiftShims
1010

11+
import Foundation
12+
1113
@objc(XX) protocol X {
1214
}
1315

@@ -115,3 +117,48 @@ bb0(%0 : $T):
115117
strong_release %0 : $T
116118
return %3 : $@thick T.Type
117119
}
120+
121+
// CHECK-LABEL: sil @$test_peephole_objc_to_thick_to_objc :
122+
// CHECK: [[T:%.*]] = apply
123+
// CHECK-NOT: objc_to_thick_metatype
124+
// CHECK-NOT: thick_to_objc_metatype
125+
// CHECK: enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, [[T]] : $@objc_metatype AnyObject.Type
126+
// CHECK: } // end sil function '$test_peephole_objc_to_thick_to_objc'
127+
128+
sil @$test_peephole_objc_to_thick_to_objc : $@convention(thin) (@guaranteed NSObject) -> Optional<UnsafeMutablePointer<OpaquePointer>> {
129+
// %0 "obj" // users: %3, %2, %1
130+
bb0(%0 : $NSObject):
131+
debug_value %0 : $NSObject, let, name "obj", argno 1 // id: %1
132+
%2 = objc_method %0 : $NSObject, #NSObject.classForCoder!getter.foreign : (NSObject) -> () -> AnyObject.Type, $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %3
133+
%3 = apply %2(%0) : $@convention(objc_method) (NSObject) -> @objc_metatype AnyObject.Type // user: %4
134+
%4 = objc_to_thick_metatype %3 : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type // users: %6, %5
135+
debug_value %4 : $@thick AnyObject.Type, let, name "c" // id: %5
136+
%6 = thick_to_objc_metatype %4 : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type // user: %7
137+
%7 = enum $Optional<@objc_metatype AnyObject.Type>, #Optional.some!enumelt, %6 : $@objc_metatype AnyObject.Type // user: %10
138+
%8 = enum $Optional<UnsafeMutablePointer<UInt32>>, #Optional.none!enumelt // user: %10
139+
// function_ref class_copyMethodList
140+
%9 = function_ref @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // user: %10
141+
%10 = apply %9(%7, %8) : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>> // users: %12, %11
142+
debug_value %10 : $Optional<UnsafeMutablePointer<OpaquePointer>>, let, name "l" // id: %11
143+
return %10 : $Optional<UnsafeMutablePointer<OpaquePointer>> // id: %12
144+
}
145+
146+
// CHECK-LABEL: sil @$test_peephole_thick_to_objc_to_thick :
147+
// CHECK: [[T:%.*]] = apply
148+
// CHECK-NOT: thick_to_objc_metatype
149+
// CHECK-NOT: objc_to_thick_metatype
150+
// CHECK: return [[T]]
151+
// CHECK: } // end sil function '$test_peephole_thick_to_objc_to_thick'
152+
153+
sil @$test_peephole_thick_to_objc_to_thick : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type {
154+
bb0(%0 : $AnyObject):
155+
%func = function_ref @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type
156+
%res = apply %func(%0) : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type
157+
%objctype = thick_to_objc_metatype %res : $@thick AnyObject.Type to $@objc_metatype AnyObject.Type
158+
%thicktype = objc_to_thick_metatype %objctype : $@objc_metatype AnyObject.Type to $@thick AnyObject.Type
159+
return %thicktype : $@thick AnyObject.Type
160+
}
161+
162+
// class_copyMethodList
163+
sil [serializable] [clang class_copyMethodList] @class_copyMethodList : $@convention(c) (Optional<@objc_metatype AnyObject.Type>, Optional<UnsafeMutablePointer<UInt32>>) -> Optional<UnsafeMutablePointer<OpaquePointer>>
164+
sil [serializable] @foo : $@convention(thin) (@guaranteed AnyObject) -> @thick AnyObject.Type

0 commit comments

Comments
 (0)