For backtracking scopes that are never cancelled, we can completely disable the SyntaxParsingContext, avoiding the creation of deferred nodes which will never get recorded.
We have finally reached our goal of optimising deferred node creation
for SyntaxTreeCreator. Instead of creating dedicated deferred nodes and
copying the data into a RawSyntax node when recording, we always create
RawSyntax nodes. Recording a deferred node is thus a no-op, since we
have already created a RawSyntax node. Should a deferred node not be
recorded, it stays alive in the SyntaxArena without any reference to it.
While this means, we are leaking some memory for such nodes, most nodes
do get recorded, so the overhead should be fine compared to the
performance benefit.
The getData and getRecordedOrDeferredNode methods broke the move-only semantics of ParsedRawSyntaxNode because it allowed retrieving the data without resetting it.
Change most uses to use takeData or takeRecordedOrDeferredNode instead of the get methods.
To retrieve the children of a ParsedRawSyntaxNode, we still need a way to access the OpaqueSyntaxNode for inspection by the SyntaxParseActions without resetting it. For this, we still maintain a method with the semantics of getData, but it’s now called getUnsafeOpaqueData to make sure it’s not accidentally used.
By now ParsedRawSyntaxNode does not have any knowledge about deferred
node data anymore, which frees up SyntaxParseActions (and, in
particular its sublass SyntaxTreeCreator) to perform optimisations to
more efficiently create and record deferred nodes.
Essentially all ParsedRawSyntaxNode types have a range associated with
them, so let's just store it in a dedicated field with a common getter.
Additionally, this cleans up the recorded storage to just contain an
OpaqueSyntaxNode. When deferred nodes are being handled by
SyntaxParseActions, we can use this OpaqueNode storage to store either
recorded or deferred node data, which is left to be interpreted by the
SyntaxParseAction.
This is a multi-commit effort to push the responsibility of deferred
node handling to the SyntaxParseActions which have more detailed
knowledge of their requirements on deferred nodes and might perform
additional optimisations. For example, the SyntaxTreeCreator can always
create RawSyntax nodes (even for deferred nodes) and decide to simply
not use them, should the deferred nodes not get recorded.
Small peformance improvement: Token is larger than a pointer and not
modified in the performance-criticial TokenReceivers, so we can pass
it by reference.
Instead, only reference count the SyntaxArena that the RawSyntax nodes
live in. The user of RawSyntax nodes must guarantee that the SyntaxArena
stays alive as long as the RawSyntax nodes are being accessed.
During parse time, the SyntaxTreeCreator holds on to the SyntaxArena
in which it creates RawSyntax nodes. When inspecting a syntax tree,
the root SyntaxData node keeps the SyntaxArena alive. The change should
be mostly invisible to the users of the public libSyntax API.
This change significantly decreases the overall reference-counting
overhead. Since we were not able to free individual RawSyntax nodes
anyway, performing the reference-counting on the level of the
SyntaxArena feels natural.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.
ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.
_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.
Resolves rdar://69980056.
This is again a transitional state before SyntaxParsingContext hands
the responsibility over to SyntaxTreeCreator and from there to
SyntaxParseActions.
This is an intermediate state in which the lexer delegates the
responsibility for trivia lexing to the parser. Later, the parser will
delegate this responsibility to SyntaxParsingContext which will hand it
over to SyntaxParseAction, which will only lex the pieces if it is
really necessary to do so.
The lexer is only responsible for skipping over trivia and noting their
length. A separate TriviaLexer can be invoked to split the raw trivia
string into its pieces.
Since most of the time the trivia pieces aren't needed, this will allow
us to later only parse trivia into pieces when they are explicitly
needed.
It was originally designed for faster trasmission of syntax trees from
C++ to SwiftSyntax, but superceded by the CLibParseActions. There's no
deserializer for it anymore, so let's just remove it.
Our name lookup rules for the resolution of custom attributes don't
allow for them to find MainActor within the _Concurrency library.
Therefore, hardcode @MainActor to map to _Concurrency.MainActor.
While here, make sure we drop concurrency-specific attributes that
show up in Clang attributes when we aren't in concurrency mode.