Skip to content

Commit fe44859

Browse files
committed
Package CMO containing the following PRs.
#73902 #73754 #73717 #72606 #73566 #73478 #73686 #72937 #73708 #73751 #73794
1 parent 21e4a5e commit fe44859

File tree

98 files changed

+2992
-615
lines changed

Some content is hidden

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

98 files changed

+2992
-615
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyLoad.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ private func transitivelyErase(load: LoadInst, _ context: SimplifyContext) {
281281

282282
private extension Value {
283283
func canBeCopied(into function: Function, _ context: SimplifyContext) -> Bool {
284-
if !function.isSerialized {
284+
if !function.isAnySerialized {
285285
return true
286286
}
287287

@@ -297,7 +297,7 @@ private extension Value {
297297

298298
while let value = worklist.pop() {
299299
if let fri = value as? FunctionRefInst {
300-
if !fri.referencedFunction.hasValidLinkageForFragileRef {
300+
if !fri.referencedFunction.hasValidLinkageForFragileRef(function.serializedKind) {
301301
return false
302302
}
303303
}

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,9 +549,8 @@ extension FullApplySite {
549549
return false
550550
}
551551
// Cannot inline a non-inlinable function it an inlinable function.
552-
if parentFunction.isSerialized,
553-
let calleeFunction = referencedFunction,
554-
!calleeFunction.isSerialized {
552+
if let calleeFunction = referencedFunction,
553+
!calleeFunction.canBeInlinedIntoCaller(parentFunction.serializedKind) {
555554
return false
556555
}
557556

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,37 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
122122
}
123123
public var isSerialized: Bool { bridged.isSerialized() }
124124

125-
public var hasValidLinkageForFragileRef: Bool { bridged.hasValidLinkageForFragileRef() }
125+
public var isAnySerialized: Bool { bridged.isAnySerialized() }
126+
127+
public enum SerializedKind {
128+
case notSerialized, serialized, serializedForPackage
129+
}
130+
131+
public var serializedKind: SerializedKind {
132+
switch bridged.getSerializedKind() {
133+
case .IsNotSerialized: return .notSerialized
134+
case .IsSerialized: return .serialized
135+
case .IsSerializedForPackage: return .serializedForPackage
136+
default: fatalError()
137+
}
138+
}
139+
140+
private func serializedKindBridged(_ arg: SerializedKind) -> BridgedFunction.SerializedKind {
141+
switch arg {
142+
case .notSerialized: return .IsNotSerialized
143+
case .serialized: return .IsSerialized
144+
case .serializedForPackage: return .IsSerializedForPackage
145+
default: fatalError()
146+
}
147+
}
148+
149+
public func canBeInlinedIntoCaller(_ kind: SerializedKind) -> Bool {
150+
bridged.canBeInlinedIntoCaller(serializedKindBridged(kind))
151+
}
152+
153+
public func hasValidLinkageForFragileRef(_ kind: SerializedKind) -> Bool {
154+
bridged.hasValidLinkageForFragileRef(serializedKindBridged(kind))
155+
}
126156

127157
public enum ThunkKind {
128158
case noThunk, thunk, reabstractionThunk, signatureOptimizedThunk

include/swift/AST/Decl.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
697697
HasAnyUnavailableDuringLoweringValues : 1
698698
);
699699

700-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
700+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
701701
/// If the module is compiled as static library.
702702
StaticLibrary : 1,
703703

@@ -756,7 +756,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
756756
HasCxxInteroperability : 1,
757757

758758
/// Whether this module has been built with -experimental-allow-non-resilient-access.
759-
AllowNonResilientAccess : 1
759+
AllowNonResilientAccess : 1,
760+
761+
/// Whether this module has been built with -experimental-package-cmo.
762+
SerializePackageEnabled : 1
760763
);
761764

762765
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
@@ -4148,6 +4151,13 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
41484151
/// is built resiliently.
41494152
bool isResilient() const;
41504153

4154+
/// True if the decl is resilient AND also its defining module does
4155+
/// _not_ allow non-resilient access; the module can allow such access
4156+
/// if package optimization is enabled so its client modules within the
4157+
/// same package can have a direct access to this decl even if it's
4158+
/// resilient.
4159+
bool isStrictlyResilient() const;
4160+
41514161
/// Returns whether this decl is accessed non/resiliently at the _use_ site
41524162
/// in \p accessingModule, depending on \p expansion.
41534163
///
@@ -6011,6 +6021,13 @@ class AbstractStorageDecl : public ValueDecl {
60116021
/// property from the given module?
60126022
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
60136023

6024+
/// True if the decl is resilient AND also its defining module does
6025+
/// _not_ allow non-resilient access; the module can allow such access
6026+
/// if package optimization is enabled so its client modules within the
6027+
/// same package can have a direct access to this decl even if it's
6028+
/// resilient.
6029+
bool isStrictlyResilient() const;
6030+
60146031
/// True if the storage can be referenced by a keypath directly.
60156032
/// Otherwise, its override must be referenced.
60166033
bool isValidKeyPathComponent() const;

include/swift/AST/Module.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,16 @@ class ModuleDecl
722722
Bits.ModuleDecl.AllowNonResilientAccess = flag;
723723
}
724724

725+
/// Returns true if -experimental-package-cmo was passed, which
726+
/// enables serialization of package, public, and inlinable decls in a
727+
/// package. This requires -experimental-allow-non-resilient-access.
728+
bool serializePackageEnabled() const {
729+
return Bits.ModuleDecl.SerializePackageEnabled;
730+
}
731+
void setSerializePackageEnabled(bool flag = true) {
732+
Bits.ModuleDecl.SerializePackageEnabled = flag;
733+
}
734+
725735
/// Returns true if this module is a non-Swift module that was imported into
726736
/// Swift.
727737
///
@@ -769,6 +779,15 @@ class ModuleDecl
769779
return getResilienceStrategy() != ResilienceStrategy::Default;
770780
}
771781

782+
/// True if this module is resilient AND also does _not_ allow
783+
/// non-resilient access; the module can allow such access if
784+
/// package optimization is enabled so its client modules within
785+
/// the same package can have a direct access to decls in this
786+
/// module even if it's built resiliently.
787+
bool isStrictlyResilient() const {
788+
return isResilient() && !allowNonResilientAccess();
789+
}
790+
772791
/// Look up a (possibly overloaded) value set at top-level scope
773792
/// (but with the specified access path, which may come from an import decl)
774793
/// within the current module.

include/swift/AST/Types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6615,6 +6615,8 @@ enum class OpaqueSubstitutionKind {
66156615
// Can be done if the underlying type is accessible from the context we
66166616
// substitute into. Private types cannot be accessed from a different TU.
66176617
SubstituteSameModuleMaximalResilience,
6618+
// Same as previous but with package and above visibility.
6619+
SubstituteSamePackageMaximalResilience,
66186620
// Substitute in a different module from the opaque defining decl. Can only
66196621
// be done if the underlying type is public.
66206622
SubstituteNonResilientModule

include/swift/SIL/GenericSpecializationMangler.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class SpecializationMangler : public Mangle::ASTMangler {
3737
/// The specialization pass.
3838
SpecializationPass Pass;
3939

40-
IsSerialized_t Serialized;
40+
swift::SerializedKind_t Serialized;
4141

4242
/// The original function which is specialized.
4343
SILFunction *Function;
@@ -50,12 +50,12 @@ class SpecializationMangler : public Mangle::ASTMangler {
5050
PossibleEffects RemovedEffects;
5151

5252
protected:
53-
SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized,
53+
SpecializationMangler(SpecializationPass P, swift::SerializedKind_t Serialized,
5454
SILFunction *F)
5555
: Pass(P), Serialized(Serialized), Function(F),
5656
ArgOpBuffer(ArgOpStorage) {}
5757

58-
SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized,
58+
SpecializationMangler(SpecializationPass P, swift::SerializedKind_t Serialized,
5959
std::string functionName)
6060
: Pass(P), Serialized(Serialized), Function(nullptr),
6161
FunctionName(functionName), ArgOpBuffer(ArgOpStorage) {}
@@ -88,7 +88,7 @@ class GenericSpecializationMangler : public SpecializationMangler {
8888
SubstitutionMap subs);
8989

9090
public:
91-
GenericSpecializationMangler(SILFunction *F, IsSerialized_t Serialized)
91+
GenericSpecializationMangler(SILFunction *F, swift::SerializedKind_t Serialized)
9292
: SpecializationMangler(SpecializationPass::GenericSpecializer,
9393
Serialized, F) {}
9494

include/swift/SIL/SILBridging.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,12 @@ struct BridgedFunction {
529529
IsSignatureOptimizedThunk
530530
};
531531

532+
enum class SerializedKind {
533+
IsNotSerialized,
534+
IsSerialized,
535+
IsSerializedForPackage
536+
};
537+
532538
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE swift::SILFunction * _Nonnull getFunction() const;
533539
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef getName() const;
534540
SWIFT_IMPORT_UNSAFE BridgedOwnedString getDebugDescription() const;
@@ -558,7 +564,10 @@ struct BridgedFunction {
558564
BRIDGED_INLINE PerformanceConstraints getPerformanceConstraints() const;
559565
BRIDGED_INLINE InlineStrategy getInlineStrategy() const;
560566
BRIDGED_INLINE bool isSerialized() const;
561-
BRIDGED_INLINE bool hasValidLinkageForFragileRef() const;
567+
BRIDGED_INLINE bool isAnySerialized() const;
568+
BRIDGED_INLINE SerializedKind getSerializedKind() const;
569+
BRIDGED_INLINE bool canBeInlinedIntoCaller(SerializedKind) const;
570+
BRIDGED_INLINE bool hasValidLinkageForFragileRef(SerializedKind) const;
562571
BRIDGED_INLINE ThunkKind isThunk() const;
563572
BRIDGED_INLINE void setThunk(ThunkKind) const;
564573
BRIDGED_INLINE bool needsStackProtection() const;

include/swift/SIL/SILBridgingImpl.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,8 +690,20 @@ bool BridgedFunction::isSerialized() const {
690690
return getFunction()->isSerialized();
691691
}
692692

693-
bool BridgedFunction::hasValidLinkageForFragileRef() const {
694-
return getFunction()->hasValidLinkageForFragileRef();
693+
bool BridgedFunction::isAnySerialized() const {
694+
return getFunction()->isAnySerialized();
695+
}
696+
697+
BridgedFunction::SerializedKind BridgedFunction::getSerializedKind() const {
698+
return (SerializedKind)getFunction()->getSerializedKind();
699+
}
700+
701+
bool BridgedFunction::canBeInlinedIntoCaller(SerializedKind kind) const {
702+
return getFunction()->canBeInlinedIntoCaller(swift::SerializedKind_t(kind));
703+
}
704+
705+
bool BridgedFunction::hasValidLinkageForFragileRef(SerializedKind kind) const {
706+
return getFunction()->hasValidLinkageForFragileRef(swift::SerializedKind_t(kind));
695707
}
696708

697709
bool BridgedFunction::needsStackProtection() const {

include/swift/SIL/SILDeclRef.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace swift {
4646
class EffectsAttr;
4747
class FileUnit;
4848
class SILFunctionType;
49-
enum IsSerialized_t : unsigned char;
49+
enum SerializedKind_t : uint8_t;
5050
enum class SubclassScope : unsigned char;
5151
class SILModule;
5252
class SILLocation;
@@ -384,7 +384,11 @@ struct SILDeclRef {
384384
/// True if the function should be treated as transparent.
385385
bool isTransparent() const;
386386
/// True if the function should have its body serialized.
387-
IsSerialized_t isSerialized() const;
387+
bool isSerialized() const;
388+
/// True if this function is neither [serialized] or [serialized_for_package].
389+
bool isNotSerialized() const;
390+
/// Returns IsNotSerialized, IsSerializedForPackage, or IsSerialized.
391+
SerializedKind_t getSerializedKind() const;
388392
/// True if the function has noinline attribute.
389393
bool isNoinline() const;
390394
/// True if the function has __always inline attribute.

include/swift/SIL/SILFunction.h

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ class SILFunction
364364
unsigned Transparent : 1;
365365

366366
/// The function's serialized attribute.
367-
bool Serialized : 1;
367+
unsigned SerializedKind : 2;
368368

369369
/// Specifies if this function is a thunk or a reabstraction thunk.
370370
///
@@ -504,7 +504,7 @@ class SILFunction
504504
SILFunction(SILModule &module, SILLinkage linkage, StringRef mangledName,
505505
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
506506
IsBare_t isBareSILFunction, IsTransparent_t isTrans,
507-
IsSerialized_t isSerialized, ProfileCounter entryCount,
507+
SerializedKind_t serializedKind, ProfileCounter entryCount,
508508
IsThunk_t isThunk, SubclassScope classSubclassScope,
509509
Inline_t inlineStrategy, EffectsKind E,
510510
const SILDebugScope *debugScope,
@@ -517,7 +517,7 @@ class SILFunction
517517
create(SILModule &M, SILLinkage linkage, StringRef name,
518518
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
519519
std::optional<SILLocation> loc, IsBare_t isBareSILFunction,
520-
IsTransparent_t isTrans, IsSerialized_t isSerialized,
520+
IsTransparent_t isTrans, SerializedKind_t serializedKind,
521521
ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
522522
IsDistributed_t isDistributed,
523523
IsRuntimeAccessible_t isRuntimeAccessible,
@@ -530,7 +530,7 @@ class SILFunction
530530

531531
void init(SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
532532
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,
533-
IsTransparent_t isTrans, IsSerialized_t isSerialized,
533+
IsTransparent_t isTrans, SerializedKind_t serializedKind,
534534
ProfileCounter entryCount, IsThunk_t isThunk,
535535
SubclassScope classSubclassScope, Inline_t inlineStrategy,
536536
EffectsKind E, const SILDebugScope *DebugScope,
@@ -782,11 +782,7 @@ class SILFunction
782782
return getLoweredFunctionType()->getRepresentation();
783783
}
784784

785-
ResilienceExpansion getResilienceExpansion() const {
786-
return (isSerialized()
787-
? ResilienceExpansion::Minimal
788-
: ResilienceExpansion::Maximal);
789-
}
785+
ResilienceExpansion getResilienceExpansion() const;
790786

791787
// Returns the type expansion context to be used inside this function.
792788
TypeExpansionContext getTypeExpansionContext() const {
@@ -877,13 +873,32 @@ class SILFunction
877873
/// Set the function's linkage attribute.
878874
void setLinkage(SILLinkage linkage) { Linkage = unsigned(linkage); }
879875

880-
/// Returns true if this function can be inlined into a fragile function
881-
/// body.
882-
bool hasValidLinkageForFragileInline() const { return isSerialized(); }
876+
/// Checks if this (callee) function body can be inlined into the caller
877+
/// by comparing their `SerializedKind_t` values.
878+
///
879+
/// If both callee and caller are `not_serialized`, the callee can be inlined
880+
/// into the caller during SIL inlining passes even if it (and the caller)
881+
/// might contain private symbols. If this callee is `serialized_for_pkg`,
882+
/// it can only be referenced by a serialized caller but not inlined into
883+
/// it.
884+
///
885+
/// ```
886+
/// canInlineInto: Caller
887+
/// | not_serialized | serialized_for_pkg | serialized
888+
/// not_serialized | ok | no | no
889+
/// Callee serialized_for_pkg | ok | ok | no
890+
/// serialized | ok | ok | ok
891+
///
892+
/// ```
893+
///
894+
/// \p callerSerializedKind The caller's SerializedKind.
895+
bool canBeInlinedIntoCaller(SerializedKind_t callerSerializedKind) const;
883896

884897
/// Returns true if this function can be referenced from a fragile function
885898
/// body.
886-
bool hasValidLinkageForFragileRef() const;
899+
/// \p callerSerializedKind The caller's SerializedKind. Used to be passed to
900+
/// \c canBeInlinedIntoCaller.
901+
bool hasValidLinkageForFragileRef(SerializedKind_t callerSerializedKind) const;
887902

888903
/// Get's the effective linkage which is used to derive the llvm linkage.
889904
/// Usually this is the same as getLinkage(), except in one case: if this
@@ -1137,11 +1152,21 @@ class SILFunction
11371152
assert(!Transparent || !IsDynamicReplaceable);
11381153
}
11391154

1155+
bool isSerialized() const {
1156+
return SerializedKind_t(SerializedKind) == IsSerialized;
1157+
}
1158+
bool isAnySerialized() const {
1159+
return SerializedKind_t(SerializedKind) == IsSerialized ||
1160+
SerializedKind_t(SerializedKind) == IsSerializedForPackage;
1161+
}
1162+
11401163
/// Get this function's serialized attribute.
1141-
IsSerialized_t isSerialized() const { return IsSerialized_t(Serialized); }
1142-
void setSerialized(IsSerialized_t isSerialized) {
1143-
Serialized = isSerialized;
1144-
assert(this->isSerialized() == isSerialized &&
1164+
SerializedKind_t getSerializedKind() const {
1165+
return SerializedKind_t(SerializedKind);
1166+
}
1167+
void setSerializedKind(SerializedKind_t serializedKind) {
1168+
SerializedKind = serializedKind;
1169+
assert(this->getSerializedKind() == serializedKind &&
11451170
"too few bits for Serialized storage");
11461171
}
11471172

0 commit comments

Comments
 (0)