Skip to content

Commit 193644d

Browse files
Merge branch 'main' into arm64e-disable
2 parents f9a8a71 + ca0f638 commit 193644d

File tree

63 files changed

+1591
-433
lines changed

Some content is hidden

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

63 files changed

+1591
-433
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ types where the metadata itself has unknown layout.)
222222
global ::= global 'Tm' // merged function
223223
global ::= entity // some identifiable thing
224224
global ::= from-type to-type generic-signature? 'TR' // reabstraction thunk
225-
global ::= impl-function-type type 'Tz' // objc-to-swift-async completion handler block implementation
226-
global ::= impl-function-type type 'TZ' // objc-to-swift-async completion handler block implementation (predefined by runtime)
225+
global ::= impl-function-type type 'Tz' index? // objc-to-swift-async completion handler block implementation
226+
global ::= impl-function-type type 'TZ' index? // objc-to-swift-async completion handler block implementation (predefined by runtime)
227227
global ::= from-type to-type generic-signature? 'TR' // reabstraction thunk
228228
global ::= impl-function-type type generic-signature? 'Tz' // objc-to-swift-async completion handler block implementation
229229
global ::= impl-function-type type generic-signature? 'TZ' // objc-to-swift-async completion handler block implementation (predefined by runtime)

docs/SIL.rst

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,6 +2320,54 @@ The current list of interior pointer SIL instructions are:
23202320
(*) We still need to finish adding support for project_box, but all other
23212321
interior pointers are guarded already.
23222322

2323+
Memory Lifetime
2324+
~~~~~~~~~~~~~~~
2325+
2326+
Similar to Ownership SSA, there are also lifetime rules for values in memory.
2327+
With "memory" we refer to memory which is addressed by SIL instruction with
2328+
address-type operands, like ``load``, ``store``, ``switch_enum_addr``, etc.
2329+
2330+
Each memory location which holds a non-trivial value is either uninitialized
2331+
or initialized. A memory location gets initialized by storing values into it
2332+
(except assignment, which expects a location to be already initialized).
2333+
A memory location gets de-initialized by "taking" from it or destroying it, e.g.
2334+
with ``destroy_addr``. It is illegal to re-initialize a memory location or to
2335+
use a location after it was de-initialized.
2336+
2337+
If a memory location holds a trivial value (e.g. an ``Int``), it is not
2338+
required to de-initialize the location.
2339+
2340+
The SIL verifier checks this rule for memory locations which can be uniquely
2341+
identified, for example and ``alloc_stack`` or an indirect parameter. The
2342+
verifier cannot check memory locations which are potentially aliased, e.g.
2343+
a ``ref_element_addr`` (a stored class property).
2344+
2345+
Lifetime of Enums in Memory
2346+
```````````````````````````
2347+
2348+
The situation is a bit more complicated with enums, because an enum can have
2349+
both, cases with non-trivial payloads and cases with no payload or trivial
2350+
payloads.
2351+
2352+
Even if an enum itself is not trivial (because it has at least on case with a
2353+
non-trivial payload), it is not required to de-initialize such an enum memory
2354+
location on paths where it's statically provable that the enum contains a
2355+
trivial or non-payload case.
2356+
2357+
That's the case if the destroy point is jointly dominated by:
2358+
2359+
* a ``store [trivial]`` to the enum memory location.
2360+
2361+
or
2362+
2363+
* an ``inject_enum_addr`` to the enum memory location with a non-trivial or
2364+
non-payload case.
2365+
2366+
or
2367+
2368+
* a successor of a ``switch_enum`` or ``switch_enum_addr`` for a non-trivial
2369+
or non-payload case.
2370+
23232371
Dead End Blocks
23242372
~~~~~~~~~~~~~~~
23252373

include/swift/AST/ASTMangler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ class ASTMangler : public Mangler {
172172
std::string mangleObjCAsyncCompletionHandlerImpl(CanSILFunctionType BlockType,
173173
CanType ResultType,
174174
CanGenericSignature Sig,
175+
Optional<bool> FlagParamIsZeroOnError,
175176
bool predefined);
176177

177178
/// Mangle the derivative function (JVP/VJP), or optionally its vtable entry

include/swift/AST/FineGrainedDependencies.h

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_AST_FINE_GRAINED_DEPENDENCIES_H
1414
#define SWIFT_AST_FINE_GRAINED_DEPENDENCIES_H
1515

16+
#include "swift/AST/EvaluatorDependencies.h"
1617
#include "swift/Basic/Debug.h"
1718
#include "swift/Basic/Fingerprint.h"
1819
#include "swift/Basic/LLVM.h"
@@ -57,11 +58,14 @@
5758
//==============================================================================
5859

5960
namespace swift {
61+
class Decl;
6062
class DependencyTracker;
6163
class DiagnosticEngine;
6264
class FrontendOptions;
6365
class ModuleDecl;
6466
class SourceFile;
67+
class NominalTypeDecl;
68+
class ValueDecl;
6569

6670
/// Use a new namespace to help keep the experimental code from clashing.
6771
namespace fine_grained_dependencies {
@@ -417,6 +421,57 @@ class DependencyKey {
417421
// For import/export
418422
friend ::llvm::yaml::MappingTraits<DependencyKey>;
419423

424+
public:
425+
class Builder {
426+
private:
427+
const NodeKind kind;
428+
const DeclAspect aspect;
429+
const NominalTypeDecl *context;
430+
StringRef name;
431+
432+
private:
433+
// A private copy constructor so our clients are forced to use the
434+
// move-only builder interface.
435+
explicit Builder(NodeKind kind, DeclAspect aspect,
436+
const NominalTypeDecl *context, StringRef name)
437+
: kind(kind), aspect(aspect), context(context), name(name) {}
438+
439+
public:
440+
/// Creates a DependencyKey::Builder from the given \p kind and \p aspect
441+
/// with a \c null context and empty name.
442+
explicit Builder(NodeKind kind, DeclAspect aspect)
443+
: kind(kind), aspect(aspect), context(nullptr), name("") {}
444+
445+
public:
446+
/// Consumes this builder and returns a dependency key created from its
447+
/// data.
448+
DependencyKey build() &&;
449+
450+
public:
451+
/// Extracts the data from the given \p ref into a this builder.
452+
Builder fromReference(const evaluator::DependencyCollector::Reference &ref);
453+
454+
public:
455+
/// Extracts the context data from the given declaration, if any.
456+
Builder withContext(const Decl *D) &&;
457+
/// Extracts the context data from the given decl-member pair, if any.
458+
Builder withContext(std::pair<const NominalTypeDecl *, const ValueDecl *>
459+
holderAndMember) &&;
460+
461+
public:
462+
/// Copies the name data for the given swiftdeps file into this builder.
463+
Builder withName(StringRef swiftDeps) &&;
464+
/// Copies the name of the given declaration into this builder, if any.
465+
Builder withName(const Decl *decl) &&;
466+
/// Extracts the name from the given decl-member pair, if any.
467+
Builder withName(std::pair<const NominalTypeDecl *, const ValueDecl *>
468+
holderAndMember) &&;
469+
470+
private:
471+
static StringRef getTopLevelName(const Decl *decl);
472+
};
473+
474+
private:
420475
NodeKind kind;
421476
DeclAspect aspect;
422477
/// The mangled context type name of the holder for \ref potentialMember, \ref
@@ -485,10 +540,6 @@ class DependencyKey {
485540
template <NodeKind kind, typename Entity>
486541
static DependencyKey createForProvidedEntityInterface(Entity);
487542

488-
/// Given some type of provided entity compute the context field of the key.
489-
template <NodeKind kind, typename Entity>
490-
static std::string computeContextForProvidedEntity(Entity);
491-
492543
DependencyKey correspondingImplementation() const {
493544
return withAspect(DeclAspect::implementation);
494545
}
@@ -497,10 +548,6 @@ class DependencyKey {
497548
return DependencyKey(kind, aspect, context, name);
498549
}
499550

500-
/// Given some type of provided entity compute the name field of the key.
501-
template <NodeKind kind, typename Entity>
502-
static std::string computeNameForProvidedEntity(Entity);
503-
504551
static DependencyKey createKeyForWholeSourceFile(DeclAspect,
505552
StringRef swiftDeps);
506553

include/swift/AST/SILOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ class SILOptions {
8989
/// and go from OSSA to non-ownership SIL.
9090
bool StopOptimizationBeforeLoweringOwnership = false;
9191

92+
/// Do we always serialize SIL in OSSA form?
93+
///
94+
/// If this is disabled we do not serialize in OSSA form when optimizing.
95+
bool EnableOSSAModules = false;
96+
9297
// The kind of function bodies to skip emitting.
9398
FunctionBodySkipping SkipFunctionBodies = FunctionBodySkipping::None;
9499

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,8 @@ LANGUAGE_FEATURE(AsyncAwait, 296, "async/await", true)
3939
LANGUAGE_FEATURE(MarkerProtocol, 0, "@_marker protocol", true)
4040
LANGUAGE_FEATURE(Actors, 0, "actors", langOpts.EnableExperimentalConcurrency)
4141
LANGUAGE_FEATURE(ConcurrentFunctions, 0, "@concurrent functions", true)
42+
LANGUAGE_FEATURE(RethrowsProtocol, 0, "@rethrows protocol", true)
43+
LANGUAGE_FEATURE(GlobalActors, 0, "Global actors", langOpts.EnableExperimentalConcurrency)
44+
LANGUAGE_FEATURE(BuiltinJob, 0, "Builtin.Job type", true)
4245

4346
#undef LANGUAGE_FEATURE

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,10 @@ def disable_ast_verifier : Flag<["-"], "disable-ast-verifier">,
789789
"disabled. NOTE: Can not be used if enable-ast-verifier is used "
790790
"as well">;
791791

792+
def enable_ossa_modules : Flag<["-"], "enable-ossa-modules">,
793+
HelpText<"Always serialize SIL in ossa form. If this flag is not passed in, "
794+
"when optimizing ownership will be lowered before serializing SIL">;
795+
792796
def new_driver_path
793797
: Separate<["-"], "new-driver-path">, MetaVarName<"<path>">,
794798
HelpText<"Path of the new driver to be used">;

include/swift/SIL/AbstractionPattern.h

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,20 @@ class AbstractionPattern {
276276
Async,
277277
};
278278

279+
enum {
280+
AsyncCompletionParameterIndexMask = 0xFFEu,
281+
AsyncCompletionParameterIndexShift = 1,
282+
283+
AsyncCompletionErrorParameterIndexMask = 0x1FF000u,
284+
AsyncCompletionErrorParameterIndexShift = 12,
285+
286+
AsyncCompletionErrorFlagParameterIndexMask = 0x3FE00000u,
287+
AsyncCompletionErrorFlagParameterIndexShift = 21,
288+
289+
AsyncCompletionErrorFlagParameterPolarityMask = 0x40000000u,
290+
AsyncCompletionErrorFlagParameterPolarityShift = 30,
291+
};
292+
279293
public:
280294
enum ForeignKind {
281295
IsNotForeign,
@@ -304,16 +318,24 @@ class AbstractionPattern {
304318

305319
EncodedForeignInfo(Async_t,
306320
unsigned completionParameterIndex,
307-
Optional<unsigned> completionErrorParameterIndex)
308-
: Value(1
309-
+ (unsigned(IsAsync) - 1)
310-
+ (unsigned(completionParameterIndex) << 1)
311-
+ ((completionErrorParameterIndex ? *completionErrorParameterIndex + 1
312-
: 0) << 21)) {
313-
assert(getKind() == IsAsync);
314-
assert(getAsyncCompletionHandlerParamIndex() == completionParameterIndex);
315-
assert(getAsyncCompletionHandlerErrorParamIndex() == completionErrorParameterIndex);
316-
}
321+
Optional<unsigned> completionErrorParameterIndex,
322+
Optional<unsigned> completionErrorFlagParameterIndex,
323+
bool completionErrorFlagIsZeroOnError)
324+
: Value(1
325+
+ (unsigned(IsAsync) - 1)
326+
+ (unsigned(completionParameterIndex) << AsyncCompletionParameterIndexShift)
327+
+ ((completionErrorParameterIndex ? *completionErrorParameterIndex + 1
328+
: 0) << AsyncCompletionErrorParameterIndexShift)
329+
+ ((completionErrorFlagParameterIndex ? *completionErrorFlagParameterIndex + 1
330+
: 0) << AsyncCompletionErrorFlagParameterIndexShift)
331+
+ (unsigned(completionErrorFlagIsZeroOnError) << AsyncCompletionErrorFlagParameterPolarityShift)){
332+
333+
assert(getKind() == IsAsync);
334+
assert(getAsyncCompletionHandlerParamIndex() == completionParameterIndex);
335+
assert(getAsyncCompletionHandlerErrorParamIndex() == completionErrorParameterIndex);
336+
assert(getAsyncCompletionHandlerErrorFlagParamIndex() == completionErrorFlagParameterIndex);
337+
assert(isCompletionErrorFlagZeroOnError() == completionErrorFlagIsZeroOnError);
338+
}
317339

318340
public:
319341
static EncodedForeignInfo
@@ -345,18 +367,37 @@ class AbstractionPattern {
345367

346368
unsigned getAsyncCompletionHandlerParamIndex() const {
347369
assert(getKind() == IsAsync);
348-
return ((Value - 1) >> 1) & 0xFFFFFu;
370+
return ((Value - 1) & AsyncCompletionParameterIndexMask)
371+
>> AsyncCompletionParameterIndexShift;
349372
}
350373

351374
Optional<unsigned> getAsyncCompletionHandlerErrorParamIndex() const {
352375
assert(getKind() == IsAsync);
353376

354-
unsigned encodedValue = (Value - 1) >> 21;
377+
unsigned encodedValue = ((Value - 1) & AsyncCompletionErrorParameterIndexMask)
378+
>> AsyncCompletionErrorParameterIndexShift;
379+
if (encodedValue == 0) {
380+
return llvm::None;
381+
}
382+
return encodedValue - 1;
383+
}
384+
385+
Optional<unsigned> getAsyncCompletionHandlerErrorFlagParamIndex() const {
386+
assert(getKind() == IsAsync);
387+
388+
unsigned encodedValue = ((Value - 1) & AsyncCompletionErrorFlagParameterIndexMask)
389+
>> AsyncCompletionErrorFlagParameterIndexShift;
355390
if (encodedValue == 0) {
356391
return llvm::None;
357392
}
358393
return encodedValue - 1;
359394
}
395+
396+
bool isCompletionErrorFlagZeroOnError() const {
397+
assert(getKind() == IsAsync);
398+
399+
return (Value - 1) & AsyncCompletionErrorFlagParameterPolarityMask;
400+
}
360401

361402
unsigned getForeignParamIndex() const {
362403
switch (getKind()) {

include/swift/SIL/MemoryLifetime.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ class MemoryLocations {
114114
/// Bit 2 is never set because Inner is completly represented by its
115115
/// sub-locations 3 and 4. But bit 0 is set in location 0 (the "self" bit),
116116
/// because it represents the untracked field ``Outer.z``.
117+
///
118+
/// Single-payload enums are represented by a location with a single sub-
119+
/// location (the projected payload address, i.e. an ``init_enum_data_addr``
120+
/// or an ``unchecked_take_enum_data_addr``.
121+
/// Multi-payload enums are not supported right now.
117122
Bits subLocations;
118123

119124
/// The accumulated parent bits, including the "self" bit.
@@ -142,6 +147,12 @@ class MemoryLocations {
142147
/// \endcode
143148
int parentIdx;
144149

150+
/// Returns true if the location with index \p idx is this location or a
151+
/// sub location of this location.
152+
bool isSubLocation(unsigned idx) const {
153+
return idx < subLocations.size() && subLocations.test(idx);
154+
}
155+
145156
private:
146157
friend class MemoryLocations;
147158

@@ -178,11 +189,18 @@ class MemoryLocations {
178189
/// small. They can be handled separately with handleSingleBlockLocations().
179190
llvm::SmallVector<SingleValueInstruction *, 16> singleBlockLocations;
180191

192+
/// A Cache for single-payload enums.
193+
llvm::DenseMap<SILType, EnumElementDecl *> singlePayloadEnums;
194+
181195
/// The bit-set of locations for which numNonTrivialFieldsNotCovered is > 0.
182196
Bits nonTrivialLocations;
183197

198+
/// If true, support init_enum_data_addr and unchecked_take_enum_data_addr
199+
bool handleEnumDataProjections;
200+
184201
public:
185-
MemoryLocations() {}
202+
MemoryLocations(bool handleEnumDataProjections) :
203+
handleEnumDataProjections(handleEnumDataProjections) {}
186204

187205
MemoryLocations(const MemoryLocations &) = delete;
188206
MemoryLocations &operator=(const MemoryLocations &) = delete;
@@ -207,6 +225,9 @@ class MemoryLocations {
207225
const Location *getLocation(unsigned index) const {
208226
return &locations[index];
209227
}
228+
229+
/// Returns the root location of \p index.
230+
const Location *getRootLocation(unsigned index) const;
210231

211232
/// Registers an address projection instruction for a location.
212233
void registerProjection(SingleValueInstruction *projection, unsigned locIdx) {
@@ -262,6 +283,15 @@ class MemoryLocations {
262283
// (locationIdx, fieldNr) -> subLocationIdx
263284
using SubLocationMap = llvm::DenseMap<std::pair<unsigned, unsigned>, unsigned>;
264285

286+
/// Returns the payload case of a single-payload enum.
287+
///
288+
/// Returns null if \p enumTy is not a single-payload enum.
289+
/// We are currently only handling enum data projections for single-payload
290+
/// enums, because it's much simpler to represent them with Locations. We
291+
/// could also support multi-payload enums, but that gets complicated. Most
292+
/// importantly, we can handle Swift.Optional.
293+
EnumElementDecl *getSinglePayloadEnumCase(SILType enumTy);
294+
265295
/// Helper function called by analyzeLocation to check all uses of the
266296
/// location recursively.
267297
///

0 commit comments

Comments
 (0)