Skip to content

Commit 438bbd5

Browse files
committed
Optimizer: add simplification for the convert_escape_to_noescape instruction
Including the required bridging stuff. %2 = thin_to_thick_function %1 to $() -> () %3 = convert_escape_to_noescape %2 : $() -> () to $@NoEscape () -> () -> %3 = thin_to_thick_function %1 to $@NoEscape () -> ()
1 parent 83ce16f commit 438bbd5

File tree

9 files changed

+97
-0
lines changed

9 files changed

+97
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ swift_compiler_sources(Optimizer
1313
SimplifyBuiltin.swift
1414
SimplifyCondBranch.swift
1515
SimplifyCondFail.swift
16+
SimplifyConvertEscapeToNoEscape.swift
1617
SimplifyDebugStep.swift
1718
SimplifyDestructure.swift
1819
SimplifyGlobalValue.swift
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===--- SimplifyConvertEscapeToNoEscape.swift ----------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
15+
extension ConvertEscapeToNoEscapeInst : OnoneSimplifyable {
16+
func simplify(_ context: SimplifyContext) {
17+
tryCombineWithThinToThickOperand(context)
18+
}
19+
}
20+
21+
private extension ConvertEscapeToNoEscapeInst {
22+
23+
/// Combine with a thin_to_thick_function operand:
24+
///
25+
/// %2 = thin_to_thick_function %1 to $() -> ()
26+
/// %3 = convert_escape_to_noescape %2 : $() -> () to $@noescape () -> ()
27+
/// ->
28+
/// %3 = thin_to_thick_function %1 to $@noescape () -> ()
29+
30+
func tryCombineWithThinToThickOperand(_ context: SimplifyContext) {
31+
if let thinToThick = fromFunction as? ThinToThickFunctionInst {
32+
let builder = Builder(before: self, context)
33+
let noEscapeFnType = thinToThick.type.getFunctionType(withNoEscape: true)
34+
let newThinToThick = builder.createThinToThickFunction(thinFunction: thinToThick.operand.value,
35+
resultType: noEscapeFnType)
36+
uses.replaceAll(with: newThinToThick, context)
37+
context.erase(instruction: self)
38+
}
39+
}
40+
}

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ public struct Builder {
220220
return notifyNew(enumInst.getAs(EnumInst.self))
221221
}
222222

223+
public func createThinToThickFunction(thinFunction: Value, resultType: Type) -> ThinToThickFunctionInst {
224+
let tttf = bridged.createThinToThickFunction(thinFunction.bridged, resultType.bridged)
225+
return notifyNew(tttf.getAs(ThinToThickFunctionInst.self))
226+
}
227+
223228
@discardableResult
224229
public func createSwitchEnum(enum enumVal: Value,
225230
cases: [(Int, BasicBlock)],

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,11 @@ class ConvertFunctionInst : SingleValueInstruction, ConversionInstruction {
794794
final public
795795
class ThinToThickFunctionInst : SingleValueInstruction, ConversionInstruction {}
796796

797+
final public
798+
class ConvertEscapeToNoEscapeInst : SingleValueInstruction, UnaryInstruction {
799+
public var fromFunction: Value { operand.value }
800+
}
801+
797802
final public
798803
class ObjCExistentialMetatypeToObjectInst : SingleValueInstruction,
799804
ConversionInstruction {}

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ public func registerSILClasses() {
131131
register(UnconditionalCheckedCastInst.self)
132132
register(ConvertFunctionInst.self)
133133
register(ThinToThickFunctionInst.self)
134+
register(ConvertEscapeToNoEscapeInst.self)
134135
register(ObjCExistentialMetatypeToObjectInst.self)
135136
register(ObjCMetatypeToObjectInst.self)
136137
register(ValueToBridgeObjectInst.self)

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
111111
return idx >= 0 ? idx : nil
112112
}
113113

114+
public func getFunctionType(withNoEscape: Bool) -> Type {
115+
bridged.getFunctionTypeWithNoEscape(withNoEscape).type
116+
}
117+
114118
public var description: String {
115119
String(taking: bridged.getDebugDescription())
116120
}

include/swift/SIL/SILBridging.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ struct BridgedType {
129129
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef getFieldName(SwiftInt idx) const;
130130
BRIDGED_INLINE SwiftInt getNumTupleElements() const;
131131
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getTupleElementType(SwiftInt idx) const;
132+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getFunctionTypeWithNoEscape(bool withNoEscape) const;
132133
};
133134

134135
// AST bridging
@@ -899,6 +900,8 @@ struct BridgedBuilder{
899900
SwiftInt caseIdx, BridgedType resultType) const;
900901
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createEnum(SwiftInt caseIdx, OptionalBridgedValue payload,
901902
BridgedType resultType) const;
903+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createThinToThickFunction(BridgedValue fn,
904+
BridgedType resultType) const;
902905
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createBranch(BridgedBasicBlock destBlock,
903906
BridgedValueArray arguments) const;
904907
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createUnreachable() const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,12 @@ BridgedType BridgedType::getTupleElementType(SwiftInt idx) const {
217217
return get().getTupleElementType(idx);
218218
}
219219

220+
BridgedType BridgedType::getFunctionTypeWithNoEscape(bool withNoEscape) const {
221+
auto fnType = get().getAs<swift::SILFunctionType>();
222+
auto newTy = fnType->getWithExtInfo(fnType->getExtInfo().withNoEscape(true));
223+
return swift::SILType::getPrimitiveObjectType(newTy);
224+
}
225+
220226
//===----------------------------------------------------------------------===//
221227
// BridgedNominalTypeDecl
222228
//===----------------------------------------------------------------------===//
@@ -1352,6 +1358,10 @@ BridgedInstruction BridgedBuilder::createEnum(SwiftInt caseIdx, OptionalBridgedV
13521358
return {get().createEnum(regularLoc(), pl, caseDecl, resultType.get())};
13531359
}
13541360

1361+
BridgedInstruction BridgedBuilder::createThinToThickFunction(BridgedValue fn, BridgedType resultType) const {
1362+
return {get().createThinToThickFunction(regularLoc(), fn.getSILValue(), resultType.get())};
1363+
}
1364+
13551365
BridgedInstruction BridgedBuilder::createBranch(BridgedBasicBlock destBlock, BridgedValueArray arguments) const {
13561366
llvm::SmallVector<swift::SILValue, 16> argValues;
13571367
return {get().createBranch(regularLoc(), destBlock.get(), arguments.getValues(argValues))};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=convert_escape_to_noescape | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
sil_stage canonical
6+
7+
import Builtin
8+
import Swift
9+
import SwiftShims
10+
11+
sil @cl : $@convention(thin) () -> Int
12+
13+
// CHECK-LABEL: sil [ossa] @remove_convert :
14+
// CHECK: [[F:%.*]] = thin_to_thick_function %0 : $@convention(thin) () -> Int to $@noescape @callee_guaranteed () -> Int
15+
// CHECK-NEXT: apply [[F]]() : $@noescape
16+
// CHECK-NEXT: destroy_value [[F]]
17+
// CHECK: } // end sil function 'remove_convert'
18+
sil [ossa] @remove_convert : $@convention(thin) () -> Int {
19+
bb0:
20+
%0 = function_ref @cl : $@convention(thin) () -> Int
21+
%1 = thin_to_thick_function %0 : $@convention(thin) () -> Int to $@callee_guaranteed () -> Int
22+
%2 = convert_escape_to_noescape %1 : $@callee_guaranteed () -> Int to $@noescape @callee_guaranteed () -> Int
23+
%3 = apply %2() : $@noescape @callee_guaranteed () -> Int
24+
destroy_value %2 : $@noescape @callee_guaranteed () -> Int
25+
return %3 : $Int
26+
}
27+
28+

0 commit comments

Comments
 (0)