Skip to content

Commit 4908327

Browse files
committed
1 parent ed21303 commit 4908327

File tree

101 files changed

+3499
-641
lines changed

Some content is hidden

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

101 files changed

+3499
-641
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
///
@@ -5966,6 +5976,13 @@ class AbstractStorageDecl : public ValueDecl {
59665976
/// property from the given module?
59675977
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
59685978

5979+
/// True if the decl is resilient AND also its defining module does
5980+
/// _not_ allow non-resilient access; the module can allow such access
5981+
/// if package optimization is enabled so its client modules within the
5982+
/// same package can have a direct access to this decl even if it's
5983+
/// resilient.
5984+
bool isStrictlyResilient() const;
5985+
59695986
/// True if the storage can be referenced by a keypath directly.
59705987
/// Otherwise, its override must be referenced.
59715988
bool isValidKeyPathComponent() const;

include/swift/AST/Module.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,16 @@ class ModuleDecl
736736
Bits.ModuleDecl.AllowNonResilientAccess = flag;
737737
}
738738

739+
/// Returns true if -experimental-package-cmo was passed, which
740+
/// enables serialization of package, public, and inlinable decls in a
741+
/// package. This requires -experimental-allow-non-resilient-access.
742+
bool serializePackageEnabled() const {
743+
return Bits.ModuleDecl.SerializePackageEnabled;
744+
}
745+
void setSerializePackageEnabled(bool flag = true) {
746+
Bits.ModuleDecl.SerializePackageEnabled = flag;
747+
}
748+
739749
/// Returns true if this module is a non-Swift module that was imported into
740750
/// Swift.
741751
///
@@ -783,6 +793,15 @@ class ModuleDecl
783793
return getResilienceStrategy() != ResilienceStrategy::Default;
784794
}
785795

796+
/// True if this module is resilient AND also does _not_ allow
797+
/// non-resilient access; the module can allow such access if
798+
/// package optimization is enabled so its client modules within
799+
/// the same package can have a direct access to decls in this
800+
/// module even if it's built resiliently.
801+
bool isStrictlyResilient() const {
802+
return isResilient() && !allowNonResilientAccess();
803+
}
804+
786805
/// Look up a (possibly overloaded) value set at top-level scope
787806
/// (but with the specified access path, which may come from an import decl)
788807
/// within the current module.

include/swift/AST/Types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6618,6 +6618,8 @@ enum class OpaqueSubstitutionKind {
66186618
// Can be done if the underlying type is accessible from the context we
66196619
// substitute into. Private types cannot be accessed from a different TU.
66206620
SubstituteSameModuleMaximalResilience,
6621+
// Same as previous but with package and above visibility.
6622+
SubstituteSamePackageMaximalResilience,
66216623
// Substitute in a different module from the opaque defining decl. Can only
66226624
// be done if the underlying type is public.
66236625
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
@@ -362,7 +362,7 @@ class SILFunction
362362
unsigned Transparent : 1;
363363

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

367367
/// Specifies if this function is a thunk or a reabstraction thunk.
368368
///
@@ -502,7 +502,7 @@ class SILFunction
502502
SILFunction(SILModule &module, SILLinkage linkage, StringRef mangledName,
503503
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
504504
IsBare_t isBareSILFunction, IsTransparent_t isTrans,
505-
IsSerialized_t isSerialized, ProfileCounter entryCount,
505+
SerializedKind_t serializedKind, ProfileCounter entryCount,
506506
IsThunk_t isThunk, SubclassScope classSubclassScope,
507507
Inline_t inlineStrategy, EffectsKind E,
508508
const SILDebugScope *debugScope,
@@ -515,7 +515,7 @@ class SILFunction
515515
create(SILModule &M, SILLinkage linkage, StringRef name,
516516
CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
517517
std::optional<SILLocation> loc, IsBare_t isBareSILFunction,
518-
IsTransparent_t isTrans, IsSerialized_t isSerialized,
518+
IsTransparent_t isTrans, SerializedKind_t serializedKind,
519519
ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
520520
IsDistributed_t isDistributed,
521521
IsRuntimeAccessible_t isRuntimeAccessible,
@@ -528,7 +528,7 @@ class SILFunction
528528

529529
void init(SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
530530
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,
531-
IsTransparent_t isTrans, IsSerialized_t isSerialized,
531+
IsTransparent_t isTrans, SerializedKind_t serializedKind,
532532
ProfileCounter entryCount, IsThunk_t isThunk,
533533
SubclassScope classSubclassScope, Inline_t inlineStrategy,
534534
EffectsKind E, const SILDebugScope *DebugScope,
@@ -780,11 +780,7 @@ class SILFunction
780780
return getLoweredFunctionType()->getRepresentation();
781781
}
782782

783-
ResilienceExpansion getResilienceExpansion() const {
784-
return (isSerialized()
785-
? ResilienceExpansion::Minimal
786-
: ResilienceExpansion::Maximal);
787-
}
783+
ResilienceExpansion getResilienceExpansion() const;
788784

789785
// Returns the type expansion context to be used inside this function.
790786
TypeExpansionContext getTypeExpansionContext() const {
@@ -875,13 +871,32 @@ class SILFunction
875871
/// Set the function's linkage attribute.
876872
void setLinkage(SILLinkage linkage) { Linkage = unsigned(linkage); }
877873

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

882895
/// Returns true if this function can be referenced from a fragile function
883896
/// body.
884-
bool hasValidLinkageForFragileRef() const;
897+
/// \p callerSerializedKind The caller's SerializedKind. Used to be passed to
898+
/// \c canBeInlinedIntoCaller.
899+
bool hasValidLinkageForFragileRef(SerializedKind_t callerSerializedKind) const;
885900

886901
/// Get's the effective linkage which is used to derive the llvm linkage.
887902
/// Usually this is the same as getLinkage(), except in one case: if this
@@ -1135,11 +1150,21 @@ class SILFunction
11351150
assert(!Transparent || !IsDynamicReplaceable);
11361151
}
11371152

1153+
bool isSerialized() const {
1154+
return SerializedKind_t(SerializedKind) == IsSerialized;
1155+
}
1156+
bool isAnySerialized() const {
1157+
return SerializedKind_t(SerializedKind) == IsSerialized ||
1158+
SerializedKind_t(SerializedKind) == IsSerializedForPackage;
1159+
}
1160+
11381161
/// Get this function's serialized attribute.
1139-
IsSerialized_t isSerialized() const { return IsSerialized_t(Serialized); }
1140-
void setSerialized(IsSerialized_t isSerialized) {
1141-
Serialized = isSerialized;
1142-
assert(this->isSerialized() == isSerialized &&
1162+
SerializedKind_t getSerializedKind() const {
1163+
return SerializedKind_t(SerializedKind);
1164+
}
1165+
void setSerializedKind(SerializedKind_t serializedKind) {
1166+
SerializedKind = serializedKind;
1167+
assert(this->getSerializedKind() == serializedKind &&
11431168
"too few bits for Serialized storage");
11441169
}
11451170

0 commit comments

Comments
 (0)