Skip to content

Commit c7f8657

Browse files
authored
Merge pull request #8723 from swiftix/wip-partial-pre-specialization-fixes
[eager-specializer] Handle functions with don’t have return basic blocks
2 parents 69e6f07 + 01e0ffd commit c7f8657

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/SILOptimizer/IPO/EagerSpecializer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,10 @@ class EagerDispatch {
324324
/// given specialized function. Converts call arguments. Emits an invocation of
325325
/// the specialized function. Handle the return value.
326326
void EagerDispatch::emitDispatchTo(SILFunction *NewFunc) {
327-
SILBasicBlock *OldReturnBB = &*GenericFunc->findReturnBB();
327+
SILBasicBlock *OldReturnBB = nullptr;
328+
auto ReturnBB = GenericFunc->findReturnBB();
329+
if (ReturnBB != GenericFunc->end())
330+
OldReturnBB = &*ReturnBB;
328331
// 1. Emit a cascading sequence of type checks blocks.
329332

330333
// First split the entry BB, moving all instructions to the FailedTypeCheckBB.
@@ -395,7 +398,7 @@ void EagerDispatch::emitDispatchTo(SILFunction *NewFunc) {
395398
Result = Builder.createTuple(Loc, VoidTy, { });
396399

397400
// Function marked as @NoReturn must be followed by 'unreachable'.
398-
if (NewFunc->isNoReturnFunction())
401+
if (NewFunc->isNoReturnFunction() || !OldReturnBB)
399402
Builder.createUnreachable(Loc);
400403
else {
401404
auto resultTy = GenericFunc->getConventions().getSILResultType();

test/SILOptimizer/eager_specialize.sil

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,57 @@ bb0(%0 : $*T, %1 : $*S):
643643
// CHECK: br bb2
644644
// CHECK: } // end sil function '_T016eager_specialize34checkExplicitPartialSpecializationyx_q_tr0_lF'
645645

646+
/////////////////////////////////////////////////////////////////////////
647+
// Check that functions with unreachable instructions can be specialized.
648+
/////////////////////////////////////////////////////////////////////////
649+
650+
protocol P {
651+
}
652+
653+
struct T : P {
654+
init()
655+
}
656+
657+
extension P {
658+
public static func f(_ x: Self) -> Self
659+
}
660+
661+
sil @error : $@convention(thin) () -> Never
662+
663+
// CHECK-LABEL: sil @_T016eager_specialize1PPAAE1fxxFZ : $@convention(method) <Self where Self : P> (@in Self, @thick Self.Type) -> @out Self
664+
// CHECK: %3 = metatype $@thick Self.Type
665+
// CHECK: %4 = metatype $@thick T.Type
666+
// CHECK: %5 = unchecked_bitwise_cast %3 : $@thick Self.Type to $Builtin.Word
667+
// CHECK: %6 = unchecked_bitwise_cast %4 : $@thick T.Type to $Builtin.Word
668+
// CHECK: %7 = builtin "cmp_eq_Word"(%5 : $Builtin.Word, %6 : $Builtin.Word) : $Builtin.Int1
669+
// CHECK: cond_br %7, bb2, bb1
670+
671+
// CHECK: bb1:
672+
// CHECK: %9 = function_ref @error : $@convention(thin) () -> Never
673+
// CHECK: %10 = apply %9() : $@convention(thin) () -> Never
674+
// CHECK: unreachable
675+
676+
// CHECK: bb2:
677+
// CHECK: %12 = unchecked_addr_cast %0 : $*Self to $*T
678+
// CHECK: %13 = unchecked_addr_cast %1 : $*Self to $*T
679+
// CHECK: %14 = load %13 : $*T
680+
// CHECK: %15 = unchecked_trivial_bit_cast %2 : $@thick Self.Type to $@thick T.Type
681+
// CHECK: %16 = function_ref @_T016eager_specialize1PPAAE1fxxFZ4main1TV_Tg5 : $@convention(method) (T, @thick T.Type) -> T
682+
// CHECK: %17 = apply %16(%14, %15) : $@convention(method) (T, @thick T.Type) -> T
683+
// CHECK: store %17 to %12 : $*T
684+
// CHECK: %19 = tuple ()
685+
// CHECK: unreachable
686+
// CHECK: } // end sil function '_T016eager_specialize1PPAAE1fxxFZ'
687+
688+
sil [_specialize exported: false, kind: full, where Self == T] @_T016eager_specialize1PPAAE1fxxFZ : $@convention(method) <Self where Self : P> (@in Self, @thick Self.Type) -> @out Self {
689+
bb0(%0 : $*Self, %1 : $*Self, %2 : $@thick Self.Type):
690+
// function_ref error
691+
%5 = function_ref @error : $@convention(thin) () -> Never
692+
%6 = apply %5() : $@convention(thin) () -> Never
693+
unreachable
694+
} // end sil function '_T016eager_specialize1PPAAE1fxxFZ'
695+
696+
646697
////////////////////////////////////////////////////////////////////
647698
// Check that IRGen generates efficient code for fixed-size Trivial
648699
// constraints.

0 commit comments

Comments
 (0)