Skip to content

Commit 52cea42

Browse files
committed
[embedded] 🚀 add Embedded expiremental feature.
Optimize all functions in embedded mode. Diagnose any uses of existentials or witness tables.
1 parent 2c3c3c1 commit 52cea42

File tree

6 files changed

+57
-2
lines changed

6 files changed

+57
-2
lines changed

‎SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

+9
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,15 @@ fileprivate struct FunctionWorklist {
300300
}
301301

302302
mutating func addAllPerformanceAnnotatedFunctions(of moduleContext: ModulePassContext) {
303+
// For embedded Swift, optimize all the functions (there cannot be any
304+
// generics, type metadata, etc.)
305+
if moduleContext.options.enableEmbeddedSwift {
306+
for f in moduleContext.functions {
307+
pushIfNotVisited(f)
308+
}
309+
return
310+
}
311+
303312
for f in moduleContext.functions where f.performanceConstraints != .none {
304313
pushIfNotVisited(f)
305314
}

‎SwiftCompilerSources/Sources/Optimizer/PassManager/Options.swift

+4
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

‎include/swift/Basic/Features.def

+3
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/SILOptimizer/OptimizerBridging.h

+5
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

+4
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/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

+32-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,26 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
353353
SILType impactType;
354354
RuntimeEffect impact = getRuntimeEffect(inst, impactType);
355355
LocWithParent loc(inst->getLoc().getSourceLoc(), parentLoc);
356-
356+
357+
if (isa<WitnessMethodInst>(inst) ||
358+
isa<InitExistentialAddrInst>(inst) ||
359+
isa<InitExistentialValueInst>(inst) ||
360+
isa<InitExistentialRefInst>(inst) ||
361+
isa<OpenExistentialValueInst>(inst) ||
362+
isa<OpenExistentialRefInst>(inst) ||
363+
isa<OpenExistentialAddrInst>(inst) ||
364+
isa<OpenExistentialBoxInst>(inst) ||
365+
isa<OpenExistentialBoxValueInst>(inst) ||
366+
isa<InitExistentialMetatypeInst>(inst) ||
367+
isa<OpenExistentialMetatypeInst>(inst)) {
368+
PrettyStackTracePerformanceDiagnostics stackTrace("existential", inst);
369+
diagnose(loc, diag::performance_metadata, "existential");
370+
return true;
371+
}
372+
373+
if (perfConstr == PerformanceConstraints::None)
374+
return false;
375+
357376
if (impact & RuntimeEffect::Casting) {
358377
// TODO: be more specific on casting.
359378
// E.g. distinguish locking and allocating dynamic casts, etc.
@@ -497,6 +516,11 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
497516
void PerformanceDiagnostics::checkNonAnnotatedFunction(SILFunction *function) {
498517
for (SILBasicBlock &block : *function) {
499518
for (SILInstruction &inst : block) {
519+
if (function->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
520+
auto loc = LocWithParent(inst.getLoc().getSourceLoc(), nullptr);
521+
visitInst(&inst, PerformanceConstraints::None, &loc);
522+
}
523+
500524
auto as = FullApplySite::isa(&inst);
501525
if (!as)
502526
continue;
@@ -592,14 +616,20 @@ class PerformanceDiagnosticsPass : public SILModuleTransform {
592616
}
593617
}
594618

595-
if (!annotatedFunctionsFound)
619+
if (!annotatedFunctionsFound &&
620+
!getModule()->getASTContext().LangOpts.hasFeature(Feature::Embedded))
596621
return;
597622

598623
for (SILFunction &function : *module) {
599624
// Don't rerun diagnostics on deserialized functions.
600625
if (function.wasDeserializedCanonical())
601626
continue;
602627

628+
// Don't check generic functions, they're about to be removed anyway.
629+
if (getModule()->getASTContext().LangOpts.hasFeature(Feature::Embedded) &&
630+
function.getLoweredFunctionType()->getSubstGenericSignature())
631+
continue;
632+
603633
if (function.getPerfConstraints() == PerformanceConstraints::None) {
604634
diagnoser.checkNonAnnotatedFunction(&function);
605635
}

0 commit comments

Comments
 (0)