Skip to content

Add experimental support for fixed arrays #70301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors

swift_compiler_sources(Optimizer
AllocVectorLowering.swift
AssumeSingleThreaded.swift
AsyncDemotion.swift
CleanupDebugSteps.swift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,27 +394,6 @@ private extension InstructionWorklist {
}
}

private extension Value {
/// Returns true if this value is a valid in a static initializer, including all its operands.
var isValidGlobalInitValue: Bool {
guard let svi = self as? SingleValueInstruction else {
return false
}
if let beginAccess = svi as? BeginAccessInst {
return beginAccess.address.isValidGlobalInitValue
}
if !svi.isValidInStaticInitializerOfGlobal {
return false
}
for op in svi.operands {
if !op.value.isValidGlobalInitValue {
return false
}
}
return true
}
}

private extension AllocRefInstBase {
var fieldsKnownStatically: Bool {
if let allocDynamic = self as? AllocRefDynamicInst,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protocol LateOnoneSimplifyable : Instruction {
let ononeSimplificationPass = FunctionPass(name: "onone-simplification") {
(function: Function, context: FunctionPassContext) in

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

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

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


@discardableResult
func runSimplification(on function: Function, _ context: FunctionPassContext,
preserveDebugInfo: Bool,
_ simplify: (Instruction, SimplifyContext) -> ()) -> Bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extension BuiltinInst : OnoneSimplifyable {
.AssignCopyArrayFrontToBack,
.AssignCopyArrayBackToFront,
.AssignTakeArray,
.AllocVector,
.IsPOD:
optimizeArgumentToThinMetatype(argument: 0, context)
case .CreateAsyncTask:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ extension Context {
}
}

var moduleIsSerialized: Bool { _bridged.moduleIsSerialized() }

func lookupDeinit(ofNominal: NominalTypeDecl) -> Function? {
_bridged.lookUpNominalDeinitFunction(ofNominal.bridged).function
}

func getBuiltinIntegerType(bitWidth: Int) -> Type { _bridged.getBuiltinIntegerType(bitWidth).type }
}

/// A context which allows mutation of a function's SIL.
Expand Down Expand Up @@ -494,6 +498,11 @@ extension Instruction {
bridged.setOperand(index, value.bridged)
context.notifyInstructionChanged(self)
}

func move(before otherInstruction: Instruction, _ context: some MutatingContext) {
BridgedPassContext.moveInstructionBefore(bridged, otherInstruction.bridged)
context.notifyInstructionsChanged()
}
}

extension BuiltinInst {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ struct Options {
}

var enableEmbeddedSwift: Bool {
_bridged.enableEmbeddedSwift()
_bridged.hasFeature(.Embedded)
}

func hasFeature(_ feature: BridgedPassContext.Feature) -> Bool {
_bridged.hasFeature(feature)
}

enum AssertConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private func registerSwiftPasses() {
registerPass(stackProtection, { stackProtection.run($0) })

// Function passes
registerPass(allocVectorLowering, { allocVectorLowering.run($0) })
registerPass(asyncDemotion, { asyncDemotion.run($0) })
registerPass(letPropertyLowering, { letPropertyLowering.run($0) })
registerPass(mergeCondFailsPass, { mergeCondFailsPass.run($0) })
Expand Down
31 changes: 31 additions & 0 deletions SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,37 @@ extension Value {
}
return builder.createCopyValue(operand: self)
}

/// True if this value is a valid in a static initializer, including all its operands.
var isValidGlobalInitValue: Bool {
guard let svi = self as? SingleValueInstruction else {
return false
}
if let beginAccess = svi as? BeginAccessInst {
return beginAccess.address.isValidGlobalInitValue
}
if !svi.isValidInStaticInitializerOfGlobal {
return false
}
for op in svi.operands {
if !op.value.isValidGlobalInitValue {
return false
}
}
return true
}
}

extension FullApplySite {
func isSemanticCall(_ name: StaticString, withArgumentCount: Int) -> Bool {
if arguments.count == withArgumentCount,
let callee = referencedFunction,
callee.hasSemanticsAttribute(name)
{
return true
}
return false
}
}

extension Builder {
Expand Down
25 changes: 25 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public struct Builder {
}
}

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

public func createAllocVector(capacity: Value, elementType: Type) -> AllocVectorInst {
let dr = bridged.createAllocVector(capacity.bridged, elementType.bridged)
return notifyNew(dr.getAs(AllocVectorInst.self))
}

@discardableResult
public func createDeallocStack(_ operand: Value) -> DeallocStackInst {
let dr = bridged.createDeallocStack(operand.bridged)
Expand All @@ -103,6 +109,12 @@ public struct Builder {
return notifyNew(dr.getAs(DeallocStackRefInst.self))
}

public func createAddressToPointer(address: Value, pointerType: Type,
needStackProtection: Bool) -> AddressToPointerInst {
let dr = bridged.createAddressToPointer(address.bridged, pointerType.bridged, needStackProtection)
return notifyNew(dr.getAs(AddressToPointerInst.self))
}

public func createUncheckedRefCast(from value: Value, to type: Type) -> UncheckedRefCastInst {
let cast = bridged.createUncheckedRefCast(value.bridged, type.bridged)
return notifyNew(cast.getAs(UncheckedRefCastInst.self))
Expand All @@ -118,6 +130,11 @@ public struct Builder {
return notifyNew(load.getAs(LoadInst.self))
}

public func createLoadBorrow(fromAddress: Value) -> LoadBorrowInst {
let load = bridged.createLoadBorrow(fromAddress.bridged)
return notifyNew(load.getAs(LoadBorrowInst.self))
}

public func createBeginDeallocRef(reference: Value, allocation: AllocRefInstBase) -> BeginDeallocRefInst {
let beginDealloc = bridged.createBeginDeallocRef(reference.bridged, allocation.bridged)
return notifyNew(beginDealloc.getAs(BeginDeallocRefInst.self))
Expand Down Expand Up @@ -280,6 +297,14 @@ public struct Builder {
return notifyNew(objectInst.getAs(ObjectInst.self))
}

@discardableResult
public func createVector(type: Type, arguments: [Value]) -> VectorInst {
let vectorInst = arguments.withBridgedValues { valuesRef in
return bridged.createVector(valuesRef)
}
return notifyNew(vectorInst.getAs(VectorInst.self))
}

public func createGlobalAddr(global: GlobalVariable) -> GlobalAddrInst {
return notifyNew(bridged.createGlobalAddr(global.bridged).getAs(GlobalAddrInst.self))
}
Expand Down
2 changes: 2 additions & 0 deletions SwiftCompilerSources/Sources/SIL/GlobalVariable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ extension Instruction {
is IntegerLiteralInst,
is FloatLiteralInst,
is ObjectInst,
is VectorInst,
is AllocVectorInst,
is ValueToBridgeObjectInst,
is ConvertFunctionInst,
is ThinToThickFunctionInst,
Expand Down
7 changes: 7 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,9 @@ final public class ObjectInst : SingleValueInstruction {
}
}

final public class VectorInst : SingleValueInstruction {
}

final public class TuplePackExtractInst: SingleValueInstruction, ForwardingInstruction {
public var indexOperand: Operand { operands[0] }
public var tupleOperand: Operand { operands[1] }
Expand Down Expand Up @@ -1001,6 +1004,10 @@ final public class AllocStackInst : SingleValueInstruction, Allocation, DebugVar
}
}

final public class AllocVectorInst : SingleValueInstruction, Allocation, UnaryInstruction {
public var capacity: Value { operand.value }
}

public class AllocRefInstBase : SingleValueInstruction, Allocation {
final public var isObjC: Bool { bridged.AllocRefInstBase_isObjc() }

Expand Down
2 changes: 2 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Registration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public func registerSILClasses() {
register(UncheckedTrivialBitCastInst.self)
register(MarkUnresolvedNonCopyableValueInst.self)
register(ObjectInst.self)
register(VectorInst.self)
register(TuplePackExtractInst.self)
register(DifferentiableFunctionInst.self)
register(LinearFunctionInst.self)
Expand Down Expand Up @@ -161,6 +162,7 @@ public func registerSILClasses() {
register(IsUniqueInst.self)
register(IsEscapingClosureInst.self)
register(AllocStackInst.self)
register(AllocVectorInst.self)
register(AllocRefInst.self)
register(AllocRefDynamicInst.self)
register(AllocBoxInst.self)
Expand Down
2 changes: 1 addition & 1 deletion SwiftCompilerSources/Sources/SIL/Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public struct TupleElementArray : RandomAccessCollection, FormattedLikeArray {
}

extension BridgedType {
var type: Type { Type(bridged: self) }
public var type: Type { Type(bridged: self) }
var typeOrNil: Type? { isNull() ? nil : type }
}

Expand Down
36 changes: 36 additions & 0 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3790,6 +3790,28 @@ type, use ``alloc_box``.

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

alloc_vector
````````````
::

sil-instruction ::= 'alloc_vector' sil-type, sil-operand

%1 = alloc_vector $T, %0 : $Builtin.Word
// %1 has type $*T

Allocates uninitialized memory that is sufficiently aligned on the stack to
contain a vector of values of type ``T``. The result of the instruction is
the address of the allocated memory.
The number of vector elements is specified by the operand, which must be a
builtin integer value.

``alloc_vector`` either allocates memory on the stack or - if contained in a
global variable static initializer list - in the data section.

``alloc_vector`` is a stack allocation instruction, unless it's contained in a
global initializer list. See the section above on stack discipline. The
corresponding stack deallocation instruction is ``dealloc_stack``.

alloc_pack
``````````

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

vector
``````

::

sil-instruction ::= 'vector' '(' (sil-operand (',' sil-operand)*)? ')'

vector (%a : $T, %b : $T, ...)
// $T must be a non-generic or bound generic reference type
// All operands must have the same type

Constructs a statically initialized vector of elements. This instruction can only appear
as final instruction in a global variable static initializer list.

ref_element_addr
````````````````
::
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,9 @@ BUILTIN_MISC_OPERATION(UnprotectedStackAlloc, "unprotectedStackAlloc", "", Speci
/// Builtin.stackAlloc(), is deallocated from the stack.
BUILTIN_MISC_OPERATION(StackDealloc, "stackDealloc", "", Special)

/// allocVector<Element>(Element.Type, Builtin.Word) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION(AllocVector, "allocVector", "", Special)

/// Fence has type () -> ().
BUILTIN_MISC_OPERATION(Fence, "fence", "", None)

Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -899,5 +899,13 @@ ERROR(regionbasedisolation_unknown_pattern, none,
ERROR(deinit_not_visible, none,
"deinit of non-copyable type not visible in the current module", ())

ERROR(lifetime_value_outside_scope, none,
"lifetime-dependent value escapes its scope", ())
ERROR(vector_capacity_not_constant, none,
"vector capacity needs to be constant", ())

ERROR(fixed_arrays_not_available, none,
"fixed arrays are only available with -enable-experimental-feature FixedArrays", ())

#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
1 change: 1 addition & 0 deletions include/swift/AST/SemanticAttrs.def
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized")
SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic")
SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic")
SEMANTICS_ATTR(ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE, "array.getContiguousArrayStorageType")
SEMANTICS_ATTR(ARRAY_COPY_INTO_VECTOR, "array.copy_into_vector")

SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach")
SEMANTICS_ATTR(TYPENAME, "typeName")
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ LANGUAGE_FEATURE(BuiltinCreateAsyncTaskInGroup, 0, "MainActor executor building
LANGUAGE_FEATURE(BuiltinCopy, 0, "Builtin.copy()", true)
LANGUAGE_FEATURE(BuiltinStackAlloc, 0, "Builtin.stackAlloc", true)
LANGUAGE_FEATURE(BuiltinUnprotectedStackAlloc, 0, "Builtin.unprotectedStackAlloc", true)
LANGUAGE_FEATURE(BuiltinAllocVector, 0, "Builtin.allocVector", true)
LANGUAGE_FEATURE(BuiltinTaskRunInline, 0, "Builtin.taskRunInline", true)
LANGUAGE_FEATURE(BuiltinUnprotectedAddressOf, 0, "Builtin.unprotectedAddressOf", true)
LANGUAGE_FEATURE(NewCxxMethodSafetyHeuristics, 0, "Only import C++ methods that return pointers (projections) on owned types as unsafe", true)
Expand Down Expand Up @@ -272,6 +273,9 @@ EXPERIMENTAL_FEATURE(ExtractConstantsFromMembers, false)
/// Enable bitwise-copyable feature.
EXPERIMENTAL_FEATURE(BitwiseCopyable, true)

/// Enables the FixedArray data type.
EXPERIMENTAL_FEATURE(FixedArrays, false)

#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE
Expand Down
Loading