Skip to content

Commit 67d0ea5

Browse files
authored
Merge pull request #2328 from swiftwasm/main
[pull] swiftwasm from main
2 parents 2e7e58b + 7a7179d commit 67d0ea5

File tree

24 files changed

+412
-126
lines changed

24 files changed

+412
-126
lines changed

lib/Frontend/CompilerInvocation.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,26 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
8181
DiagnosticOpts.LocalizationPath = std::string(DiagnosticMessagesDir.str());
8282
}
8383

84+
static std::string
85+
getVersionedPrebuiltModulePath(Optional<llvm::VersionTuple> sdkVer,
86+
StringRef defaultPrebuiltPath) {
87+
if (!sdkVer.hasValue())
88+
return defaultPrebuiltPath.str();
89+
std::string versionStr = sdkVer->getAsString();
90+
StringRef vs = versionStr;
91+
do {
92+
SmallString<64> pathWithSDKVer = defaultPrebuiltPath;
93+
llvm::sys::path::append(pathWithSDKVer, vs);
94+
if (llvm::sys::fs::exists(pathWithSDKVer)) {
95+
return pathWithSDKVer.str().str();
96+
} else if (vs.endswith(".0")) {
97+
vs = vs.substr(0, vs.size() - 2);
98+
} else {
99+
return defaultPrebuiltPath.str();
100+
}
101+
} while(true);
102+
}
103+
84104
void CompilerInvocation::setDefaultPrebuiltCacheIfNecessary() {
85105

86106
if (!FrontendOpts.PrebuiltModuleCachePath.empty())
@@ -101,18 +121,8 @@ void CompilerInvocation::setDefaultPrebuiltCacheIfNecessary() {
101121

102122
// If the SDK version is given, we should check if SDK-versioned prebuilt
103123
// module cache is available and use it if so.
104-
if (auto ver = LangOpts.SDKVersion) {
105-
// "../macosx/prebuilt-modules"
106-
SmallString<64> defaultPrebuiltPathWithSDKVer = defaultPrebuiltPath;
107-
// "../macosx/prebuilt-modules/10.15"
108-
llvm::sys::path::append(defaultPrebuiltPathWithSDKVer, ver->getAsString());
109-
// If the versioned prebuilt module cache exists in the disk, use it.
110-
if (llvm::sys::fs::exists(defaultPrebuiltPathWithSDKVer)) {
111-
FrontendOpts.PrebuiltModuleCachePath = std::string(defaultPrebuiltPathWithSDKVer.str());
112-
return;
113-
}
114-
}
115-
FrontendOpts.PrebuiltModuleCachePath = std::string(defaultPrebuiltPath.str());
124+
FrontendOpts.PrebuiltModuleCachePath =
125+
getVersionedPrebuiltModulePath(LangOpts.SDKVersion, defaultPrebuiltPath);
116126
}
117127

118128
static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,

lib/Parse/ParseType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
368368
// Parse an async specifier.
369369
SourceLoc asyncLoc;
370370
if (shouldParseExperimentalConcurrency() &&
371-
Tok.isContextualKeyword("async")) {
371+
Tok.isContextualKeyword("async") &&
372+
peekToken().isAny(tok::arrow, tok::kw_throws)) {
372373
asyncLoc = consumeToken();
373374
}
374375

lib/SILGen/SwitchEnumBuilder.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ void SwitchCaseFullExpr::unreachableExit() {
6767
//===----------------------------------------------------------------------===//
6868

6969
void SwitchEnumBuilder::emit() && {
70-
bool isAddressOnly = optional.getType().isAddressOnly(builder.getFunction()) &&
71-
getSGF().silConv.useLoweredAddresses();
70+
bool isAddressOnly =
71+
subjectExprOperand.getType().isAddressOnly(builder.getFunction()) &&
72+
getSGF().silConv.useLoweredAddresses();
7273
using DeclBlockPair = std::pair<EnumElementDecl *, SILBasicBlock *>;
7374
{
7475
// TODO: We could store the data in CaseBB form and not have to do this.
@@ -90,20 +91,20 @@ void SwitchEnumBuilder::emit() && {
9091
defaultBlockData ? defaultBlockData->count : ProfileCounter();
9192
ArrayRef<ProfileCounter> caseBlockCountsRef = caseBlockCounts;
9293
if (isAddressOnly) {
93-
builder.createSwitchEnumAddr(loc, optional.getValue(), defaultBlock,
94-
caseBlocks, caseBlockCountsRef,
94+
builder.createSwitchEnumAddr(loc, subjectExprOperand.getValue(),
95+
defaultBlock, caseBlocks, caseBlockCountsRef,
9596
defaultBlockCount);
9697
} else {
97-
if (optional.getType().isAddress()) {
98+
if (subjectExprOperand.getType().isAddress()) {
9899
// TODO: Refactor this into a maybe load.
99-
if (optional.hasCleanup()) {
100-
optional = builder.createLoadTake(loc, optional);
100+
if (subjectExprOperand.hasCleanup()) {
101+
subjectExprOperand = builder.createLoadTake(loc, subjectExprOperand);
101102
} else {
102-
optional = builder.createLoadCopy(loc, optional);
103+
subjectExprOperand = builder.createLoadCopy(loc, subjectExprOperand);
103104
}
104105
}
105-
builder.createSwitchEnum(loc, optional.forward(getSGF()), defaultBlock,
106-
caseBlocks, caseBlockCountsRef,
106+
builder.createSwitchEnum(loc, subjectExprOperand.forward(getSGF()),
107+
defaultBlock, caseBlocks, caseBlockCountsRef,
107108
defaultBlockCount);
108109
}
109110
}
@@ -121,9 +122,9 @@ void SwitchEnumBuilder::emit() && {
121122
SwitchCaseFullExpr presentScope(builder.getSILGenFunction(),
122123
CleanupLocation::get(loc), branchDest);
123124
builder.emitBlock(defaultBlock);
124-
ManagedValue input = optional;
125+
ManagedValue input = subjectExprOperand;
125126
if (!isAddressOnly) {
126-
input = builder.createOwnedPhiArgument(optional.getType());
127+
input = builder.createOwnedPhiArgument(subjectExprOperand.getType());
127128
}
128129
handler(input, std::move(presentScope));
129130
builder.clearInsertionPoint();
@@ -144,9 +145,9 @@ void SwitchEnumBuilder::emit() && {
144145
ManagedValue input;
145146
if (decl->hasAssociatedValues()) {
146147
// Pull the payload out if we have one.
147-
SILType inputType = optional.getType().getEnumElementType(
148+
SILType inputType = subjectExprOperand.getType().getEnumElementType(
148149
decl, builder.getModule(), builder.getFunction());
149-
input = optional;
150+
input = subjectExprOperand;
150151
if (!isAddressOnly) {
151152
input = builder.createOwnedPhiArgument(inputType);
152153
}
@@ -167,9 +168,9 @@ void SwitchEnumBuilder::emit() && {
167168
SwitchCaseFullExpr presentScope(builder.getSILGenFunction(),
168169
CleanupLocation::get(loc), branchDest);
169170
builder.emitBlock(defaultBlock);
170-
ManagedValue input = optional;
171+
ManagedValue input = subjectExprOperand;
171172
if (!isAddressOnly) {
172-
input = builder.createOwnedPhiArgument(optional.getType());
173+
input = builder.createOwnedPhiArgument(subjectExprOperand.getType());
173174
}
174175
handler(input, std::move(presentScope));
175176
builder.clearInsertionPoint();

lib/SILGen/SwitchEnumBuilder.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,14 @@ class SwitchEnumBuilder {
133133

134134
SILGenBuilder &builder;
135135
SILLocation loc;
136-
ManagedValue optional;
136+
ManagedValue subjectExprOperand;
137137
llvm::Optional<DefaultCaseData> defaultBlockData;
138138
llvm::SmallVector<NormalCaseData, 8> caseDataArray;
139139

140140
public:
141141
SwitchEnumBuilder(SILGenBuilder &builder, SILLocation loc,
142-
ManagedValue optional)
143-
: builder(builder), loc(loc), optional(optional) {}
142+
ManagedValue subjectExprOperand)
143+
: builder(builder), loc(loc), subjectExprOperand(subjectExprOperand) {}
144144

145145
void addDefaultCase(
146146
SILBasicBlock *defaultBlock, SwitchCaseBranchDest branchDest,

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -822,12 +822,12 @@ static SILInstruction *tryDevirtualizeApplyHelper(FullApplySite InnerAI,
822822
///
823823
/// \returns true if successful, false if failed due to circular inlining.
824824
static bool
825-
runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
826-
SILFunction *F, FullApplySite AI,
827-
DenseFunctionSet &FullyInlinedSet,
825+
runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder, SILFunction *F,
826+
FullApplySite AI, DenseFunctionSet &FullyInlinedSet,
828827
ImmutableFunctionSet::Factory &SetFactory,
829828
ImmutableFunctionSet CurrentInliningSet,
830-
ClassHierarchyAnalysis *CHA) {
829+
ClassHierarchyAnalysis *CHA,
830+
DenseFunctionSet &changedFunctions) {
831831
// Avoid reprocessing functions needlessly.
832832
if (FullyInlinedSet.count(F))
833833
return true;
@@ -874,6 +874,10 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
874874
// but a casted result of InnerAI or even a block argument due to
875875
// abstraction changes when calling the witness or class method.
876876
auto *devirtInst = tryDevirtualizeApplyHelper(InnerAI, CHA);
877+
// If devirtualization succeeds, make sure we record that this function
878+
// changed.
879+
if (devirtInst != InnerAI.getInstruction())
880+
changedFunctions.insert(F);
877881
// Restore II to the current apply site.
878882
II = devirtInst->getReverseIterator();
879883
// If the devirtualized call result is no longer a invalid FullApplySite,
@@ -892,9 +896,9 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
892896
continue;
893897

894898
// Then recursively process it first before trying to inline it.
895-
if (!runOnFunctionRecursively(FuncBuilder, CalleeFunction, InnerAI,
896-
FullyInlinedSet, SetFactory,
897-
CurrentInliningSet, CHA)) {
899+
if (!runOnFunctionRecursively(
900+
FuncBuilder, CalleeFunction, InnerAI, FullyInlinedSet, SetFactory,
901+
CurrentInliningSet, CHA, changedFunctions)) {
898902
// If we failed due to circular inlining, then emit some notes to
899903
// trace back the failure if we have more information.
900904
// FIXME: possibly it could be worth recovering and attempting other
@@ -984,6 +988,10 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
984988
closureCleanup.cleanupDeadClosures(F);
985989
invalidatedStackNesting |= closureCleanup.invalidatedStackNesting;
986990

991+
// Record that we inlined into this function so that we can invalidate it
992+
// later.
993+
changedFunctions.insert(F);
994+
987995
// Resume inlining within nextBB, which contains only the inlined
988996
// instructions and possibly instructions in the original call block that
989997
// have not yet been visited.
@@ -993,6 +1001,7 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
9931001

9941002
if (invalidatedStackNesting) {
9951003
StackNesting().correctStackNesting(F);
1004+
changedFunctions.insert(F);
9961005
}
9971006

9981007
// Keep track of full inlined functions so we don't waste time recursively
@@ -1012,10 +1021,10 @@ class MandatoryInlining : public SILModuleTransform {
10121021
void run() override {
10131022
ClassHierarchyAnalysis *CHA = getAnalysis<ClassHierarchyAnalysis>();
10141023
SILModule *M = getModule();
1015-
bool ShouldCleanup = !getOptions().DebugSerialization;
10161024
bool SILVerifyAll = getOptions().VerifyAll;
10171025
DenseFunctionSet FullyInlinedSet;
10181026
ImmutableFunctionSet::Factory SetFactory;
1027+
DenseFunctionSet changedFunctions;
10191028

10201029
SILOptFunctionBuilder FuncBuilder(*this);
10211030
for (auto &F : *M) {
@@ -1027,13 +1036,15 @@ class MandatoryInlining : public SILModuleTransform {
10271036
if (F.wasDeserializedCanonical())
10281037
continue;
10291038

1030-
runOnFunctionRecursively(FuncBuilder, &F,
1031-
FullApplySite(), FullyInlinedSet, SetFactory,
1032-
SetFactory.getEmptySet(), CHA);
1039+
runOnFunctionRecursively(FuncBuilder, &F, FullApplySite(),
1040+
FullyInlinedSet, SetFactory,
1041+
SetFactory.getEmptySet(), CHA, changedFunctions);
10331042

10341043
// The inliner splits blocks at call sites. Re-merge trivial branches
10351044
// to reestablish a canonical CFG.
1036-
mergeBasicBlocks(&F);
1045+
if (mergeBasicBlocks(&F)) {
1046+
changedFunctions.insert(&F);
1047+
}
10371048

10381049
// If we are asked to perform SIL verify all, perform that now so that we
10391050
// can discover the immediate inlining trigger of the problematic
@@ -1043,38 +1054,10 @@ class MandatoryInlining : public SILModuleTransform {
10431054
}
10441055
}
10451056

1046-
if (!ShouldCleanup)
1057+
if (getOptions().DebugSerialization)
10471058
return;
1048-
1049-
// Now that we've inlined some functions, clean up. If there are any
1050-
// transparent functions that are deserialized from another module that are
1051-
// now unused, just remove them from the module.
1052-
//
1053-
// We do this with a simple linear scan, because transparent functions that
1054-
// reference each other have already been flattened.
1055-
for (auto FI = M->begin(), E = M->end(); FI != E; ) {
1056-
SILFunction &F = *FI++;
1057-
1058-
invalidateAnalysis(&F, SILAnalysis::InvalidationKind::Everything);
1059-
1060-
if (F.getRefCount() != 0) continue;
1061-
1062-
// Leave non-transparent functions alone.
1063-
if (!F.isTransparent())
1064-
continue;
1065-
1066-
// We discard functions that don't have external linkage,
1067-
// e.g. deserialized functions, internal functions, and thunks.
1068-
// Being marked transparent controls this.
1069-
if (F.isPossiblyUsedExternally()) continue;
1070-
1071-
// ObjC functions are called through the runtime and are therefore alive
1072-
// even if not referenced inside SIL.
1073-
if (F.getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod)
1074-
continue;
1075-
1076-
// Okay, just erase the function from the module.
1077-
FuncBuilder.eraseFunction(&F);
1059+
for (auto *F : changedFunctions) {
1060+
invalidateAnalysis(F, SILAnalysis::InvalidationKind::Everything);
10781061
}
10791062
}
10801063

lib/SymbolGraphGen/FormatVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515

1616
#define SWIFT_SYMBOLGRAPH_FORMAT_MAJOR 0
1717
#define SWIFT_SYMBOLGRAPH_FORMAT_MINOR 5
18-
#define SWIFT_SYMBOLGRAPH_FORMAT_PATCH 0
18+
#define SWIFT_SYMBOLGRAPH_FORMAT_PATCH 1
1919

2020
#endif // SWIFT_SYMBOLGRAPHGEN_FORMATVERSION_H

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ SymbolGraph::SymbolGraph(SymbolGraphASTWalker &Walker,
3939
M(M),
4040
ExtendedModule(ExtendedModule),
4141
Ctx(Ctx),
42-
ModuleVersion(ModuleVersion) {}
42+
ModuleVersion(ModuleVersion) {
43+
if (auto *DM = M.getDeclaringModuleIfCrossImportOverlay()) {
44+
DeclaringModule = DM;
45+
SmallVector<Identifier, 1> Bystanders;
46+
if (M.getRequiredBystandersIfCrossImportOverlay(DM, Bystanders)) {
47+
BystanderModules = Bystanders;
48+
}
49+
}
50+
}
4351

4452
// MARK: - Utilities
4553

@@ -499,7 +507,17 @@ void SymbolGraph::serialize(llvm::json::OStream &OS) {
499507
}); // end metadata:
500508

501509
OS.attributeObject("module", [&](){
502-
OS.attribute("name", M.getNameStr());
510+
if (DeclaringModule) {
511+
// A cross-import overlay can be considered part of its declaring module
512+
OS.attribute("name", (*DeclaringModule)->getNameStr());
513+
std::vector<StringRef> B;
514+
for (auto BModule : BystanderModules) {
515+
B.push_back(BModule.str());
516+
}
517+
OS.attribute("bystanders", B);
518+
} else {
519+
OS.attribute("name", M.getNameStr());
520+
}
503521
AttributeRAII Platform("platform", OS);
504522

505523
auto *MainFile = M.getFiles().front();

lib/SymbolGraphGen/SymbolGraph.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ struct SymbolGraph {
4242
The module whose types were extended in `M`.
4343
*/
4444
Optional<ModuleDecl *> ExtendedModule;
45+
46+
/**
47+
The module declaring `M`, if `M` is a cross-import overlay.
48+
*/
49+
Optional<ModuleDecl *> DeclaringModule;
50+
51+
/**
52+
The modules that must be imported alongside `DeclaringModule` for `M` to be imported, if `M` is a cross-import overlay.
53+
*/
54+
SmallVector<Identifier, 1> BystanderModules;
4555

4656
/**
4757
A context for allocations.

lib/SymbolGraphGen/SymbolGraphGen.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,27 @@ using namespace symbolgraphgen;
2222
namespace {
2323
int serializeSymbolGraph(SymbolGraph &SG,
2424
const SymbolGraphOptions &Options) {
25-
SmallString<256> FileName(SG.M.getNameStr());
26-
if (SG.ExtendedModule.hasValue()) {
25+
SmallString<256> FileName;
26+
if (SG.DeclaringModule.hasValue()) {
27+
// Save a cross-import overlay symbol graph as `MainModule@BystandingModule[@BystandingModule...]@OverlayModule.symbols.json`
28+
//
29+
// The overlay module's name is added as a disambiguator in case an overlay
30+
// declares multiple modules for the same set of imports.
31+
FileName.append(SG.DeclaringModule.getValue()->getNameStr());
32+
for (auto BystanderModule : SG.BystanderModules) {
33+
FileName.push_back('@');
34+
FileName.append(BystanderModule.str());
35+
}
36+
2737
FileName.push_back('@');
28-
FileName.append(SG.ExtendedModule.getValue()->getNameStr());
38+
FileName.append(SG.M.getNameStr());
39+
} else {
40+
FileName.append(SG.M.getNameStr());
41+
42+
if (SG.ExtendedModule.hasValue()) {
43+
FileName.push_back('@');
44+
FileName.append(SG.ExtendedModule.getValue()->getNameStr());
45+
}
2946
}
3047
FileName.append(".symbols.json");
3148

stdlib/public/Concurrency/PartialAsyncTask.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ internal func _resumeUnsafeThrowingContinuationWithError<T>(
7979

8080
#endif
8181

82-
// Wrappers around unsafe continuation builtins
82+
/// The operation functions must resume the continuation *exactly once*.
83+
///
84+
/// The continuation will not begin executing until the operation function returns.
8385
@_alwaysEmitIntoClient
8486
public func withUnsafeContinuation<T>(
8587
_ fn: (UnsafeContinuation<T>) -> Void
@@ -89,6 +91,9 @@ public func withUnsafeContinuation<T>(
8991
}
9092
}
9193

94+
/// The operation functions must resume the continuation *exactly once*.
95+
///
96+
/// The continuation will not begin executing until the operation function returns.
9297
@_alwaysEmitIntoClient
9398
public func withUnsafeThrowingContinuation<T>(
9499
_ fn: (UnsafeThrowingContinuation<T>) -> Void

0 commit comments

Comments
 (0)