Skip to content

Commit 484fc77

Browse files
authored
Merge pull request #70301 from eeckstein/fixed-array
Add experimental support for fixed arrays
2 parents 665eb4f + ae27805 commit 484fc77

File tree

69 files changed

+1938
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1938
-46
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AllocVectorLowering.swift

Lines changed: 457 additions & 0 deletions
Large diffs are not rendered by default.

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/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+
AllocVectorLowering.swift
1011
AssumeSingleThreaded.swift
1112
AsyncDemotion.swift
1213
CleanupDebugSteps.swift

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -394,27 +394,6 @@ private extension InstructionWorklist {
394394
}
395395
}
396396

397-
private extension Value {
398-
/// Returns true if this value is a valid in a static initializer, including all its operands.
399-
var isValidGlobalInitValue: Bool {
400-
guard let svi = self as? SingleValueInstruction else {
401-
return false
402-
}
403-
if let beginAccess = svi as? BeginAccessInst {
404-
return beginAccess.address.isValidGlobalInitValue
405-
}
406-
if !svi.isValidInStaticInitializerOfGlobal {
407-
return false
408-
}
409-
for op in svi.operands {
410-
if !op.value.isValidGlobalInitValue {
411-
return false
412-
}
413-
}
414-
return true
415-
}
416-
}
417-
418397
private extension AllocRefInstBase {
419398
var fieldsKnownStatically: Bool {
420399
if let allocDynamic = self as? AllocRefDynamicInst,

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/SimplificationPasses.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protocol LateOnoneSimplifyable : Instruction {
3737
let ononeSimplificationPass = FunctionPass(name: "onone-simplification") {
3838
(function: Function, context: FunctionPassContext) in
3939

40-
_ = runSimplification(on: function, context, preserveDebugInfo: true) {
40+
runSimplification(on: function, context, preserveDebugInfo: true) {
4141
if let i = $0 as? OnoneSimplifyable {
4242
i.simplify($1)
4343
}
@@ -47,7 +47,7 @@ let ononeSimplificationPass = FunctionPass(name: "onone-simplification") {
4747
let simplificationPass = FunctionPass(name: "simplification") {
4848
(function: Function, context: FunctionPassContext) in
4949

50-
_ = runSimplification(on: function, context, preserveDebugInfo: false) {
50+
runSimplification(on: function, context, preserveDebugInfo: false) {
5151
if let i = $0 as? Simplifyable {
5252
i.simplify($1)
5353
}
@@ -57,7 +57,7 @@ let simplificationPass = FunctionPass(name: "simplification") {
5757
let lateOnoneSimplificationPass = FunctionPass(name: "late-onone-simplification") {
5858
(function: Function, context: FunctionPassContext) in
5959

60-
_ = runSimplification(on: function, context, preserveDebugInfo: true) {
60+
runSimplification(on: function, context, preserveDebugInfo: true) {
6161
if let i = $0 as? LateOnoneSimplifyable {
6262
i.simplifyLate($1)
6363
} else if let i = $0 as? OnoneSimplifyable {
@@ -70,7 +70,7 @@ let lateOnoneSimplificationPass = FunctionPass(name: "late-onone-simplification"
7070
// Pass implementation
7171
//===--------------------------------------------------------------------===//
7272

73-
73+
@discardableResult
7474
func runSimplification(on function: Function, _ context: FunctionPassContext,
7575
preserveDebugInfo: Bool,
7676
_ simplify: (Instruction, SimplifyContext) -> ()) -> Bool {

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ extension BuiltinInst : OnoneSimplifyable {
4141
.AssignCopyArrayFrontToBack,
4242
.AssignCopyArrayBackToFront,
4343
.AssignTakeArray,
44+
.AllocVector,
4445
.IsPOD:
4546
optimizeArgumentToThinMetatype(argument: 0, context)
4647
case .CreateAsyncTask:

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,13 @@ extension Context {
4343
}
4444
}
4545

46+
var moduleIsSerialized: Bool { _bridged.moduleIsSerialized() }
47+
4648
func lookupDeinit(ofNominal: NominalTypeDecl) -> Function? {
4749
_bridged.lookUpNominalDeinitFunction(ofNominal.bridged).function
4850
}
51+
52+
func getBuiltinIntegerType(bitWidth: Int) -> Type { _bridged.getBuiltinIntegerType(bitWidth).type }
4953
}
5054

5155
/// A context which allows mutation of a function's SIL.
@@ -494,6 +498,11 @@ extension Instruction {
494498
bridged.setOperand(index, value.bridged)
495499
context.notifyInstructionChanged(self)
496500
}
501+
502+
func move(before otherInstruction: Instruction, _ context: some MutatingContext) {
503+
BridgedPassContext.moveInstructionBefore(bridged, otherInstruction.bridged)
504+
context.notifyInstructionsChanged()
505+
}
497506
}
498507

499508
extension BuiltinInst {

SwiftCompilerSources/Sources/Optimizer/PassManager/Options.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ struct Options {
2929
}
3030

3131
var enableEmbeddedSwift: Bool {
32-
_bridged.enableEmbeddedSwift()
32+
_bridged.hasFeature(.Embedded)
33+
}
34+
35+
func hasFeature(_ feature: BridgedPassContext.Feature) -> Bool {
36+
_bridged.hasFeature(feature)
3337
}
3438

3539
enum AssertConfiguration {

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ private func registerSwiftPasses() {
6565
registerPass(stackProtection, { stackProtection.run($0) })
6666

6767
// Function passes
68+
registerPass(allocVectorLowering, { allocVectorLowering.run($0) })
6869
registerPass(asyncDemotion, { asyncDemotion.run($0) })
6970
registerPass(letPropertyLowering, { letPropertyLowering.run($0) })
7071
registerPass(mergeCondFailsPass, { mergeCondFailsPass.run($0) })

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,37 @@ extension Value {
131131
}
132132
return builder.createCopyValue(operand: self)
133133
}
134+
135+
/// True if this value is a valid in a static initializer, including all its operands.
136+
var isValidGlobalInitValue: Bool {
137+
guard let svi = self as? SingleValueInstruction else {
138+
return false
139+
}
140+
if let beginAccess = svi as? BeginAccessInst {
141+
return beginAccess.address.isValidGlobalInitValue
142+
}
143+
if !svi.isValidInStaticInitializerOfGlobal {
144+
return false
145+
}
146+
for op in svi.operands {
147+
if !op.value.isValidGlobalInitValue {
148+
return false
149+
}
150+
}
151+
return true
152+
}
153+
}
154+
155+
extension FullApplySite {
156+
func isSemanticCall(_ name: StaticString, withArgumentCount: Int) -> Bool {
157+
if arguments.count == withArgumentCount,
158+
let callee = referencedFunction,
159+
callee.hasSemanticsAttribute(name)
160+
{
161+
return true
162+
}
163+
return false
164+
}
134165
}
135166

136167
extension Builder {

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public struct Builder {
7373
}
7474
}
7575

76+
@discardableResult
7677
public func createCondFail(condition: Value, message: String) -> CondFailInst {
7778
return message._withBridgedStringRef { messageStr in
7879
let cf = bridged.createCondFail(condition.bridged, messageStr)
@@ -91,6 +92,11 @@ public struct Builder {
9192
return notifyNew(dr.getAs(AllocStackInst.self))
9293
}
9394

95+
public func createAllocVector(capacity: Value, elementType: Type) -> AllocVectorInst {
96+
let dr = bridged.createAllocVector(capacity.bridged, elementType.bridged)
97+
return notifyNew(dr.getAs(AllocVectorInst.self))
98+
}
99+
94100
@discardableResult
95101
public func createDeallocStack(_ operand: Value) -> DeallocStackInst {
96102
let dr = bridged.createDeallocStack(operand.bridged)
@@ -103,6 +109,12 @@ public struct Builder {
103109
return notifyNew(dr.getAs(DeallocStackRefInst.self))
104110
}
105111

112+
public func createAddressToPointer(address: Value, pointerType: Type,
113+
needStackProtection: Bool) -> AddressToPointerInst {
114+
let dr = bridged.createAddressToPointer(address.bridged, pointerType.bridged, needStackProtection)
115+
return notifyNew(dr.getAs(AddressToPointerInst.self))
116+
}
117+
106118
public func createUncheckedRefCast(from value: Value, to type: Type) -> UncheckedRefCastInst {
107119
let cast = bridged.createUncheckedRefCast(value.bridged, type.bridged)
108120
return notifyNew(cast.getAs(UncheckedRefCastInst.self))
@@ -118,6 +130,11 @@ public struct Builder {
118130
return notifyNew(load.getAs(LoadInst.self))
119131
}
120132

133+
public func createLoadBorrow(fromAddress: Value) -> LoadBorrowInst {
134+
let load = bridged.createLoadBorrow(fromAddress.bridged)
135+
return notifyNew(load.getAs(LoadBorrowInst.self))
136+
}
137+
121138
public func createBeginDeallocRef(reference: Value, allocation: AllocRefInstBase) -> BeginDeallocRefInst {
122139
let beginDealloc = bridged.createBeginDeallocRef(reference.bridged, allocation.bridged)
123140
return notifyNew(beginDealloc.getAs(BeginDeallocRefInst.self))
@@ -280,6 +297,14 @@ public struct Builder {
280297
return notifyNew(objectInst.getAs(ObjectInst.self))
281298
}
282299

300+
@discardableResult
301+
public func createVector(type: Type, arguments: [Value]) -> VectorInst {
302+
let vectorInst = arguments.withBridgedValues { valuesRef in
303+
return bridged.createVector(valuesRef)
304+
}
305+
return notifyNew(vectorInst.getAs(VectorInst.self))
306+
}
307+
283308
public func createGlobalAddr(global: GlobalVariable) -> GlobalAddrInst {
284309
return notifyNew(bridged.createGlobalAddr(global.bridged).getAs(GlobalAddrInst.self))
285310
}

SwiftCompilerSources/Sources/SIL/GlobalVariable.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ extension Instruction {
142142
is IntegerLiteralInst,
143143
is FloatLiteralInst,
144144
is ObjectInst,
145+
is VectorInst,
146+
is AllocVectorInst,
145147
is ValueToBridgeObjectInst,
146148
is ConvertFunctionInst,
147149
is ThinToThickFunctionInst,

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,9 @@ final public class ObjectInst : SingleValueInstruction {
974974
}
975975
}
976976

977+
final public class VectorInst : SingleValueInstruction {
978+
}
979+
977980
final public class TuplePackExtractInst: SingleValueInstruction, ForwardingInstruction {
978981
public var indexOperand: Operand { operands[0] }
979982
public var tupleOperand: Operand { operands[1] }
@@ -1001,6 +1004,10 @@ final public class AllocStackInst : SingleValueInstruction, Allocation, DebugVar
10011004
}
10021005
}
10031006

1007+
final public class AllocVectorInst : SingleValueInstruction, Allocation, UnaryInstruction {
1008+
public var capacity: Value { operand.value }
1009+
}
1010+
10041011
public class AllocRefInstBase : SingleValueInstruction, Allocation {
10051012
final public var isObjC: Bool { bridged.AllocRefInstBase_isObjc() }
10061013

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public func registerSILClasses() {
8787
register(UncheckedTrivialBitCastInst.self)
8888
register(MarkUnresolvedNonCopyableValueInst.self)
8989
register(ObjectInst.self)
90+
register(VectorInst.self)
9091
register(TuplePackExtractInst.self)
9192
register(DifferentiableFunctionInst.self)
9293
register(LinearFunctionInst.self)
@@ -161,6 +162,7 @@ public func registerSILClasses() {
161162
register(IsUniqueInst.self)
162163
register(IsEscapingClosureInst.self)
163164
register(AllocStackInst.self)
165+
register(AllocVectorInst.self)
164166
register(AllocRefInst.self)
165167
register(AllocRefDynamicInst.self)
166168
register(AllocBoxInst.self)

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ public struct TupleElementArray : RandomAccessCollection, FormattedLikeArray {
251251
}
252252

253253
extension BridgedType {
254-
var type: Type { Type(bridged: self) }
254+
public var type: Type { Type(bridged: self) }
255255
var typeOrNil: Type? { isNull() ? nil : type }
256256
}
257257

docs/SIL.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3790,6 +3790,28 @@ type, use ``alloc_box``.
37903790

37913791
``T`` must not be a pack type. To allocate a pack, use ``alloc_pack``.
37923792

3793+
alloc_vector
3794+
````````````
3795+
::
3796+
3797+
sil-instruction ::= 'alloc_vector' sil-type, sil-operand
3798+
3799+
%1 = alloc_vector $T, %0 : $Builtin.Word
3800+
// %1 has type $*T
3801+
3802+
Allocates uninitialized memory that is sufficiently aligned on the stack to
3803+
contain a vector of values of type ``T``. The result of the instruction is
3804+
the address of the allocated memory.
3805+
The number of vector elements is specified by the operand, which must be a
3806+
builtin integer value.
3807+
3808+
``alloc_vector`` either allocates memory on the stack or - if contained in a
3809+
global variable static initializer list - in the data section.
3810+
3811+
``alloc_vector`` is a stack allocation instruction, unless it's contained in a
3812+
global initializer list. See the section above on stack discipline. The
3813+
corresponding stack deallocation instruction is ``dealloc_stack``.
3814+
37933815
alloc_pack
37943816
``````````
37953817

@@ -6689,6 +6711,20 @@ object
66896711
Constructs a statically initialized object. This instruction can only appear
66906712
as final instruction in a global variable static initializer list.
66916713

6714+
vector
6715+
``````
6716+
6717+
::
6718+
6719+
sil-instruction ::= 'vector' '(' (sil-operand (',' sil-operand)*)? ')'
6720+
6721+
vector (%a : $T, %b : $T, ...)
6722+
// $T must be a non-generic or bound generic reference type
6723+
// All operands must have the same type
6724+
6725+
Constructs a statically initialized vector of elements. This instruction can only appear
6726+
as final instruction in a global variable static initializer list.
6727+
66926728
ref_element_addr
66936729
````````````````
66946730
::

include/swift/AST/Builtins.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@ BUILTIN_MISC_OPERATION(UnprotectedStackAlloc, "unprotectedStackAlloc", "", Speci
646646
/// Builtin.stackAlloc(), is deallocated from the stack.
647647
BUILTIN_MISC_OPERATION(StackDealloc, "stackDealloc", "", Special)
648648

649+
/// allocVector<Element>(Element.Type, Builtin.Word) -> Builtin.RawPointer
650+
BUILTIN_MISC_OPERATION(AllocVector, "allocVector", "", Special)
651+
649652
/// Fence has type () -> ().
650653
BUILTIN_MISC_OPERATION(Fence, "fence", "", None)
651654

include/swift/AST/DiagnosticsSIL.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,5 +899,13 @@ ERROR(regionbasedisolation_unknown_pattern, none,
899899
ERROR(deinit_not_visible, none,
900900
"deinit of non-copyable type not visible in the current module", ())
901901

902+
ERROR(lifetime_value_outside_scope, none,
903+
"lifetime-dependent value escapes its scope", ())
904+
ERROR(vector_capacity_not_constant, none,
905+
"vector capacity needs to be constant", ())
906+
907+
ERROR(fixed_arrays_not_available, none,
908+
"fixed arrays are only available with -enable-experimental-feature FixedArrays", ())
909+
902910
#define UNDEFINE_DIAGNOSTIC_MACROS
903911
#include "DefineDiagnosticMacros.h"

include/swift/AST/SemanticAttrs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized")
6464
SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic")
6565
SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic")
6666
SEMANTICS_ATTR(ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE, "array.getContiguousArrayStorageType")
67+
SEMANTICS_ATTR(ARRAY_COPY_INTO_VECTOR, "array.copy_into_vector")
6768

6869
SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach")
6970
SEMANTICS_ATTR(TYPENAME, "typeName")

include/swift/Basic/Features.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ LANGUAGE_FEATURE(BuiltinCreateAsyncTaskInGroup, 0, "MainActor executor building
8989
LANGUAGE_FEATURE(BuiltinCopy, 0, "Builtin.copy()", true)
9090
LANGUAGE_FEATURE(BuiltinStackAlloc, 0, "Builtin.stackAlloc", true)
9191
LANGUAGE_FEATURE(BuiltinUnprotectedStackAlloc, 0, "Builtin.unprotectedStackAlloc", true)
92+
LANGUAGE_FEATURE(BuiltinAllocVector, 0, "Builtin.allocVector", true)
9293
LANGUAGE_FEATURE(BuiltinTaskRunInline, 0, "Builtin.taskRunInline", true)
9394
LANGUAGE_FEATURE(BuiltinUnprotectedAddressOf, 0, "Builtin.unprotectedAddressOf", true)
9495
LANGUAGE_FEATURE(NewCxxMethodSafetyHeuristics, 0, "Only import C++ methods that return pointers (projections) on owned types as unsafe", true)
@@ -271,6 +272,9 @@ EXPERIMENTAL_FEATURE(ExtractConstantsFromMembers, false)
271272
/// Enable bitwise-copyable feature.
272273
EXPERIMENTAL_FEATURE(BitwiseCopyable, true)
273274

275+
/// Enables the FixedArray data type.
276+
EXPERIMENTAL_FEATURE(FixedArrays, false)
277+
274278
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
275279
#undef EXPERIMENTAL_FEATURE
276280
#undef UPCOMING_FEATURE

0 commit comments

Comments
 (0)