Skip to content

Commit a184782

Browse files
committed
Introduce a Builtin.FixedArray type.
`Builtin.FixedArray<let N: Int, T: ~Copyable & ~Escapable>` has the layout of `N` elements of type `T` laid out sequentially in memory (with the tail padding of every element occupied by the array). This provides a primitive on which the standard library `Vector` type can be built.
1 parent ddd5575 commit a184782

Some content is hidden

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

54 files changed

+2489
-72
lines changed

docs/ABI/Mangling.rst

+1
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ Types
693693
type ::= 'Bp' // Builtin.RawPointer
694694
type ::= 'Bt' // Builtin.SILToken
695695
type ::= type 'Bv' NATURAL '_' // Builtin.Vec<n>x<type>
696+
type ::= type type 'BV' // Builtin.FixedArray<N, T>
696697
type ::= 'Bw' // Builtin.Word
697698
type ::= function-signature 'c' // function type (escaping)
698699
type ::= function-signature 'X' FUNCTION-KIND // special function type

include/swift/ABI/Metadata.h

+21
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,27 @@ struct TargetMetatypeMetadata : public TargetMetadata<Runtime> {
16651665
};
16661666
using MetatypeMetadata = TargetMetatypeMetadata<InProcess>;
16671667

1668+
/// The structure of `Builtin.FixedArray` type metadata.
1669+
template <typename Runtime>
1670+
struct TargetFixedArrayTypeMetadata : public TargetMetadata<Runtime> {
1671+
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
1672+
1673+
StoredPointerDifference Count;
1674+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> Element;
1675+
1676+
// Returns the number of elements for which storage is reserved.
1677+
// A type that is instantiated with negative size cannot have values
1678+
// instantiated, so is laid out with zero size like an uninhabited type.
1679+
StoredPointerDifference getRealizedCount() const {
1680+
return Count < 0 ? 0 : Count;
1681+
}
1682+
1683+
static bool classof(const TargetMetadata<Runtime> *metadata) {
1684+
return metadata->getKind() == MetadataKind::FixedArray;
1685+
}
1686+
};
1687+
using FixedArrayTypeMetadata = TargetFixedArrayTypeMetadata<InProcess>;
1688+
16681689
/// The structure of tuple type metadata.
16691690
template <typename Runtime>
16701691
struct TargetTupleTypeMetadata : public TargetMetadata<Runtime> {

include/swift/ABI/MetadataKind.def

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ NOMINALTYPEMETADATAKIND(Class, 0)
4444
NOMINALTYPEMETADATAKIND(Struct, 0 | MetadataKindIsNonHeap)
4545

4646
/// An enum type.
47-
/// If we add reference enums, that needs to go here.
4847
NOMINALTYPEMETADATAKIND(Enum, 1 | MetadataKindIsNonHeap)
4948

5049
/// An optional type.
@@ -80,6 +79,10 @@ METADATAKIND(ExistentialMetatype, 6 | MetadataKindIsRuntimePrivate | MetadataKin
8079
/// An extended existential type.
8180
METADATAKIND(ExtendedExistential, 7 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap)
8281

82+
/// A `Builtin.FixedArray`.
83+
METADATAKIND(FixedArray, 8 | MetadataKindIsRuntimePrivate | MetadataKindIsNonHeap)
84+
85+
8386
/// A heap-allocated local variable using statically-generated metadata.
8487
METADATAKIND(HeapLocalVariable, 0 | MetadataKindIsNonType)
8588

include/swift/AST/Builtins.def

+7
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,13 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(DistributedActorAsAnyActor, "distributedActor
11261126
/// lowered away at IRGen, no sooner.
11271127
BUILTIN_MISC_OPERATION_WITH_SILGEN(AddressOfRawLayout, "addressOfRawLayout", "n", Special)
11281128

1129+
/// emplace<T>((Builtin.RawPointer) -> Void) -> T
1130+
///
1131+
/// Passes a pointer to an uninitialized result value to the given function,
1132+
/// which must initialize the memory before finishing execution. The value in
1133+
/// memory becomes the result of the call.
1134+
BUILTIN_SIL_OPERATION(Emplace, "emplace", Special)
1135+
11291136
/// Builtins for instrumentation added by sanitizers during SILGen.
11301137
#ifndef BUILTIN_SANITIZER_OPERATION
11311138
#define BUILTIN_SANITIZER_OPERATION(Id, Name, Attrs) BUILTIN(Id, Name, Attrs)

include/swift/AST/DiagnosticsSema.def

+2
Original file line numberDiff line numberDiff line change
@@ -4641,6 +4641,8 @@ ERROR(cannot_explicitly_specialize_function,none,
46414641
"cannot explicitly specialize %kind0", (ValueDecl *))
46424642
ERROR(not_a_generic_type,none,
46434643
"cannot specialize non-generic type %0", (Type))
4644+
ERROR(invalid_generic_builtin_type,none,
4645+
"invalid generic arguments to builtin type %0", (Type))
46444646
ERROR(not_a_generic_macro,none,
46454647
"cannot specialize a non-generic external macro %0", (const ValueDecl *))
46464648
ERROR(protocol_declares_unknown_primary_assoc_type,none,

include/swift/AST/TypeDifferenceVisitor.h

+13
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,19 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
129129
return asImpl().visitDifferentTypeStructure(type1, type2);
130130
return asImpl().visit(type1.getElementType(), type2.getElementType());
131131
}
132+
133+
bool visitBuiltinUnboundGenericType(CanBuiltinUnboundGenericType type1,
134+
CanBuiltinUnboundGenericType type2) {
135+
return asImpl().visitDifferentTypeStructure(type1, type2);
136+
}
137+
138+
bool visitBuiltinFixedArrayType(CanBuiltinFixedArrayType type1,
139+
CanBuiltinFixedArrayType type2) {
140+
if (asImpl().visit(type1->getSize(), type2->getSize())) {
141+
return true;
142+
}
143+
return asImpl().visit(type1->getElementType(), type2->getElementType());
144+
}
132145

133146
bool visitPackType(CanPackType type1, CanPackType type2) {
134147
return visitComponentArray(type1, type2,

include/swift/AST/TypeMatcher.h

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class TypeMatcher {
111111
TRIVIAL_CASE(BuiltinIntegerType)
112112
TRIVIAL_CASE(BuiltinFloatType)
113113
TRIVIAL_CASE(BuiltinVectorType)
114+
TRIVIAL_CASE(BuiltinUnboundGenericType)
115+
TRIVIAL_CASE(BuiltinFixedArrayType)
114116
TRIVIAL_CASE(IntegerType)
115117
#define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type)
116118
#include "swift/AST/TypeNodes.def"

include/swift/AST/TypeNodes.def

+35-15
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
/// This type is a builtin type. The default behavior is
2828
/// ALWAYS_CANONICAL_TYPE(id, parent).
2929

30+
/// BUILTIN_CONCRETE_TYPE(id, parent)
31+
/// This type is a builtin type without generic parameters. The default
32+
/// behavior is BUILTIN_TYPE(id, parent).
33+
34+
/// BUILTIN_GENERIC_TYPE(id, parent)
35+
/// This type is a builtin type with generic parameters. The default
36+
/// behavior is BUILTIN_TYPE(id, parent).
37+
3038
/// SUGARED_TYPE(id, parent)
3139
/// This type is never canonical. It provides an efficient accessor,
3240
/// getSinglyDesugaredType(), which removes one level of sugar. This
@@ -72,6 +80,14 @@
7280
#define BUILTIN_TYPE(id, parent) ALWAYS_CANONICAL_TYPE(id, parent)
7381
#endif
7482

83+
#ifndef BUILTIN_CONCRETE_TYPE
84+
#define BUILTIN_CONCRETE_TYPE(id, parent) BUILTIN_TYPE(id, parent)
85+
#endif
86+
87+
#ifndef BUILTIN_GENERIC_TYPE
88+
#define BUILTIN_GENERIC_TYPE(id, parent) BUILTIN_TYPE(id, parent)
89+
#endif
90+
7591
#ifndef SUGARED_TYPE
7692
#define SUGARED_TYPE(id, parent) TYPE(id, parent)
7793
#endif
@@ -111,22 +127,24 @@ UNCHECKED_TYPE(Unresolved, Type)
111127
UNCHECKED_TYPE(Placeholder, Type)
112128
ABSTRACT_TYPE(Builtin, Type)
113129
ABSTRACT_TYPE(AnyBuiltinInteger, BuiltinType)
114-
BUILTIN_TYPE(BuiltinInteger, AnyBuiltinIntegerType)
115-
BUILTIN_TYPE(BuiltinIntegerLiteral, AnyBuiltinIntegerType)
130+
BUILTIN_CONCRETE_TYPE(BuiltinInteger, AnyBuiltinIntegerType)
131+
BUILTIN_CONCRETE_TYPE(BuiltinIntegerLiteral, AnyBuiltinIntegerType)
116132
TYPE_RANGE(AnyBuiltinInteger, BuiltinInteger, BuiltinIntegerLiteral)
117-
BUILTIN_TYPE(BuiltinExecutor, BuiltinType)
118-
BUILTIN_TYPE(BuiltinFloat, BuiltinType)
119-
BUILTIN_TYPE(BuiltinJob, BuiltinType)
120-
BUILTIN_TYPE(BuiltinPackIndex, BuiltinType)
121-
BUILTIN_TYPE(BuiltinRawPointer, BuiltinType)
122-
BUILTIN_TYPE(BuiltinRawUnsafeContinuation, BuiltinType)
123-
BUILTIN_TYPE(BuiltinNativeObject, BuiltinType)
124-
BUILTIN_TYPE(BuiltinBridgeObject, BuiltinType)
125-
BUILTIN_TYPE(BuiltinUnsafeValueBuffer, BuiltinType)
126-
BUILTIN_TYPE(BuiltinDefaultActorStorage, BuiltinType)
127-
BUILTIN_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
128-
BUILTIN_TYPE(BuiltinVector, BuiltinType)
129-
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinVector)
133+
BUILTIN_CONCRETE_TYPE(BuiltinExecutor, BuiltinType)
134+
BUILTIN_CONCRETE_TYPE(BuiltinFloat, BuiltinType)
135+
BUILTIN_CONCRETE_TYPE(BuiltinJob, BuiltinType)
136+
BUILTIN_CONCRETE_TYPE(BuiltinPackIndex, BuiltinType)
137+
BUILTIN_CONCRETE_TYPE(BuiltinRawPointer, BuiltinType)
138+
BUILTIN_CONCRETE_TYPE(BuiltinRawUnsafeContinuation, BuiltinType)
139+
BUILTIN_CONCRETE_TYPE(BuiltinNativeObject, BuiltinType)
140+
BUILTIN_CONCRETE_TYPE(BuiltinBridgeObject, BuiltinType)
141+
BUILTIN_CONCRETE_TYPE(BuiltinUnsafeValueBuffer, BuiltinType)
142+
BUILTIN_CONCRETE_TYPE(BuiltinDefaultActorStorage, BuiltinType)
143+
BUILTIN_CONCRETE_TYPE(BuiltinNonDefaultDistributedActorStorage, BuiltinType)
144+
BUILTIN_CONCRETE_TYPE(BuiltinVector, BuiltinType)
145+
BUILTIN_GENERIC_TYPE(BuiltinFixedArray, BuiltinType)
146+
BUILTIN_CONCRETE_TYPE(BuiltinUnboundGeneric, BuiltinType)
147+
TYPE_RANGE(Builtin, BuiltinInteger, BuiltinUnboundGeneric)
130148
TYPE(Tuple, Type)
131149
ABSTRACT_TYPE(ReferenceStorage, Type)
132150
#define REF_STORAGE(Name, ...) \
@@ -228,6 +246,8 @@ SINGLETON_TYPE(SILToken, SILToken)
228246
#undef UNCHECKED_TYPE
229247
#undef ARTIFICIAL_TYPE
230248
#undef SUGARED_TYPE
249+
#undef BUILTIN_GENERIC_TYPE
250+
#undef BUILTIN_CONCRETE_TYPE
231251
#undef BUILTIN_TYPE
232252
#undef ALWAYS_CANONICAL_TYPE
233253
#undef ALWAYS_CANONICAL_ARTIFICIAL_TYPE

include/swift/AST/TypeTransform.h

+26-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class TypeTransform {
106106
TypeBase *base = t.getPointer();
107107

108108
switch (base->getKind()) {
109-
#define BUILTIN_TYPE(Id, Parent) \
109+
#define BUILTIN_CONCRETE_TYPE(Id, Parent) \
110110
case TypeKind::Id:
111111
#define TYPE(Id, Parent)
112112
#include "swift/AST/TypeNodes.def"
@@ -120,6 +120,31 @@ case TypeKind::Id:
120120
case TypeKind::Integer:
121121
return t;
122122

123+
case TypeKind::BuiltinFixedArray: {
124+
auto bfaTy = cast<BuiltinFixedArrayType>(base);
125+
126+
Type transSize = doIt(bfaTy->getSize(),
127+
TypePosition::Invariant);
128+
if (!transSize) {
129+
return Type();
130+
}
131+
132+
Type transElement = doIt(bfaTy->getElementType(),
133+
TypePosition::Invariant);
134+
if (!transElement) {
135+
return Type();
136+
}
137+
138+
CanType canTransSize = transSize->getCanonicalType();
139+
CanType canTransElement = transElement->getCanonicalType();
140+
if (canTransSize != bfaTy->getSize()
141+
|| canTransElement != bfaTy->getElementType()) {
142+
return BuiltinFixedArrayType::get(canTransSize, canTransElement);
143+
}
144+
145+
return bfaTy;
146+
}
147+
123148
case TypeKind::PrimaryArchetype:
124149
case TypeKind::PackArchetype: {
125150
auto *archetype = cast<ArchetypeType>(base);

include/swift/AST/Types.h

+114-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class ArgumentList;
6262
class AssociatedTypeDecl;
6363
class ASTContext;
6464
enum BufferPointerTypeKind : unsigned;
65+
struct BuiltinNameStringLiteral;
6566
class BuiltinTupleDecl;
6667
class ClassDecl;
6768
class ClangModuleLoader;
@@ -1508,6 +1509,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
15081509
/// return `None`.
15091510
std::optional<TangentSpace>
15101511
getAutoDiffTangentSpace(LookupConformanceFn lookupConformance);
1512+
1513+
/// Return the kind of generic parameter that this type can be matched to.
1514+
GenericTypeParamKind getMatchingParamKind();
15111515
};
15121516

15131517
/// AnyGenericType - This abstract class helps types ensure that fields
@@ -1648,8 +1652,9 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(UnresolvedType, Type)
16481652
/// BuiltinType - An abstract class for all the builtin types.
16491653
class BuiltinType : public TypeBase {
16501654
protected:
1651-
BuiltinType(TypeKind kind, const ASTContext &canTypeCtx)
1652-
: TypeBase(kind, &canTypeCtx, RecursiveTypeProperties()) {}
1655+
BuiltinType(TypeKind kind, const ASTContext &canTypeCtx,
1656+
RecursiveTypeProperties properties = {})
1657+
: TypeBase(kind, &canTypeCtx, properties) {}
16531658
public:
16541659
static bool classof(const TypeBase *T) {
16551660
return T->getKind() >= TypeKind::First_BuiltinType &&
@@ -1672,6 +1677,113 @@ class BuiltinType : public TypeBase {
16721677
};
16731678
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinType, Type)
16741679

1680+
/// BuiltinUnboundGenericType - the base declaration of a generic builtin type
1681+
/// that has not yet had generic parameters applied.
1682+
///
1683+
/// Referring to an unbound generic type by itself is invalid, but this
1684+
/// representation is used as an intermediate during type resolution when
1685+
/// resolving a type reference such as `Builtin.Int<31>`. Applying
1686+
/// the generic parameters produces the actual builtin type based on the
1687+
/// kind of the base.
1688+
class BuiltinUnboundGenericType : public BuiltinType {
1689+
friend class ASTContext;
1690+
TypeKind BoundGenericTypeKind;
1691+
1692+
BuiltinUnboundGenericType(const ASTContext &C,
1693+
TypeKind genericTypeKind)
1694+
: BuiltinType(TypeKind::BuiltinUnboundGeneric, C),
1695+
BoundGenericTypeKind(genericTypeKind)
1696+
{}
1697+
1698+
public:
1699+
static bool classof(const TypeBase *T) {
1700+
return T->getKind() == TypeKind::BuiltinUnboundGeneric;
1701+
}
1702+
1703+
/// Produce the unqualified name of the type.
1704+
BuiltinNameStringLiteral getBuiltinTypeName() const;
1705+
StringRef getBuiltinTypeNameString() const;
1706+
1707+
static BuiltinUnboundGenericType *get(TypeKind genericTypeKind,
1708+
const ASTContext &C);
1709+
1710+
/// Get the generic signature with which to substitute this type.
1711+
GenericSignature getGenericSignature() const;
1712+
1713+
/// Get the type that results from binding the generic parameters of this
1714+
/// builtin to the given substitutions.
1715+
///
1716+
/// Produces an ErrorType if the substitution is invalid.
1717+
Type getBound(SubstitutionMap subs) const;
1718+
};
1719+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinUnboundGenericType, BuiltinType)
1720+
1721+
/// BuiltinFixedArrayType - The builtin type representing N values stored
1722+
/// inline contiguously.
1723+
///
1724+
/// All elements of a value of this type must be fully initialized any time the
1725+
/// value may be copied, moved, or destroyed.
1726+
class BuiltinFixedArrayType : public BuiltinType, public llvm::FoldingSetNode {
1727+
friend class ASTContext;
1728+
1729+
CanType Size;
1730+
CanType ElementType;
1731+
1732+
static RecursiveTypeProperties
1733+
getRecursiveTypeProperties(CanType Size, CanType Element) {
1734+
RecursiveTypeProperties properties;
1735+
properties |= Size->getRecursiveProperties();
1736+
properties |= Element->getRecursiveProperties();
1737+
return properties;
1738+
}
1739+
1740+
BuiltinFixedArrayType(CanType Size,
1741+
CanType ElementType)
1742+
: BuiltinType(TypeKind::BuiltinFixedArray, ElementType->getASTContext(),
1743+
getRecursiveTypeProperties(Size, ElementType)),
1744+
Size(Size),
1745+
ElementType(ElementType)
1746+
{}
1747+
1748+
public:
1749+
/// Arrays with more elements than this are always treated as in-memory values.
1750+
///
1751+
/// (4096 is the hardcoded limit above which we refuse to import C arrays
1752+
/// as tuples. From first principles, a much lower threshold would probably
1753+
/// make sense, but we don't want to break the type lowering of C types
1754+
/// as they appear in existing Swift code.)
1755+
static constexpr const uint64_t MaximumLoadableSize = 4096;
1756+
1757+
static bool classof(const TypeBase *T) {
1758+
return T->getKind() == TypeKind::BuiltinFixedArray;
1759+
}
1760+
1761+
static BuiltinFixedArrayType *get(CanType Size,
1762+
CanType ElementType);
1763+
1764+
/// Get the integer generic parameter representing the number of elements.
1765+
CanType getSize() const { return Size; }
1766+
1767+
/// Get the fixed integer number of elements if known and zero or greater.
1768+
std::optional<uint64_t> getFixedInhabitedSize() const;
1769+
1770+
/// True if the type is statically negative-sized (and therefore uninhabited).
1771+
bool isFixedNegativeSize() const;
1772+
1773+
/// Get the element type.
1774+
CanType getElementType() const { return ElementType; }
1775+
1776+
void Profile(llvm::FoldingSetNodeID &ID) const {
1777+
Profile(ID, getSize(), getElementType());
1778+
}
1779+
static void Profile(llvm::FoldingSetNodeID &ID,
1780+
CanType Size, CanType ElementType) {
1781+
ID.AddPointer(Size.getPointer());
1782+
ID.AddPointer(ElementType.getPointer());
1783+
}
1784+
};
1785+
DEFINE_EMPTY_CAN_TYPE_WRAPPER(BuiltinFixedArrayType, BuiltinType)
1786+
16751787
/// BuiltinRawPointerType - The builtin raw (and dangling) pointer type. This
16761788
/// pointer is completely unmanaged and is equivalent to i8* in LLVM IR.
16771789
class BuiltinRawPointerType : public BuiltinType {

include/swift/Demangling/DemangleNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ NODE(BoundGenericTypeAlias)
4646
NODE(BoundGenericFunction)
4747
NODE(BuiltinTypeName)
4848
NODE(BuiltinTupleType)
49+
NODE(BuiltinFixedArray)
4950
NODE(CFunctionPointer)
5051
NODE(ClangType)
5152
CONTEXT_NODE(Class)

include/swift/Runtime/Metadata.h

+8
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,14 @@ MetadataResponse
573573
swift_getForeignTypeMetadata(MetadataRequest request,
574574
ForeignTypeMetadata *nonUnique);
575575

576+
/// Fetch a metadata record representing a `Builtin.FixedArray`
577+
/// of a given count and element type.
578+
SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
579+
MetadataResponse
580+
swift_getFixedArrayTypeMetadata(MetadataRequest request,
581+
intptr_t count,
582+
const Metadata *element);
583+
576584
/// Fetch a uniqued metadata for a tuple type.
577585
///
578586
/// The labels argument is null if and only if there are no element

0 commit comments

Comments
 (0)