16
16
#include " RValue.h"
17
17
#include " SILGenFunction.h"
18
18
#include " SILGenFunctionBuilder.h"
19
+ #include " SILGenTopLevel.h"
19
20
#include " Scope.h"
20
21
#include " swift/AST/Decl.h"
21
22
#include " swift/AST/DiagnosticsSIL.h"
@@ -51,7 +52,7 @@ using namespace Lowering;
51
52
// ===----------------------------------------------------------------------===//
52
53
53
54
SILGenModule::SILGenModule (SILModule &M, ModuleDecl *SM)
54
- : M(M), Types(M.Types), SwiftModule(SM), TopLevelSGF( nullptr ),
55
+ : M(M), Types(M.Types), SwiftModule(SM),
55
56
FileIDsByFilePath(SM->computeFileIDMap (/* shouldDiagnose=*/ true )) {
56
57
const SILOptions &Opts = M.getOptions ();
57
58
if (!Opts.UseProfile .empty ()) {
@@ -70,7 +71,6 @@ SILGenModule::SILGenModule(SILModule &M, ModuleDecl *SM)
70
71
}
71
72
72
73
SILGenModule::~SILGenModule () {
73
- assert (!TopLevelSGF && " active source file lowering!?" );
74
74
75
75
// Update the linkage of external private functions to public_external,
76
76
// because there is no private_external linkage. External private functions
@@ -962,7 +962,6 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
962
962
auto *pbd = var->getParentPatternBinding ();
963
963
unsigned idx = pbd->getPatternEntryIndexForVarDecl (var);
964
964
auto *initDC = pbd->getInitContext (idx);
965
- auto captureInfo = pbd->getCaptureInfo (idx);
966
965
auto *init = constant.getInitializationExpr ();
967
966
assert (init);
968
967
@@ -971,17 +970,6 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
971
970
PrettyStackTraceSILFunction X (" silgen emitStoredPropertyInitialization" , f);
972
971
f->createProfiler (constant);
973
972
SILGenFunction SGF (*this , *f, initDC);
974
-
975
- // If this is a stored property initializer inside a type at global scope,
976
- // it may close over a global variable. If we're emitting top-level code,
977
- // then emit a "mark_function_escape" that lists the captured global
978
- // variables so that definite initialization can reason about this
979
- // escape point.
980
- if (!var->getDeclContext ()->isLocalContext () && TopLevelSGF &&
981
- TopLevelSGF->B .hasValidInsertionPoint ()) {
982
- emitMarkFunctionEscapeForTopLevelCodeGlobals (var, captureInfo);
983
- }
984
-
985
973
SGF.emitGeneratorFunction (constant, init, /* EmitProfilerIncrement=*/ true );
986
974
postEmitFunction (constant, f);
987
975
break ;
@@ -1107,9 +1095,15 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
1107
1095
case SILDeclRef::Kind::AsyncEntryPoint:
1108
1096
case SILDeclRef::Kind::EntryPoint: {
1109
1097
f->setBare (IsBare);
1098
+ if (constant.hasFileUnit ()) {
1099
+ auto *File = constant.getFileUnit ();
1100
+ // In script mode
1101
+ assert (isa<SourceFile>(File) && " Emitting entry-point of non source file?!" );
1102
+ auto *SF = cast<SourceFile>(File);
1103
+ emitEntryPoint (SF, f);
1104
+ return ;
1105
+ }
1110
1106
1111
- // TODO: Handle main SourceFile emission (currently done by
1112
- // SourceFileScope).
1113
1107
auto loc = constant.getAsRegularLocation ();
1114
1108
preEmitFunction (constant, f, loc);
1115
1109
auto *decl = constant.getDecl ();
@@ -1363,41 +1357,10 @@ void SILGenModule::emitDifferentiabilityWitness(
1363
1357
vjp);
1364
1358
}
1365
1359
1366
- void SILGenModule::
1367
- emitMarkFunctionEscapeForTopLevelCodeGlobals (SILLocation loc,
1368
- CaptureInfo captureInfo) {
1369
- assert (TopLevelSGF && TopLevelSGF->B .hasValidInsertionPoint ()
1370
- && " no valid code generator for top-level function?!" );
1371
-
1372
- SmallVector<SILValue, 4 > Captures;
1373
-
1374
- for (auto capture : captureInfo.getCaptures ()) {
1375
- // Decls captured by value don't escape.
1376
- auto It = TopLevelSGF->VarLocs .find (capture.getDecl ());
1377
- if (It == TopLevelSGF->VarLocs .end () ||
1378
- !It->getSecond ().value ->getType ().isAddress ())
1379
- continue ;
1380
-
1381
- Captures.push_back (It->second .value );
1382
- }
1383
-
1384
- if (!Captures.empty ())
1385
- TopLevelSGF->B .createMarkFunctionEscape (loc, Captures);
1386
- }
1387
-
1388
1360
void SILGenModule::emitAbstractFuncDecl (AbstractFunctionDecl *AFD) {
1389
1361
// Emit default arguments and property wrapper initializers.
1390
1362
emitArgumentGenerators (AFD, AFD->getParameters ());
1391
1363
1392
- // If this is a function at global scope, it may close over a global variable.
1393
- // If we're emitting top-level code, then emit a "mark_function_escape" that
1394
- // lists the captured global variables so that definite initialization can
1395
- // reason about this escape point.
1396
- if (!AFD->getDeclContext ()->isLocalContext () &&
1397
- TopLevelSGF && TopLevelSGF->B .hasValidInsertionPoint ()) {
1398
- emitMarkFunctionEscapeForTopLevelCodeGlobals (AFD, AFD->getCaptureInfo ());
1399
- }
1400
-
1401
1364
// If the declaration is exported as a C function, emit its native-to-foreign
1402
1365
// thunk too, if it wasn't already forced.
1403
1366
if (AFD->getAttrs ().hasAttribute <CDeclAttr>()) {
@@ -1770,7 +1733,6 @@ void SILGenModule::emitObjCDestructorThunk(DestructorDecl *destructor) {
1770
1733
}
1771
1734
1772
1735
void SILGenModule::visitPatternBindingDecl (PatternBindingDecl *pd) {
1773
- assert (!TopLevelSGF && " script mode PBDs should be in TopLevelCodeDecls" );
1774
1736
for (auto i : range (pd->getNumPatternEntries ()))
1775
1737
if (pd->getExecutableInit (i))
1776
1738
emitGlobalInitialization (pd, i);
@@ -1964,225 +1926,8 @@ void SILGenModule::visitPoundDiagnosticDecl(PoundDiagnosticDecl *PDD) {
1964
1926
// Nothing to do for #error/#warning; they've already been emitted.
1965
1927
}
1966
1928
1967
- void SILGenModule::visitTopLevelCodeDecl (TopLevelCodeDecl *td) {
1968
- assert (TopLevelSGF && " top-level code in a non-main source file!" );
1969
-
1970
- if (!TopLevelSGF->B .hasValidInsertionPoint ())
1971
- return ;
1972
-
1973
- TopLevelSGF->emitProfilerIncrement (td->getBody ());
1974
-
1975
- DebugScope DS (*TopLevelSGF, CleanupLocation (td));
1976
-
1977
- for (auto &ESD : td->getBody ()->getElements ()) {
1978
- if (!TopLevelSGF->B .hasValidInsertionPoint ()) {
1979
- if (auto *S = ESD.dyn_cast <Stmt*>()) {
1980
- if (S->isImplicit ())
1981
- continue ;
1982
- } else if (auto *E = ESD.dyn_cast <Expr*>()) {
1983
- if (E->isImplicit ())
1984
- continue ;
1985
- }
1986
-
1987
- diagnose (ESD.getStartLoc (), diag::unreachable_code);
1988
- // There's no point in trying to emit anything else.
1989
- return ;
1990
- }
1991
-
1992
- if (auto *S = ESD.dyn_cast <Stmt*>()) {
1993
- TopLevelSGF->emitStmt (S);
1994
- } else if (auto *E = ESD.dyn_cast <Expr*>()) {
1995
- TopLevelSGF->emitIgnoredExpr (E);
1996
- } else {
1997
- TopLevelSGF->visit (ESD.get <Decl*>());
1998
- }
1999
- }
2000
- }
2001
-
2002
1929
namespace {
2003
1930
2004
- // / An RAII class to scope source file codegen.
2005
- class SourceFileScope {
2006
- SILGenModule &sgm;
2007
- SILDeclRef EntryRef;
2008
- llvm::Optional<Scope> scope;
2009
- bool isAsyncTopLevel = false ;
2010
- public:
2011
- SourceFileScope (SILGenModule &sgm, SourceFile *sf) : sgm(sgm) {
2012
- // If this is the script-mode file for the module, create a toplevel.
2013
- // TODO: We need to unify emission of the entry point such that we walk
2014
- // all of the TopLevelCodeDecls in one shot. This will be needed in order
2015
- // to requestify entry point emission.
2016
- if (sf->isScriptMode ()) {
2017
- assert (!sgm.TopLevelSGF && " already emitted toplevel?!" );
2018
- assert (!sgm.M .lookUpFunction (
2019
- sgm.getASTContext ().getEntryPointFunctionName ()) &&
2020
- " already emitted toplevel?!" );
2021
-
2022
- auto mainEntryRef = SILDeclRef::getMainFileEntryPoint (sf);
2023
- SILFunction * toplevel = sgm.getFunction (mainEntryRef, ForDefinition);
2024
- toplevel->setBare (IsBare);
2025
- EntryRef = mainEntryRef;
2026
-
2027
- if (sf->isAsyncContext ()) {
2028
- isAsyncTopLevel = true ;
2029
- auto asyncEntryRef = SILDeclRef::getAsyncMainFileEntryPoint (sf);
2030
- auto *asyncTopLevel = sgm.getFunction (asyncEntryRef, ForDefinition);
2031
- SILGenFunction (sgm, *toplevel, sf).emitAsyncMainThreadStart (asyncEntryRef);
2032
- toplevel = asyncTopLevel;
2033
- EntryRef = asyncEntryRef;
2034
- }
2035
-
2036
- toplevel->createProfiler (EntryRef);
2037
-
2038
- sgm.TopLevelSGF = new SILGenFunction (sgm, *toplevel, sf);
2039
- sgm.TopLevelSGF ->MagicFunctionName = sgm.SwiftModule ->getName ();
2040
- auto moduleCleanupLoc = CleanupLocation::getModuleCleanupLocation ();
2041
-
2042
- sgm.TopLevelSGF ->prepareEpilog (llvm::None, true , moduleCleanupLoc);
2043
-
2044
- auto prologueLoc = RegularLocation::getModuleLocation ();
2045
- prologueLoc.markAsPrologue ();
2046
- if (sf->isAsyncContext ()) {
2047
- // emitAsyncMainThreadStart will create argc and argv.
2048
- // Just set the main actor as the expected executor; we should
2049
- // already be running on it.
2050
- SILValue executor = sgm.TopLevelSGF ->emitMainExecutor (prologueLoc);
2051
- sgm.TopLevelSGF ->ExpectedExecutor =
2052
- sgm.TopLevelSGF ->B .createOptionalSome (
2053
- prologueLoc, executor,
2054
- SILType::getOptionalType (executor->getType ()));
2055
- } else {
2056
- // Create the argc and argv arguments.
2057
- auto entry = sgm.TopLevelSGF ->B .getInsertionBB ();
2058
- auto context = sgm.TopLevelSGF ->getTypeExpansionContext ();
2059
- auto paramTypeIter = sgm.TopLevelSGF ->F .getConventions ()
2060
- .getParameterSILTypes (context)
2061
- .begin ();
2062
-
2063
- entry->createFunctionArgument (*paramTypeIter);
2064
- entry->createFunctionArgument (*std::next (paramTypeIter));
2065
- }
2066
- scope.emplace (sgm.TopLevelSGF ->Cleanups , moduleCleanupLoc);
2067
- }
2068
- }
2069
-
2070
- ~SourceFileScope () {
2071
- if (sgm.TopLevelSGF ) {
2072
- scope.reset ();
2073
-
2074
- // Unregister the top-level function emitter.
2075
- auto &SGF = *sgm.TopLevelSGF ;
2076
- sgm.TopLevelSGF = nullptr ;
2077
-
2078
- // Write out the epilog.
2079
- auto moduleLoc = RegularLocation::getModuleLocation ();
2080
- moduleLoc.markAutoGenerated ();
2081
- auto returnInfo = SGF.emitEpilogBB (moduleLoc);
2082
- auto returnLoc = returnInfo.second ;
2083
- returnLoc.markAutoGenerated ();
2084
-
2085
- SILFunction *exitFunc = nullptr ;
2086
-
2087
- SILType returnType;
2088
- if (isAsyncTopLevel) {
2089
- FuncDecl *exitFuncDecl = sgm.getExit ();
2090
- assert (exitFuncDecl && " Failed to find exit function declaration" );
2091
- exitFunc = sgm.getFunction (
2092
- SILDeclRef (exitFuncDecl, SILDeclRef::Kind::Func, /* isForeign*/ true ),
2093
- NotForDefinition);
2094
- SILFunctionType & funcType = *exitFunc->getLoweredType ().getAs <SILFunctionType>();
2095
- returnType = SILType::getPrimitiveObjectType (
2096
- funcType.getParameters ().front ().getInterfaceType ());
2097
- } else {
2098
- returnType = SGF.F .getConventions ().getSingleSILResultType (
2099
- SGF.getTypeExpansionContext ());
2100
- }
2101
-
2102
- auto emitTopLevelReturnValue = [&](unsigned value) -> SILValue {
2103
- // Create an integer literal for the value.
2104
- auto litType = SILType::getBuiltinIntegerType (32 , sgm.getASTContext ());
2105
- SILValue retValue =
2106
- SGF.B .createIntegerLiteral (moduleLoc, litType, value);
2107
-
2108
- // Wrap that in a struct if necessary.
2109
- if (litType != returnType) {
2110
- retValue = SGF.B .createStruct (moduleLoc, returnType, retValue);
2111
- }
2112
- return retValue;
2113
- };
2114
-
2115
- // Fallthrough should signal a normal exit by returning 0.
2116
- SILValue returnValue;
2117
- if (SGF.B .hasValidInsertionPoint ())
2118
- returnValue = emitTopLevelReturnValue (0 );
2119
-
2120
- // Handle the implicit rethrow block.
2121
- auto rethrowBB = SGF.ThrowDest .getBlock ();
2122
- SGF.ThrowDest = JumpDest::invalid ();
2123
-
2124
- // If the rethrow block wasn't actually used, just remove it.
2125
- if (rethrowBB->pred_empty ()) {
2126
- SGF.eraseBasicBlock (rethrowBB);
2127
-
2128
- // Otherwise, we need to produce a unified return block.
2129
- } else {
2130
- auto returnBB = SGF.createBasicBlock ();
2131
- if (SGF.B .hasValidInsertionPoint ())
2132
- SGF.B .createBranch (returnLoc, returnBB, returnValue);
2133
- returnValue =
2134
- returnBB->createPhiArgument (returnType, OwnershipKind::Owned);
2135
- SGF.B .emitBlock (returnBB);
2136
-
2137
- // Emit the rethrow block.
2138
- SILGenSavedInsertionPoint savedIP (SGF, rethrowBB,
2139
- FunctionSection::Postmatter);
2140
-
2141
- // Log the error.
2142
- SILValue error = rethrowBB->getArgument (0 );
2143
- SGF.B .createBuiltin (moduleLoc,
2144
- sgm.getASTContext ().getIdentifier (" errorInMain" ),
2145
- sgm.Types .getEmptyTupleType (), {}, {error});
2146
-
2147
- // Then end the lifetime of the error.
2148
- //
2149
- // We do this to appease the ownership verifier. We do not care about
2150
- // actually destroying the value since we are going to immediately exit,
2151
- // so this saves us a slight bit of code-size since end_lifetime is
2152
- // stripped out after ownership is removed.
2153
- SGF.B .createEndLifetime (moduleLoc, error);
2154
-
2155
- // Signal an abnormal exit by returning 1.
2156
- SGF.Cleanups .emitCleanupsForReturn (CleanupLocation (moduleLoc),
2157
- IsForUnwind);
2158
- SGF.B .createBranch (returnLoc, returnBB, emitTopLevelReturnValue (1 ));
2159
- }
2160
-
2161
- // Return.
2162
- if (SGF.B .hasValidInsertionPoint ()) {
2163
-
2164
- if (isAsyncTopLevel) {
2165
- SILValue exitCall = SGF.B .createFunctionRef (moduleLoc, exitFunc);
2166
- SGF.B .createApply (moduleLoc, exitCall, {}, {returnValue});
2167
- SGF.B .createUnreachable (moduleLoc);
2168
- } else {
2169
- SGF.B .createReturn (returnLoc, returnValue);
2170
- }
2171
- }
2172
-
2173
- // Okay, we're done emitting the top-level function; destroy the
2174
- // emitter and verify the result.
2175
- SILFunction *toplevel = &SGF.getFunction ();
2176
- delete &SGF;
2177
-
2178
- LLVM_DEBUG (llvm::dbgs () << " lowered toplevel sil:\n " ;
2179
- toplevel->print (llvm::dbgs ()));
2180
- toplevel->verifyIncompleteOSSA ();
2181
- sgm.emitLazyConformancesForFunction (toplevel);
2182
- }
2183
- }
2184
- };
2185
-
2186
1931
// An RAII object that constructs a \c SILGenModule instance.
2187
1932
// On destruction, delayed definitions are automatically emitted.
2188
1933
class SILGenModuleRAII {
@@ -2193,7 +1938,10 @@ class SILGenModuleRAII {
2193
1938
// Type-check the file if we haven't already.
2194
1939
performTypeChecking (*sf);
2195
1940
2196
- SourceFileScope scope (SGM, sf);
1941
+ if (sf->isScriptMode ()) {
1942
+ SGM.emitEntryPoint (sf);
1943
+ }
1944
+
2197
1945
for (auto *D : sf->getTopLevelDecls ()) {
2198
1946
// Emit auxiliary decls.
2199
1947
D->visitAuxiliaryDecls ([&](Decl *auxiliaryDecl) {
0 commit comments