Skip to content

Commit 45d7ea3

Browse files
authored
Merge pull request #75518 from Azoy/integer-generics
Implement Value generics
2 parents 0aaaa60 + 17eb973 commit 45d7ea3

File tree

185 files changed

+4298
-799
lines changed

Some content is hidden

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

185 files changed

+4298
-799
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ swift_compiler_sources(Optimizer
2424
SimplifyInitEnumDataAddr.swift
2525
SimplifyKeyPath.swift
2626
SimplifyLoad.swift
27+
SimplifyMisc.swift
2728
SimplifyPartialApply.swift
2829
SimplifyPointerToAddress.swift
2930
SimplifyRefCasts.swift
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===--- SimplifyMisc.swift -----------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 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 TypeValueInst: OnoneSimplifyable, SILCombineSimplifyable {
16+
func simplify(_ context: SimplifyContext) {
17+
// If our parameter is not known statically, then bail.
18+
guard paramType.isInteger() else {
19+
return
20+
}
21+
22+
// Note: Right now, value generics only support 'Int'. If we ever expand the
23+
// scope of types supported, then this should change.
24+
let fieldType = type.getNominalFields(in: parentFunction)![0]
25+
26+
let builder = Builder(before: self, context)
27+
let intLiteral = builder.createIntegerLiteral(value, type: fieldType)
28+
let structInst = builder.createStruct(type: type, elements: [intLiteral])
29+
uses.replaceAll(with: structInst, context)
30+
context.erase(instruction: self)
31+
}
32+
}

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ private func registerSwiftPasses() {
108108
registerForSILCombine(DestroyValueInst.self, { run(DestroyValueInst.self, $0) })
109109
registerForSILCombine(DestructureStructInst.self, { run(DestructureStructInst.self, $0) })
110110
registerForSILCombine(DestructureTupleInst.self, { run(DestructureTupleInst.self, $0) })
111+
registerForSILCombine(TypeValueInst.self, { run(TypeValueInst.self, $0) })
111112

112113
// Test passes
113114
registerPass(aliasInfoDumper, { aliasInfoDumper.run($0) })

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,16 @@ class ExistentialMetatypeInst : SingleValueInstruction, UnaryInstruction {}
718718

719719
final public class ObjCProtocolInst : SingleValueInstruction {}
720720

721+
final public class TypeValueInst: SingleValueInstruction, UnaryInstruction {
722+
public var paramType: BridgedASTType {
723+
bridged.TypeValueInst_getParamType()
724+
}
725+
726+
public var value: Int {
727+
bridged.TypeValueInst_getValue()
728+
}
729+
}
730+
721731
public class GlobalAccessInstruction : SingleValueInstruction {
722732
final public var global: GlobalVariable {
723733
bridged.GlobalAccessInst_getGlobal().globalVar

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public func registerSILClasses() {
150150
register(MetatypeInst.self)
151151
register(ValueMetatypeInst.self)
152152
register(ExistentialMetatypeInst.self)
153+
register(TypeValueInst.self)
153154
register(OpenPackElementInst.self)
154155
register(PackLengthInst.self)
155156
register(DynamicPackIndexInst.self)

docs/ABI/Mangling.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,10 @@ Types
710710
type ::= type 'Xm' METATYPE-REPR // existential metatype with representation
711711
type ::= 'Xe' // error or unresolved type
712712

713+
#if SWIFT_RUNTIME_VERSION >= 6.TBD
714+
type ::= '$' 'n'? NATURAL_ZERO // integer type
715+
#endif
716+
713717
bound-generic-type ::= type 'y' (type* '_')* type* retroactive-conformance* 'G' // one type-list per nesting level of type
714718
bound-generic-type ::= substitution
715719

@@ -1008,11 +1012,18 @@ now codified into the ABI; the index 0 is therefore reserved.
10081012

10091013
::
10101014

1011-
generic-signature ::= requirement* generic-param-pack-marker* 'l' // one generic parameter
1012-
generic-signature ::= requirement* generic-param-pack-marker* 'r' GENERIC-PARAM-COUNT* 'l'
1015+
generic-signature ::= requirement* generic-param-marker 'l' // one generic parameter
1016+
generic-signature ::= requirement* generic-param-marker* 'r' GENERIC-PARAM-COUNT* 'l'
1017+
1018+
generic-param-marker ::= generic-param-pack-marker
1019+
generic-param-marker ::= generic-param-value-marker
10131020

10141021
generic-param-pack-marker ::= 'Rv' GENERIC_PARAM-INDEX // generic parameter pack marker
10151022

1023+
#if SWIFT_RUNTIME_VERSION >= 6.TBD
1024+
generic-param-value-marker ::= type 'RV' GENERIC-PARAM-INDEX // generic parameter value marker
1025+
#endif
1026+
10161027
GENERIC-PARAM-COUNT ::= 'z' // zero parameters
10171028
GENERIC-PARAM-COUNT ::= INDEX // N+1 parameters
10181029

docs/SIL.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7762,6 +7762,20 @@ element value operand is the projected element type of the pack element
77627762
and must be structurally well-typed for the given index and pack type;
77637763
see the structural type matching rules for pack indices.
77647764

7765+
Value Generics
7766+
~~~~~~~~~~~~~~~~~
7767+
7768+
type_value
7769+
```````````
7770+
7771+
::
7772+
7773+
sil-instruction ::= 'type_value' sil-type 'for' sil-identifier
7774+
7775+
Produce the dynamic value of the given value generic, which must be a formal
7776+
value generic type. The value of the instruction has the type of whatever the
7777+
underlying value generic's type is. For right now that is limited to ``Int``.
7778+
77657779
Unchecked Conversions
77667780
~~~~~~~~~~~~~~~~~~~~~
77677781

include/swift/ABI/GenericContext.h

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ struct TargetGenericContextDescriptorHeader {
7474
/// same order as the requirement descriptors which satisfy
7575
/// hasKeyArgument().
7676
///
77+
/// a sequence of values, in the same order as the parameter descriptors
78+
/// which satisify getKind() == GenericParamKind::Value and
79+
/// hasKeyArgument();
80+
///
7781
/// The elements above which are packs are precisely those appearing
7882
/// in the sequence of trailing GenericPackShapeDescriptors.
7983
uint16_t NumKeyArguments;
@@ -319,6 +323,18 @@ struct ConditionalInvertibleProtocolSet: InvertibleProtocolSet {
319323
template<typename Runtime>
320324
struct TargetConditionalInvertibleProtocolRequirement: TargetGenericRequirementDescriptor<Runtime> { };
321325

326+
struct GenericValueHeader {
327+
/// The total number of generic parameters in this signature where
328+
/// getKind() == GenericParamKind::Value.
329+
uint32_t NumValues;
330+
};
331+
332+
/// The GenericValueHeader is followed by an array of these descriptors,
333+
/// whose length is given by the header's NumValues field.
334+
struct GenericValueDescriptor {
335+
GenericValueType Type;
336+
};
337+
322338
/// An array of generic parameter descriptors, all
323339
/// GenericParamDescriptor::implicit(), which is by far
324340
/// the most common case. Some generic context storage can
@@ -356,20 +372,26 @@ class RuntimeGenericSignature {
356372
const TargetGenericRequirementDescriptor<Runtime> *Requirements;
357373
GenericPackShapeHeader PackShapeHeader;
358374
const GenericPackShapeDescriptor *PackShapeDescriptors;
375+
GenericValueHeader ValueHeader;
376+
const GenericValueDescriptor *ValueDescriptors;
359377

360378
public:
361379
RuntimeGenericSignature()
362-
: Header{0, 0, 0, GenericContextDescriptorFlags(false, false)},
380+
: Header{0, 0, 0, GenericContextDescriptorFlags(false, false, false)},
363381
Params(nullptr), Requirements(nullptr),
364-
PackShapeHeader{0, 0}, PackShapeDescriptors(nullptr) {}
382+
PackShapeHeader{0, 0}, PackShapeDescriptors(nullptr), ValueHeader{0},
383+
ValueDescriptors(nullptr) {}
365384

366385
RuntimeGenericSignature(const TargetGenericContextDescriptorHeader<Runtime> &header,
367386
const GenericParamDescriptor *params,
368387
const TargetGenericRequirementDescriptor<Runtime> *requirements,
369388
const GenericPackShapeHeader &packShapeHeader,
370-
const GenericPackShapeDescriptor *packShapeDescriptors)
389+
const GenericPackShapeDescriptor *packShapeDescriptors,
390+
const GenericValueHeader &valueHeader,
391+
const GenericValueDescriptor *valueDescriptors)
371392
: Header(header), Params(params), Requirements(requirements),
372-
PackShapeHeader(packShapeHeader), PackShapeDescriptors(packShapeDescriptors) {}
393+
PackShapeHeader(packShapeHeader), PackShapeDescriptors(packShapeDescriptors),
394+
ValueHeader(valueHeader), ValueDescriptors(valueDescriptors) {}
373395

374396
llvm::ArrayRef<GenericParamDescriptor> getParams() const {
375397
return llvm::ArrayRef(Params, Header.NumParams);
@@ -387,6 +409,14 @@ class RuntimeGenericSignature {
387409
return llvm::ArrayRef(PackShapeDescriptors, PackShapeHeader.NumPacks);
388410
}
389411

412+
const GenericValueHeader &getGenericValueHeader() const {
413+
return ValueHeader;
414+
}
415+
416+
llvm::ArrayRef<GenericValueDescriptor> getGenericValueDescriptors() const {
417+
return llvm::ArrayRef(ValueDescriptors, ValueHeader.NumValues);
418+
}
419+
390420
size_t getArgumentLayoutSizeInWords() const {
391421
return Header.getArgumentLayoutSizeInWords();
392422
}
@@ -482,6 +512,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
482512
ConditionalInvertibleProtocolSet,
483513
ConditionalInvertibleProtocolsRequirementCount,
484514
TargetConditionalInvertibleProtocolRequirement<Runtime>,
515+
GenericValueHeader,
516+
GenericValueDescriptor,
485517
FollowingTrailingObjects...>
486518
{
487519
protected:
@@ -500,6 +532,8 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
500532
ConditionalInvertibleProtocolSet,
501533
ConditionalInvertibleProtocolsRequirementCount,
502534
GenericConditionalInvertibleProtocolRequirement,
535+
GenericValueHeader,
536+
GenericValueDescriptor,
503537
FollowingTrailingObjects...>;
504538
friend TrailingObjects;
505539

@@ -648,13 +682,33 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
648682
header.NumPacks};
649683
}
650684

685+
GenericValueHeader getGenericValueHeader() const {
686+
if (!asSelf()->isGeneric())
687+
return {0};
688+
if (!getGenericContextHeader().Flags.hasValues())
689+
return {0};
690+
return *this->template getTrailingObjects<GenericValueHeader>();
691+
}
692+
693+
llvm::ArrayRef<GenericValueDescriptor> getGenericValueDescriptors() const {
694+
auto header = getGenericValueHeader();
695+
696+
if (header.NumValues == 0)
697+
return {};
698+
699+
return {this->template getTrailingObjects<GenericValueDescriptor>(),
700+
header.NumValues};
701+
}
702+
651703
RuntimeGenericSignature<Runtime> getGenericSignature() const {
652704
if (!asSelf()->isGeneric()) return RuntimeGenericSignature<Runtime>();
653705
return {getGenericContextHeader(),
654706
getGenericParams().data(),
655707
getGenericRequirements().data(),
656708
getGenericPackShapeHeader(),
657-
getGenericPackShapeDescriptors().data()};
709+
getGenericPackShapeDescriptors().data(),
710+
getGenericValueHeader(),
711+
getGenericValueDescriptors().data()};
658712
}
659713

660714
protected:
@@ -713,6 +767,23 @@ class TrailingGenericContextObjects<TargetSelf<Runtime>,
713767
return counts.empty() ? 0 : counts.back().count;
714768
}
715769

770+
size_t numTrailingObjects(OverloadToken<GenericValueHeader>) const {
771+
if (!asSelf()->isGeneric())
772+
return 0;
773+
774+
return getGenericContextHeader().Flags.hasValues() ? 1 : 0;
775+
}
776+
777+
size_t numTrailingObjects(OverloadToken<GenericValueDescriptor>) const {
778+
if (!asSelf()->isGeneric())
779+
return 0;
780+
781+
if (!getGenericContextHeader().Flags.hasValues())
782+
return 0;
783+
784+
return getGenericValueHeader().NumValues;
785+
}
786+
716787
#if defined(_MSC_VER) && _MSC_VER < 1920
717788
#undef OverloadToken
718789
#endif

include/swift/ABI/Metadata.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,7 @@ struct TargetExtendedExistentialTypeShape
21452145

21462146
RuntimeGenericSignature<Runtime> getRequirementSignature() const {
21472147
return {ReqSigHeader, getReqSigParams(), getReqSigRequirements(),
2148-
{0, 0}, nullptr};
2148+
{0, 0}, nullptr, {0}, nullptr};
21492149
}
21502150

21512151
unsigned getNumReqSigParams() const {
@@ -2225,7 +2225,8 @@ struct TargetExtendedExistentialTypeShape
22252225
RuntimeGenericSignature<Runtime> getGeneralizationSignature() const {
22262226
if (!hasGeneralizationSignature()) return RuntimeGenericSignature<Runtime>();
22272227
return {*getGenSigHeader(), getGenSigParams(), getGenSigRequirements(),
2228-
getGenSigPackShapeHeader(), getGenSigPackShapeDescriptors()};
2228+
getGenSigPackShapeHeader(), getGenSigPackShapeDescriptors(),
2229+
{0}, nullptr};
22292230
}
22302231

22312232
unsigned getNumGenSigParams() const {

0 commit comments

Comments
 (0)