From 8155707ee3677e4bd3ac372266732287a78e86e2 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 27 Feb 2018 10:34:08 -0800 Subject: [PATCH] MandatoryInlining: Add a peephole for inlining thorough a thin to noescape conversion %0 = function_ref @return_one : $@convention(thin) () -> Builtin.Int32 %1 = convert_function %0 : $@convention(thin) () -> Builtin.Int32 to $@convention(thin) @noescape () -> Builtin.Int32 %2 = thin_to_thick_function %1 : $@convention(thin) @noescape () -> Builtin.Int32 to $@noescape () -> Builtin.Int32 %3 = apply %2() : $@noescape () -> Builtin.Int32 rdar://37945226 --- .../Mandatory/MandatoryInlining.cpp | 21 +++++++++++++++++++ test/SILOptimizer/mandatory_inlining.sil | 20 ++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index c1065d8e2293b..8536f24a91260 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -319,6 +319,27 @@ static SILFunction *getCalleeFunction( // would be a good optimization to handle and would be as simple as inserting // a cast. auto skipFuncConvert = [](SILValue CalleeValue) { + // We can also allow a thin @escape to noescape conversion as such: + // %1 = function_ref @thin_closure_impl : $@convention(thin) () -> () + // %2 = convert_function %1 : + // $@convention(thin) () -> () to $@convention(thin) @noescape () -> () + // %3 = thin_to_thick_function %2 : + // $@convention(thin) @noescape () -> () to + // $@noescape @callee_guaranteed () -> () + // %4 = apply %3() : $@noescape @callee_guaranteed () -> () + if (auto *ThinToNoescapeCast = dyn_cast(CalleeValue)) { + auto FromCalleeTy = + ThinToNoescapeCast->getOperand()->getType().castTo(); + if (FromCalleeTy->getExtInfo().hasContext()) + return CalleeValue; + auto ToCalleeTy = ThinToNoescapeCast->getType().castTo(); + auto EscapingCalleeTy = ToCalleeTy->getWithExtInfo( + ToCalleeTy->getExtInfo().withNoEscape(false)); + if (FromCalleeTy != EscapingCalleeTy) + return CalleeValue; + return ThinToNoescapeCast->getOperand(); + } + auto *CFI = dyn_cast(CalleeValue); if (!CFI) return CalleeValue; diff --git a/test/SILOptimizer/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil index a5f2683b5fc7c..911be326b99a7 100644 --- a/test/SILOptimizer/mandatory_inlining.sil +++ b/test/SILOptimizer/mandatory_inlining.sil @@ -1184,3 +1184,23 @@ bb0(%0: $C): apply %closure() : $@callee_guaranteed () -> () return %closure : $@callee_guaranteed () -> () } + + +sil [transparent] @return_one : $@convention(thin) () -> Builtin.Int32 { +bb0: + %0 = integer_literal $Builtin.Int32, 1 + return %0 : $Builtin.Int32 +} + +// CHECK-LABEL: sil @test_thin_convert_function_inline +// CHECK-NEXT: bb0 +// CHECK-NEXT: [[RES:%.*]] = integer_literal $Builtin.Int32, 1 +// CHECK-NEXT return [[RES]] +sil @test_thin_convert_function_inline : $@convention(thin) () -> Builtin.Int32 { +bb0: + %0 = function_ref @return_one : $@convention(thin) () -> Builtin.Int32 + %1 = convert_function %0 : $@convention(thin) () -> Builtin.Int32 to $@convention(thin) @noescape () -> Builtin.Int32 + %2 = thin_to_thick_function %1 : $@convention(thin) @noescape () -> Builtin.Int32 to $@noescape () -> Builtin.Int32 + %3 = apply %2() : $@noescape () -> Builtin.Int32 + return %3 : $Builtin.Int32 +}