Skip to content

Commit cdaa37b

Browse files
authored
Merge pull request #4020 from swiftwasm/main
2 parents bdf5207 + df563ba commit cdaa37b

File tree

66 files changed

+756
-469
lines changed

Some content is hidden

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

66 files changed

+756
-469
lines changed

include/swift/Basic/FileTypes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,6 @@ TYPE("pcm", ClangModuleFile, "pcm", "")
9595
TYPE("pch", PCH, "pch", "")
9696
TYPE("none", Nothing, "", "")
9797

98+
TYPE("abi-baseline-json", SwiftABIDescriptor, "abi.json", "")
99+
98100
#undef TYPE

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,10 @@ def dependency_scan_cache_remarks : Flag<["-"], "Rdependency-scan-cache">,
215215
def enable_copy_propagation : Flag<["-"], "enable-copy-propagation">,
216216
HelpText<"Run SIL copy propagation with lexical lifetimes to shorten object "
217217
"lifetimes while preserving variable lifetimes.">;
218-
def disable_copy_propagation : Flag<["-"], "disable-copy-propagation">,
219-
HelpText<"Don't run SIL copy propagation to preserve object lifetime.">;
218+
def copy_propagation_state_EQ :
219+
Joined<["-"], "enable-copy-propagation=">,
220+
HelpText<"Whether to enable copy propagation">,
221+
MetaVarName<"true|requested-passes-only|false">;
220222

221223
def enable_infer_public_concurrent_value : Flag<["-"], "enable-infer-public-sendable">,
222224
HelpText<"Enable inference of Sendable conformances for public structs and enums">;

include/swift/Runtime/AtomicWaitQueue.h

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,28 @@ class AtomicWaitQueue {
106106
return referenceCount == 1;
107107
}
108108

109+
/// This queue is being re-used with new construction arguments.
110+
/// Update it appropriately.
111+
void updateForNewArguments() {
112+
// We intentionally take no arguments so that only calls to
113+
// createQueue with no arguments will succeed at calling this no-op
114+
// implementation. Queue types with construction arguments
115+
// will need to implement this method to take the appropriate
116+
// arguments. Hopefully this discourages people from forgetting
117+
// that queues can be re-used if created in a loop.
118+
}
119+
109120
/// An RAII helper class for signalling that the current thread is a
110121
/// worker thread which has acquired the lock.
111122
///
123+
/// `AtomicWaitQueue` does not require the global lock to be held
124+
/// while creating or publishing the queue. Clients taking advantage
125+
/// of this should inform the Worker class that a created queue has
126+
/// been published by calling `flagQueueIsPublished`. Clients who
127+
/// wish to publish the queue while holding the global lock, perhaps
128+
/// to get a rule that all stores are done under the lock, may instead
129+
/// use `tryPublishQueue`.
130+
///
112131
/// The expected use pattern is something like:
113132
///
114133
/// ```
@@ -117,26 +136,47 @@ class AtomicWaitQueue {
117136
/// while (true) {
118137
/// if (oldStatus.isDone()) return;
119138
///
120-
/// // Try to publish the wait queue. If this succeeds, we've become
121-
/// // the worker thread.
122-
/// bool published = worker.tryPublishQueue([&] {
123-
/// auto newStatus = oldStatus.withLock(worker.createQueue());
124-
/// return myAtomic.compare_exchange_weak(oldStatus, newStatus,
125-
/// /*success*/ std::memory_order_release,
126-
/// /*failure*/ std::memory_order_acquire);
127-
/// });
128-
/// if (!published) continue;
139+
/// if (oldStatus.hasWaitQueue()) {
140+
/// bool waited = worker.tryReloadAndWait([&] {
141+
/// oldStatus = myAtomic.load(std::memory_order_acquire);
142+
/// return (oldStatus.hasWaitQueue() ? oldStatus.getWaitQueue()
143+
/// : nullptr);
144+
/// });
129145
///
130-
/// // Do the actual work here.
146+
/// // If we waited, `oldStatus` will be out of date; reload it.
147+
/// //
148+
/// // (For the pattern in this example, where the worker thread
149+
/// // always transitions the status to done, this is actually
150+
/// // unnecessary: by virtue of having successfully waited, we've
151+
/// // synchronized with the worker thread and know that the status
152+
/// // is done, so we could just return. But in general, this
153+
/// // reload is necessary.)
154+
/// if (waited)
155+
/// oldStatus = myAtomic.load(std::memory_order_acquire);
131156
///
132-
/// // "Unpublish" the queue from the the atomic.
133-
/// while (true) {
134-
/// auto newStatus = oldStatus.withDone(true);
135-
/// if (myAtomic.compare_exchange_weak(oldStatus, newStatus,
157+
/// // Go back and reconsider the updated status.
158+
/// continue;
159+
/// }
160+
///
161+
/// // Create a queue and try to publish it. If this succeeds,
162+
/// // we've become the worker thread. We don't have to worry
163+
/// // about the queue leaking if we don't use it; that's managed
164+
/// // by the Worker class.
165+
/// {
166+
/// auto queue = worker.createQueue();
167+
/// auto newStatus = oldStatus.withWaitQueue(queue);
168+
/// if (!myAtomic.compare_exchange_weak(oldStatus, newStatus,
136169
/// /*success*/ std::memory_order_release,
137170
/// /*failure*/ std::memory_order_acquire))
138-
/// break;
171+
/// continue;
172+
/// worker.flagQueueIsPublished(queue);
139173
/// }
174+
///
175+
/// // Do the actual work here.
176+
///
177+
/// // Report that the work is done and "unpublish" the queue from
178+
/// // the atomic.
179+
/// myAtomic.store(oldStatus.withDone(true), std::memory_order_release);
140180
/// worker.finishAndUnpublishQueue([]{});
141181
/// return;
142182
/// }
@@ -182,6 +222,19 @@ class AtomicWaitQueue {
182222
return Published;
183223
}
184224

225+
/// Given that this thread is not the worker thread and there seems
226+
/// to be a wait queue in place, try to wait on it.
227+
///
228+
/// Acquire the global lock and call the given function. If it
229+
/// returns a wait queue, wait on that queue and return true;
230+
/// otherwise, return false.
231+
template <class Fn>
232+
bool tryReloadAndWait(Fn &&fn) {
233+
assert(!isWorkerThread());
234+
typename Impl::Waiter waiter(GlobalLock);
235+
return waiter.tryReloadAndWait(std::forward<Fn>(fn));
236+
}
237+
185238
/// Given that this thread is the worker thread, return the queue
186239
/// that's been created and published for it.
187240
Impl *getPublishedQueue() const {
@@ -195,14 +248,18 @@ class AtomicWaitQueue {
195248
///
196249
/// The Worker object takes ownership of the queue until it's
197250
/// published, so you can safely call this even if publishing
198-
/// might fail. Note that the same queue will be returned on
199-
/// successive invocations, so take care if the arguments might
200-
/// change during the loop.
251+
/// might fail.
252+
///
253+
/// Note that the same queue will be returned on successive
254+
/// invocations. Queues that accept arguments for construction
255+
/// should implement `updateForNewArguments`.
201256
template <class... Args>
202257
Impl *createQueue(Args &&...args) {
203258
assert(!Published);
204259
if (!CurrentQueue)
205260
CurrentQueue = asImpl().createNewQueue(std::forward<Args>(args)...);
261+
else
262+
CurrentQueue->updateForNewArguments(std::forward<Args>(args)...);
206263
return CurrentQueue;
207264
}
208265

include/swift/Runtime/Config.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,14 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
330330

331331
/// Copy an address-discriminated signed pointer from the source to the dest.
332332
template <class T>
333-
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
334-
static inline void swift_ptrauth_copy(T *dest, const T *src, unsigned extra) {
333+
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE static inline void
334+
swift_ptrauth_copy(T *dest, const T *src, unsigned extra, bool allowNull) {
335335
#if SWIFT_PTRAUTH
336+
if (allowNull && *src == nullptr) {
337+
*dest = nullptr;
338+
return;
339+
}
340+
336341
*dest = ptrauth_auth_and_resign(*src,
337342
ptrauth_key_function_pointer,
338343
ptrauth_blend_discriminator(src, extra),
@@ -348,8 +353,13 @@ static inline void swift_ptrauth_copy(T *dest, const T *src, unsigned extra) {
348353
template <class T>
349354
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
350355
static inline void swift_ptrauth_copy_data(T *dest, const T *src,
351-
unsigned extra) {
356+
unsigned extra, bool allowNull) {
352357
#if SWIFT_PTRAUTH
358+
if (allowNull && *src == nullptr) {
359+
*dest = nullptr;
360+
return;
361+
}
362+
353363
*dest = ptrauth_auth_and_resign(*src,
354364
ptrauth_key_process_independent_data,
355365
ptrauth_blend_discriminator(src, extra),
@@ -365,11 +375,11 @@ static inline void swift_ptrauth_copy_data(T *dest, const T *src,
365375
template <class T>
366376
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE static inline void
367377
swift_ptrauth_copy_code_or_data(T *dest, const T *src, unsigned extra,
368-
bool isCode) {
378+
bool isCode, bool allowNull) {
369379
if (isCode) {
370-
return swift_ptrauth_copy(dest, src, extra);
380+
return swift_ptrauth_copy(dest, src, extra, allowNull);
371381
} else {
372-
return swift_ptrauth_copy_data(dest, src, extra);
382+
return swift_ptrauth_copy_data(dest, src, extra, allowNull);
373383
}
374384
}
375385

lib/Basic/FileTypes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ bool file_types::isTextual(ID Id) {
8484
case file_types::TY_SwiftOverlayFile:
8585
case file_types::TY_JSONDependencies:
8686
case file_types::TY_JSONFeatures:
87+
case file_types::TY_SwiftABIDescriptor:
8788
return true;
8889
case file_types::TY_Image:
8990
case file_types::TY_Object:
@@ -157,6 +158,7 @@ bool file_types::isAfterLLVM(ID Id) {
157158
case file_types::TY_JSONDependencies:
158159
case file_types::TY_JSONFeatures:
159160
case file_types::TY_IndexUnitOutputPath:
161+
case file_types::TY_SwiftABIDescriptor:
160162
return false;
161163
case file_types::TY_INVALID:
162164
llvm_unreachable("Invalid type ID.");
@@ -208,6 +210,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) {
208210
case file_types::TY_JSONDependencies:
209211
case file_types::TY_JSONFeatures:
210212
case file_types::TY_IndexUnitOutputPath:
213+
case file_types::TY_SwiftABIDescriptor:
211214
return false;
212215
case file_types::TY_INVALID:
213216
llvm_unreachable("Invalid type ID.");

lib/Driver/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
20872087
case file_types::TY_SwiftOverlayFile:
20882088
case file_types::TY_JSONDependencies:
20892089
case file_types::TY_JSONFeatures:
2090+
case file_types::TY_SwiftABIDescriptor:
20902091
// We could in theory handle assembly or LLVM input, but let's not.
20912092
// FIXME: What about LTO?
20922093
Diags.diagnose(SourceLoc(), diag::error_unexpected_input_file,

lib/Driver/ToolChains.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const {
682682
case file_types::TY_SwiftCrossImportDir:
683683
case file_types::TY_SwiftOverlayFile:
684684
case file_types::TY_IndexUnitOutputPath:
685+
case file_types::TY_SwiftABIDescriptor:
685686
llvm_unreachable("Output type can never be primary output.");
686687
case file_types::TY_INVALID:
687688
llvm_unreachable("Invalid type ID");
@@ -941,6 +942,7 @@ ToolChain::constructInvocation(const BackendJobAction &job,
941942
case file_types::TY_SwiftCrossImportDir:
942943
case file_types::TY_SwiftOverlayFile:
943944
case file_types::TY_IndexUnitOutputPath:
945+
case file_types::TY_SwiftABIDescriptor:
944946
llvm_unreachable("Output type can never be primary output.");
945947
case file_types::TY_INVALID:
946948
llvm_unreachable("Invalid type ID");

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
599599
paths.PrivateModuleInterfaceOutputPath},
600600
{file_types::TY_YAMLOptRecord, paths.YAMLOptRecordPath},
601601
{file_types::TY_BitstreamOptRecord, paths.BitstreamOptRecordPath},
602+
{file_types::TY_SwiftABIDescriptor, paths.ABIDescriptorOutputPath},
602603
};
603604
for (const std::pair<file_types::ID, std::string &> &typeAndString :
604605
typesAndStrings) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,42 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
14661466
// -Ounchecked might also set removal of runtime asserts (cond_fail).
14671467
Opts.RemoveRuntimeAsserts |= Args.hasArg(OPT_RemoveRuntimeAsserts);
14681468

1469+
Optional<CopyPropagationOption> specifiedCopyPropagationOption;
1470+
if (Arg *A = Args.getLastArg(OPT_copy_propagation_state_EQ)) {
1471+
specifiedCopyPropagationOption =
1472+
llvm::StringSwitch<Optional<CopyPropagationOption>>(A->getValue())
1473+
.Case("true", CopyPropagationOption::On)
1474+
.Case("false", CopyPropagationOption::Off)
1475+
.Case("requested-passes-only",
1476+
CopyPropagationOption::RequestedPassesOnly)
1477+
.Default(None);
1478+
}
1479+
if (Args.hasArg(OPT_enable_copy_propagation)) {
1480+
if (specifiedCopyPropagationOption) {
1481+
if (*specifiedCopyPropagationOption == CopyPropagationOption::Off) {
1482+
// Error if copy propagation has been set to ::Off via the meta-var form
1483+
// and enabled via the flag.
1484+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_combination,
1485+
"enable-copy-propagation",
1486+
"enable-copy-propagation=false");
1487+
return true;
1488+
} else if (*specifiedCopyPropagationOption ==
1489+
CopyPropagationOption::RequestedPassesOnly) {
1490+
// Error if copy propagation has been set to ::RequestedPassesOnly via
1491+
// the meta-var form and enabled via the flag.
1492+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_combination,
1493+
"enable-copy-propagation",
1494+
"enable-copy-propagation=requested-passes-only");
1495+
return true;
1496+
}
1497+
} else {
1498+
specifiedCopyPropagationOption = CopyPropagationOption::On;
1499+
}
1500+
}
1501+
if (specifiedCopyPropagationOption) {
1502+
Opts.CopyPropagation = *specifiedCopyPropagationOption;
1503+
}
1504+
14691505
Optional<bool> enableLexicalBorrowScopesFlag;
14701506
if (Arg *A = Args.getLastArg(OPT_enable_lexical_borrow_scopes)) {
14711507
enableLexicalBorrowScopesFlag =
@@ -1525,13 +1561,14 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
15251561
return true;
15261562
}
15271563

1528-
// -enable-copy-propagation implies -enable-lexical-lifetimes unless
1529-
// otherwise specified.
1530-
if (Args.hasArg(OPT_enable_copy_propagation))
1564+
// Unless overridden below, enabling copy propagation means enabling lexical
1565+
// lifetimes.
1566+
if (Opts.CopyPropagation == CopyPropagationOption::On)
15311567
Opts.LexicalLifetimes = LexicalLifetimesOption::On;
15321568

1533-
// -disable-copy-propagation implies -enable-lexical-lifetimes=false
1534-
if (Args.hasArg(OPT_disable_copy_propagation))
1569+
// Unless overridden below, disable copy propagation means disabling lexical
1570+
// lifetimes.
1571+
if (Opts.CopyPropagation == CopyPropagationOption::Off)
15351572
Opts.LexicalLifetimes = LexicalLifetimesOption::DiagnosticMarkersOnly;
15361573

15371574
// If move-only is enabled, always enable lexical lifetime as well. Move-only
@@ -1554,24 +1591,6 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
15541591
}
15551592
}
15561593

1557-
if (Args.hasArg(OPT_enable_copy_propagation) &&
1558-
Args.hasArg(OPT_disable_copy_propagation)) {
1559-
// Error if copy propagation is enabled and copy propagation is disabled.
1560-
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_combination,
1561-
"enable-copy-propagation", "disable-copy-propagation");
1562-
return true;
1563-
} else if (Args.hasArg(OPT_enable_copy_propagation) &&
1564-
!Args.hasArg(OPT_disable_copy_propagation)) {
1565-
Opts.CopyPropagation = CopyPropagationOption::On;
1566-
} else if (!Args.hasArg(OPT_enable_copy_propagation) &&
1567-
Args.hasArg(OPT_disable_copy_propagation)) {
1568-
Opts.CopyPropagation = CopyPropagationOption::Off;
1569-
} else /*if (!Args.hasArg(OPT_enable_copy_propagation) &&
1570-
!Args.hasArg(OPT_disable_copy_propagation))*/
1571-
{
1572-
Opts.CopyPropagation = CopyPropagationOption::RequestedPassesOnly;
1573-
}
1574-
15751594
Opts.EnableARCOptimizations &= !Args.hasArg(OPT_disable_arc_opts);
15761595
Opts.EnableOSSAModules |= Args.hasArg(OPT_enable_ossa_modules);
15771596
Opts.EnableOSSAOptimizations &= !Args.hasArg(OPT_disable_ossa_opts);

lib/FrontendTool/FrontendTool.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,10 +1379,14 @@ static bool validateTBDIfNeeded(const CompilerInvocation &Invocation,
13791379
// may have serialized hand-crafted SIL definitions that are invisible to
13801380
// TBDGen as it is an AST-only traversal.
13811381
if (auto *mod = MSF.dyn_cast<ModuleDecl *>()) {
1382-
return llvm::none_of(mod->getFiles(), [](const FileUnit *File) -> bool {
1382+
bool hasSIB = llvm::any_of(mod->getFiles(), [](const FileUnit *File) -> bool {
13831383
auto SASTF = dyn_cast<SerializedASTFile>(File);
13841384
return SASTF && SASTF->isSIB();
13851385
});
1386+
1387+
if (hasSIB) {
1388+
return false;
1389+
}
13861390
}
13871391

13881392
// "Default" mode's behavior varies if using a debug compiler.

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,8 +1649,8 @@ class SubstFunctionTypePatternVisitor
16491649
newGPMapping.insert({gp, newParamTy});
16501650
auto substGPTy = Type(gp).subst(substGPMap)->castTo<GenericTypeParamType>();
16511651
substRequirements.push_back(Requirement(RequirementKind::SameType,
1652-
substGPTy,
1653-
newParamTy));
1652+
newParamTy,
1653+
substGPTy));
16541654
assert(!substReplacementTypes[substGPTy->getIndex()]);
16551655
substReplacementTypes[substGPTy->getIndex()] = substParamTy;
16561656
}

0 commit comments

Comments
 (0)