Skip to content

Commit d3c5149

Browse files
authored
Merge pull request swiftlang#76658 from kubamracek/embedded-managed-buffer
[embedded] Add support for ManagedBuffer to Embedded Swift
2 parents ea23b8a + 0b50c21 commit d3c5149

File tree

12 files changed

+229
-1
lines changed

12 files changed

+229
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
swift_compiler_sources(Optimizer
10+
SimplifyAllocRefDynamic.swift
1011
SimplifyApply.swift
1112
SimplifyBeginBorrow.swift
1213
SimplifyBeginCOWMutation.swift
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===--- SimplifyAllocRefDynamic.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 AllocRefDynamicInst : OnoneSimplifyable {
16+
func simplify(_ context: SimplifyContext) {
17+
/// Optimize alloc_ref_dynamic of a known type to alloc_ref:
18+
///
19+
/// %3 = metatype SubClass.Type
20+
/// %4 = upcast %3 : SubClass.Type to BaseClass.Type
21+
/// %6 = alloc_ref_dynamic [...] %4 : BaseClass.Type, $BaseClass
22+
/// %8 = (... some use of ...) %6 : $BaseClass
23+
/// ->
24+
/// %6 = alloc_ref [...] $SubClass
25+
/// %7 = upcast %6 : $SubClass to $BaseClass
26+
/// %8 = (... some use of ...) %7 : $BaseClass
27+
28+
let type: Type
29+
let emitUpcast: Bool
30+
if let metatypeInst = metatypeOperand.value as? MetatypeInst {
31+
type = metatypeInst.type.loweredInstanceTypeOfMetatype(in: parentFunction)
32+
emitUpcast = false
33+
} else if let upcastInst = metatypeOperand.value as? UpcastInst,
34+
let metatypeInst = upcastInst.operands[0].value as? MetatypeInst {
35+
type = metatypeInst.type.loweredInstanceTypeOfMetatype(in: parentFunction)
36+
emitUpcast = true
37+
} else {
38+
return
39+
}
40+
41+
let builder = Builder(before: self, context)
42+
let newAlloc = builder.createAllocRef(type, isObjC: self.isObjC, canAllocOnStack: self.canAllocOnStack, isBare: false,
43+
tailAllocatedTypes: self.tailAllocatedTypes, tailAllocatedCounts: Array(self.tailAllocatedCounts.values))
44+
45+
let result: Value
46+
if emitUpcast {
47+
result = builder.createUpcast(from: newAlloc, to: self.type)
48+
} else {
49+
result = newAlloc
50+
}
51+
uses.replaceAll(with: result, context)
52+
context.erase(instruction: self)
53+
}
54+
}

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ public struct Builder {
8989
let literal = bridged.createIntegerLiteral(type.bridged, value)
9090
return notifyNew(literal.getAs(IntegerLiteralInst.self))
9191
}
92+
93+
public func createAllocRef(_ type: Type, isObjC: Bool = false, canAllocOnStack: Bool = false, isBare: Bool = false,
94+
tailAllocatedTypes: TypeArray, tailAllocatedCounts: [Value]) -> AllocRefInst {
95+
return tailAllocatedCounts.withBridgedValues { countsRef in
96+
let dr = bridged.createAllocRef(type.bridged, isObjC, canAllocOnStack, isBare, tailAllocatedTypes.bridged, countsRef)
97+
return notifyNew(dr.getAs(AllocRefInst.self))
98+
}
99+
}
92100

93101
public func createAllocStack(_ type: Type, hasDynamicLifetime: Bool = false,
94102
isLexical: Bool = false, isFromVarDecl: Bool = false,

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,11 @@ final public class AllocRefDynamicInst : AllocRefInstBase {
11961196
public var isDynamicTypeDeinitAndSizeKnownEquivalentToBaseType: Bool {
11971197
bridged.AllocRefDynamicInst_isDynamicTypeDeinitAndSizeKnownEquivalentToBaseType()
11981198
}
1199+
1200+
public var metatypeOperand: Operand {
1201+
let numTailTypes = bridged.AllocRefInstBase_getNumTailTypes()
1202+
return operands[numTailTypes]
1203+
}
11991204
}
12001205

12011206
final public class AllocBoxInst : SingleValueInstruction, Allocation, DebugVariableInstruction {

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ extension Type: Equatable {
207207
}
208208

209209
public struct TypeArray : RandomAccessCollection, CustomReflectable {
210-
private let bridged: BridgedSILTypeArray
210+
public let bridged: BridgedSILTypeArray
211211

212212
public var startIndex: Int { return 0 }
213213
public var endIndex: Int { return bridged.getCount() }

docs/EmbeddedSwift/EmbeddedSwiftStatus.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ This status table describes which of the following standard library features can
4343
| Integer parsing | No |
4444
| KeyPaths | Partial (only compile-time constant key paths to stored properties supported, only usable in MemoryLayout and UnsafePointer APIs) |
4545
| Lazy collections | No |
46+
| ManagedBuffer | Yes |
4647
| Mirror (runtime reflection) | No, intentionally unsupported long-term |
4748
| Objective-C bridging | No, intentionally unsupported long-term |
4849
| Optional | Yes |

include/swift/SIL/SILBridging.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,11 @@ struct BridgedBuilder{
13061306
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createCondFail(BridgedValue condition,
13071307
BridgedStringRef message) const;
13081308
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createIntegerLiteral(BridgedType type, SwiftInt value) const;
1309+
1310+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createAllocRef(BridgedType type,
1311+
bool objc, bool canAllocOnStack, bool isBare,
1312+
BridgedSILTypeArray elementTypes, BridgedValueArray elementCountOperands) const;
1313+
13091314
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction
13101315
createAllocStack(BridgedType type, bool hasDynamicLifetime, bool isLexical,
13111316
bool isFromVarDecl, bool wasMoved) const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,17 @@ BridgedInstruction BridgedBuilder::createIntegerLiteral(BridgedType type, SwiftI
16281628
unbridged().createIntegerLiteral(regularLoc(), type.unbridged(), value)};
16291629
}
16301630

1631+
BridgedInstruction BridgedBuilder::createAllocRef(BridgedType type,
1632+
bool objc, bool canAllocOnStack, bool isBare,
1633+
BridgedSILTypeArray elementTypes, BridgedValueArray elementCountOperands) const {
1634+
llvm::SmallVector<swift::SILValue, 16> elementCountOperandsValues;
1635+
return {unbridged().createAllocRef(
1636+
regularLoc(), type.unbridged(), objc, canAllocOnStack, isBare,
1637+
elementTypes.unbridged(),
1638+
elementCountOperands.getValues(elementCountOperandsValues)
1639+
)};
1640+
}
1641+
16311642
BridgedInstruction BridgedBuilder::createAllocStack(BridgedType type,
16321643
bool hasDynamicLifetime,
16331644
bool isLexical,

stdlib/public/core/EmbeddedRuntime.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ public func swift_dynamicCastClass(object: UnsafeMutableRawPointer, targetMetada
206206
return object
207207
}
208208

209+
@_cdecl("swift_dynamicCastClassUnconditional")
210+
public func swift_dynamicCastClassUnconditional(object: UnsafeMutableRawPointer, targetMetadata: UnsafeRawPointer,
211+
file: UnsafePointer<CChar>, line: CUnsignedInt, column: CUnsignedInt) -> UnsafeMutableRawPointer {
212+
guard let result = swift_dynamicCastClass(object: object, targetMetadata: targetMetadata) else {
213+
Builtin.int_trap()
214+
}
215+
return result
216+
}
217+
209218
@_cdecl("swift_isUniquelyReferenced_native")
210219
public func swift_isUniquelyReferenced_native(object: Builtin.RawPointer) -> Bool {
211220
if !isValidPointerForNativeRetain(object: object) { return false }

stdlib/public/core/ManagedBuffer.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ extension ManagedBuffer where Element: ~Copyable {
7777
/// an initial `Header`.
7878
@_preInverseGenerics
7979
@inlinable
80+
#if $Embedded
81+
// Transparent in Embedded Swift to avoid needing "self" as a metatype. By
82+
// inlining into the caller, we'll know the concrete type instead.
83+
@_transparent
84+
#endif
8085
public final class func create(
8186
minimumCapacity: Int,
8287
makingHeaderWith factory: (ManagedBuffer<Header, Element>) throws -> Header
@@ -290,7 +295,9 @@ public struct ManagedBufferPointer<
290295
@_preInverseGenerics
291296
@inlinable
292297
public init(unsafeBufferObject buffer: AnyObject) {
298+
#if !$Embedded
293299
ManagedBufferPointer._checkValidBufferClass(type(of: buffer))
300+
#endif
294301

295302
self._nativeBuffer = Builtin.unsafeCastToNativeObject(buffer)
296303
}
@@ -308,7 +315,10 @@ public struct ManagedBufferPointer<
308315
@_preInverseGenerics
309316
@inlinable
310317
internal init(_uncheckedUnsafeBufferObject buffer: AnyObject) {
318+
#if !$Embedded
311319
ManagedBufferPointer._internalInvariantValidBufferClass(type(of: buffer))
320+
#endif
321+
312322
self._nativeBuffer = Builtin.unsafeCastToNativeObject(buffer)
313323
}
314324

0 commit comments

Comments
 (0)