Skip to content

Commit 74e22dc

Browse files
authored
Merge pull request swiftlang#68244 from zoecarver/embedded-swift
2 parents f540753 + 26d223a commit 74e22dc

25 files changed

+212
-21
lines changed

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,14 @@ let mandatoryPerformanceOptimizations = ModulePass(name: "mandatory-performance-
3030
(moduleContext: ModulePassContext) in
3131

3232
var worklist = FunctionWorklist()
33-
worklist.addAllPerformanceAnnotatedFunctions(of: moduleContext)
34-
worklist.addAllAnnotatedGlobalInitOnceFunctions(of: moduleContext)
33+
// For embedded Swift, optimize all the functions (there cannot be any
34+
// generics, type metadata, etc.)
35+
if moduleContext.options.enableEmbeddedSwift {
36+
worklist.addAllNonGenericFunctions(of: moduleContext)
37+
} else {
38+
worklist.addAllPerformanceAnnotatedFunctions(of: moduleContext)
39+
worklist.addAllAnnotatedGlobalInitOnceFunctions(of: moduleContext)
40+
}
3541

3642
optimizeFunctionsTopDown(using: &worklist, moduleContext)
3743
}
@@ -305,6 +311,13 @@ fileprivate struct FunctionWorklist {
305311
}
306312
}
307313

314+
mutating func addAllNonGenericFunctions(of moduleContext: ModulePassContext) {
315+
for f in moduleContext.functions where f.isGenericFunction {
316+
pushIfNotVisited(f)
317+
}
318+
return
319+
}
320+
308321
mutating func addAllAnnotatedGlobalInitOnceFunctions(of moduleContext: ModulePassContext) {
309322
for f in moduleContext.functions where f.isGlobalInitOnceFunction {
310323
if let global = f.getInitializedGlobal(),

SwiftCompilerSources/Sources/Optimizer/PassManager/Options.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ struct Options {
2828
_bridged.enableSimplificationFor(inst.bridged)
2929
}
3030

31+
var enableEmbeddedSwift: Bool {
32+
_bridged.enableEmbeddedSwift()
33+
}
34+
3135
enum AssertConfiguration {
3236
case enabled
3337
case disabled

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
137137
/// It's called from a `[global_init]` function via a `builtin "once"`.
138138
public var isGlobalInitOnceFunction: Bool { bridged.isGlobalInitOnceFunction() }
139139

140+
public var isGenericFunction: Bool { bridged.isGenericFunction() }
141+
140142
/// Kinds of effect attributes which can be defined for a Swift function.
141143
public enum EffectAttribute {
142144
/// No effect attribute is specified.

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,5 +554,8 @@ ERROR(layout_string_instantiation_without_layout_strings,none,
554554
"-enable-layout-string-value-witnesses-instantiation can not be enabled "
555555
"without -enable-layout-string-value-witnesses.", ())
556556

557+
ERROR(evolution_with_embedded,none,
558+
"Library evolution cannot be enabled with embedded Swift.", ())
559+
557560
#define UNDEFINE_DIAGNOSTIC_MACROS
558561
#include "DefineDiagnosticMacros.h"

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ EXPERIMENTAL_FEATURE(ThenStatements, false)
232232
/// Enable the `@_rawLayout` attribute.
233233
EXPERIMENTAL_FEATURE(RawLayout, true)
234234

235+
/// Enables the "embedded" swift mode (no runtime).
236+
EXPERIMENTAL_FEATURE(Embedded, true)
237+
235238
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
236239
#undef EXPERIMENTAL_FEATURE
237240
#undef UPCOMING_FEATURE

include/swift/IRGen/Linking.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ enum class TypeMetadataAddress {
8585
FullMetadata,
8686
};
8787

88+
inline bool isEmbedded(CanType t) {
89+
return t->getASTContext().LangOpts.hasFeature(Feature::Embedded);
90+
}
91+
92+
inline bool isEmbedded(Decl *d) {
93+
return d->getASTContext().LangOpts.hasFeature(Feature::Embedded);
94+
}
95+
96+
inline bool isEmbedded(const ProtocolConformance *c) {
97+
return c->getType()->getASTContext().LangOpts.hasFeature(Feature::Embedded);
98+
}
99+
88100
/// A link entity is some sort of named declaration, combined with all
89101
/// the information necessary to distinguish specific implementations
90102
/// of the declaration from each other.
@@ -828,13 +840,15 @@ class LinkEntity {
828840
static LinkEntity forTypeMetadata(CanType concreteType,
829841
TypeMetadataAddress addr) {
830842
assert(!isObjCImplementation(concreteType));
843+
assert(!isEmbedded(concreteType));
831844
LinkEntity entity;
832845
entity.setForType(Kind::TypeMetadata, concreteType);
833846
entity.Data |= LINKENTITY_SET_FIELD(MetadataAddress, unsigned(addr));
834847
return entity;
835848
}
836849

837850
static LinkEntity forTypeMetadataPattern(NominalTypeDecl *decl) {
851+
assert(!isEmbedded(decl));
838852
LinkEntity entity;
839853
entity.setForDecl(Kind::TypeMetadataPattern, decl);
840854
return entity;
@@ -891,25 +905,29 @@ class LinkEntity {
891905

892906
static LinkEntity forNominalTypeDescriptor(NominalTypeDecl *decl) {
893907
assert(!isObjCImplementation(decl));
908+
assert(!isEmbedded(decl));
894909
LinkEntity entity;
895910
entity.setForDecl(Kind::NominalTypeDescriptor, decl);
896911
return entity;
897912
}
898913

899914
static LinkEntity forNominalTypeDescriptorRecord(NominalTypeDecl *decl) {
900915
assert(!isObjCImplementation(decl));
916+
assert(!isEmbedded(decl));
901917
LinkEntity entity;
902918
entity.setForDecl(Kind::NominalTypeDescriptorRecord, decl);
903919
return entity;
904920
}
905921

906922
static LinkEntity forOpaqueTypeDescriptor(OpaqueTypeDecl *decl) {
923+
assert(!isEmbedded(decl));
907924
LinkEntity entity;
908925
entity.setForDecl(Kind::OpaqueTypeDescriptor, decl);
909926
return entity;
910927
}
911928

912929
static LinkEntity forOpaqueTypeDescriptorRecord(OpaqueTypeDecl *decl) {
930+
assert(!isEmbedded(decl));
913931
LinkEntity entity;
914932
entity.setForDecl(Kind::OpaqueTypeDescriptorRecord, decl);
915933
return entity;
@@ -990,6 +1008,7 @@ class LinkEntity {
9901008
}
9911009

9921010
static LinkEntity forValueWitness(CanType concreteType, ValueWitness witness) {
1011+
assert(!isEmbedded(concreteType));
9931012
LinkEntity entity;
9941013
entity.Pointer = concreteType.getPointer();
9951014
entity.Data = LINKENTITY_SET_FIELD(Kind, unsigned(Kind::ValueWitness))
@@ -998,6 +1017,7 @@ class LinkEntity {
9981017
}
9991018

10001019
static LinkEntity forValueWitnessTable(CanType type) {
1020+
assert(!isEmbedded(type));
10011021
LinkEntity entity;
10021022
entity.setForType(Kind::ValueWitnessTable, type);
10031023
return entity;
@@ -1027,13 +1047,15 @@ class LinkEntity {
10271047
}
10281048

10291049
static LinkEntity forProtocolWitnessTable(const RootProtocolConformance *C) {
1050+
assert(!isEmbedded(C));
10301051
LinkEntity entity;
10311052
entity.setForProtocolConformance(Kind::ProtocolWitnessTable, C);
10321053
return entity;
10331054
}
10341055

10351056
static LinkEntity
10361057
forProtocolWitnessTablePattern(const ProtocolConformance *C) {
1058+
assert(!isEmbedded(C));
10371059
LinkEntity entity;
10381060
entity.setForProtocolConformance(Kind::ProtocolWitnessTablePattern, C);
10391061
return entity;

include/swift/SIL/RuntimeEffect.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ enum class RuntimeEffect : unsigned {
5252
/// The runtime function calls ObjectiveC methods.
5353
ObjectiveC = 0x40,
5454

55+
/// Witness methods, boxing, unboxing, initializing, etc.
56+
Existential = 0x80,
57+
5558
/// Not modelled currently.
5659
Concurrency = 0x0,
5760

include/swift/SIL/SILBridging.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ struct BridgedFunction {
260260
return getFunction()->isGlobalInitOnceFunction();
261261
}
262262

263+
bool isGenericFunction() const {
264+
return getFunction()->getGenericSignature().isNull();
265+
}
266+
263267
bool hasSemanticsAttr(llvm::StringRef attrName) const {
264268
return getFunction()->hasSemanticsAttr(attrName);
265269
}

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,11 @@ struct BridgedPassContext {
494494
return mod->getOptions().EnableStackProtection;
495495
}
496496

497+
bool enableEmbeddedSwift() const {
498+
swift::SILModule *mod = invocation->getPassManager()->getModule();
499+
return mod->getASTContext().LangOpts.hasFeature(swift::Feature::Embedded);
500+
}
501+
497502
bool enableMoveInoutStackProtection() const {
498503
swift::SILModule *mod = invocation->getPassManager()->getModule();
499504
return mod->getOptions().EnableMoveInoutStackProtection;

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,6 +3148,10 @@ static bool usesFeatureBuiltinStackAlloc(Decl *decl) {
31483148
return false;
31493149
}
31503150

3151+
static bool usesFeatureEmbedded(Decl *decl) {
3152+
return false;
3153+
}
3154+
31513155
static bool usesFeatureBuiltinUnprotectedStackAlloc(Decl *decl) {
31523156
return false;
31533157
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
13161316
}
13171317
Opts.BypassResilienceChecks |= Args.hasArg(OPT_bypass_resilience);
13181318

1319+
if (FrontendOpts.EnableLibraryEvolution && Opts.hasFeature(Feature::Embedded)) {
1320+
Diags.diagnose(SourceLoc(), diag::evolution_with_embedded);
1321+
HadError = true;
1322+
}
1323+
13191324
return HadError || UnsupportedOS || UnsupportedArch;
13201325
}
13211326

lib/IRGen/GenClass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,8 +1075,10 @@ void IRGenModule::emitClassDecl(ClassDecl *D) {
10751075
assert(!IRGen.hasLazyMetadata(D));
10761076

10771077
// Emit the class metadata.
1078-
emitClassMetadata(*this, D, fragileLayout, resilientLayout);
1079-
emitFieldDescriptor(D);
1078+
if (!D->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1079+
emitClassMetadata(*this, D, fragileLayout, resilientLayout);
1080+
emitFieldDescriptor(D);
1081+
}
10801082

10811083
IRGen.addClassForEagerInitialization(D);
10821084
IRGen.addBackDeployedObjCActorInitialization(D);

lib/IRGen/GenDecl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,13 @@ void IRGenModule::emitGlobalLists() {
12391239
// Eagerly emit functions that are externally visible. Functions that are
12401240
// dynamic replacements must also be eagerly emitted.
12411241
static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
1242+
// Embedded Swift only emits specialized function, so don't emit genreic
1243+
// functions, even if they're externally visible.
1244+
if (f.getASTContext().LangOpts.hasFeature(Feature::Embedded) &&
1245+
f.getLoweredFunctionType()->getSubstGenericSignature()) {
1246+
return true;
1247+
}
1248+
12421249
if (f.isPossiblyUsedExternally())
12431250
return false;
12441251

@@ -1403,6 +1410,18 @@ deleteAndReenqueueForEmissionValuesDependentOnCanonicalPrespecializedMetadataRec
14031410
/// Emit any lazy definitions (of globals or functions or whatever
14041411
/// else) that we require.
14051412
void IRGenerator::emitLazyDefinitions() {
1413+
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1414+
// In embedded Swift, the compiler cannot emit any metadata, etc.
1415+
LazyTypeMetadata.clear();
1416+
LazySpecializedTypeMetadataRecords.clear();
1417+
LazyTypeContextDescriptors.clear();
1418+
LazyOpaqueTypeDescriptors.clear();
1419+
LazyFunctionDefinitions.clear();
1420+
LazyCanonicalSpecializedMetadataAccessors.clear();
1421+
LazyMetadataAccessors.clear();
1422+
LazyWitnessTables.clear();
1423+
}
1424+
14061425
while (!LazyTypeMetadata.empty() ||
14071426
!LazySpecializedTypeMetadataRecords.empty() ||
14081427
!LazyTypeContextDescriptors.empty() ||

lib/IRGen/GenEnum.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7158,7 +7158,8 @@ const TypeInfo *TypeConverter::convertEnumType(TypeBase *key, CanType type,
71587158
}
71597159

71607160
void IRGenModule::emitEnumDecl(EnumDecl *theEnum) {
7161-
if (!IRGen.hasLazyMetadata(theEnum)) {
7161+
if (!IRGen.hasLazyMetadata(theEnum) &&
7162+
!theEnum->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
71627163
emitEnumMetadata(*this, theEnum);
71637164
emitFieldDescriptor(theEnum);
71647165
}

lib/IRGen/GenExistential.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,11 @@ static void forEachProtocolWitnessTable(
17801780
assert(protocols.size() == witnessConformances.size() &&
17811781
"mismatched protocol conformances");
17821782

1783+
// Don't emit witness tables in embedded Swift.
1784+
if (srcType->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1785+
return;
1786+
}
1787+
17831788
for (unsigned i = 0, e = protocols.size(); i < e; ++i) {
17841789
assert(protocols[i] == witnessConformances[i].getRequirement());
17851790
auto table = emitWitnessTableRef(IGF, srcType, srcMetadataCache,

lib/IRGen/GenMeta.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2568,6 +2568,10 @@ static void eraseExistingTypeContextDescriptor(IRGenModule &IGM,
25682568
void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
25692569
NominalTypeDecl *type,
25702570
RequireMetadata_t requireMetadata) {
2571+
if (type->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
2572+
return;
2573+
}
2574+
25712575
eraseExistingTypeContextDescriptor(IGM, type);
25722576

25732577
bool hasLayoutString = false;
@@ -6466,6 +6470,10 @@ SpecialProtocol irgen::getSpecialProtocolID(ProtocolDecl *P) {
64666470
void IRGenModule::emitProtocolDecl(ProtocolDecl *protocol) {
64676471
PrettyStackTraceDecl stackTraceRAII("emitting metadata for", protocol);
64686472

6473+
if (protocol->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
6474+
return;
6475+
}
6476+
64696477
// Marker protocols are never emitted.
64706478
if (protocol->isMarkerProtocol())
64716479
return;

lib/IRGen/GenProto.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,10 @@ static void addWTableTypeMetadata(IRGenModule &IGM,
23942394
}
23952395

23962396
void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2397+
if (Context.LangOpts.hasFeature(Feature::Embedded)) {
2398+
return;
2399+
}
2400+
23972401
// Don't emit a witness table if it is a declaration.
23982402
if (wt->isDeclaration())
23992403
return;
@@ -3353,6 +3357,8 @@ llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF,
33533357
CanType srcType,
33543358
llvm::Value **srcMetadataCache,
33553359
ProtocolConformanceRef conformance) {
3360+
assert(!srcType->getASTContext().LangOpts.hasFeature(Feature::Embedded));
3361+
33563362
auto proto = conformance.getRequirement();
33573363
assert(Lowering::TypeConverter::protocolRequiresWitnessTable(proto)
33583364
&& "protocol does not have witness tables?!");

lib/IRGen/GenStruct.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,8 @@ const TypeInfo *irgen::getPhysicalStructFieldTypeInfo(IRGenModule &IGM,
15971597
}
15981598

15991599
void IRGenModule::emitStructDecl(StructDecl *st) {
1600-
if (!IRGen.hasLazyMetadata(st)) {
1600+
if (!IRGen.hasLazyMetadata(st) &&
1601+
!st->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
16011602
emitStructMetadata(*this, st);
16021603
emitFieldDescriptor(st);
16031604
}

lib/IRGen/MetadataRequest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3303,6 +3303,8 @@ llvm::Value *IRGenFunction::emitTypeMetadataRef(CanType type) {
33033303
MetadataResponse
33043304
IRGenFunction::emitTypeMetadataRef(CanType type,
33053305
DynamicMetadataRequest request) {
3306+
assert(!type->getASTContext().LangOpts.hasFeature(Feature::Embedded));
3307+
33063308
type = IGM.getRuntimeReifiedType(type);
33073309
// Look through any opaque types we're allowed to.
33083310
type = IGM.substOpaqueTypesWithUnderlyingTypes(type);

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
601601
if (canSkipNominal(NTD))
602602
return;
603603

604+
if (NTD->getASTContext().LangOpts.hasFeature(Feature::Embedded))
605+
return;
606+
604607
auto declaredType = NTD->getDeclaredType()->getCanonicalType();
605608

606609
if (!NTD->getObjCImplementationDecl()) {

0 commit comments

Comments
 (0)