Move these to SILDeclRef, maybe not the best place but a good home for now.
Factor out a new requiresForeignToNativeThunk() function, which cleans up
some code duplication introduced by the following patch:
478e1c7513
This is a small step towards consolidating duplicated logic for figuring out
method dispatch semantics and emitting curry thunks.
Now that we open-code enum construction, enum constructor entry points are
only needed when they are partially-applied, which is a rare case. So we
treat them like curry thunks and only emit them as needed.
The main consequence of this is that enum case constructors are no longer
part of our ABI.
To avoid a regression in the code path for diagnosing infinite value types,
force type lowering to walk a type when emitting its declaration, even if
there are no other references to the type in the program (which is now the
case for public enums which are otherwise not used).
Also XFAIL a DebugInfo test since it is not clear to me what the test does
or how to fix it. The obvious change of adding references to the enum
case constructor function to force it to be emitted did not work.
There's no longer a direct use of the variable's address when we invoke the closure, but we have a handy mark_function_escape instruction to mark the use without requiring merging analysis of the box and its contents. This also gives us a slightly more accurate error message when a variable is prematurely captured, noting the variable was captured by a closure instead of just generically used.
Now that boxes are typed and projectable, the address no longer has to be passed separately.
For now, this breaks capture promotion, DI, and debug info, which analyze uses of the address param. Will be addressed in upcoming commits:
Swift :: DebugInfo/byref-capture.swift
Swift :: DebugInfo/closure-args.swift
Swift :: DebugInfo/closure-args2.swift
Swift :: DebugInfo/inout.swift
Swift :: DebugInfo/linetable.swift
Swift :: SILPasses/capture_promotion.swift
Swift :: SILPasses/definite_init_diagnostics.swift
The drivers for this change are providing a simpler API to SIL pass
authors, having a more efficient of the in-memory representation,
and ruling out an entire class of common bugs that usually result
in hard-to-debug backend crashes.
Summary
-------
SILInstruction
Old New
+---------------+ +------------------+ +-----------------+
|SILInstruction | |SILInstruction | |SILDebugLocation |
+---------------+ +------------------+ +-----------------+
| ... | | ... | | ... |
|SILLocation | |SILDebugLocation *| -> |SILLocation |
|SILDebugScope *| +------------------+ |SILDebugScope * |
+---------------+ +-----------------+
We’re introducing a new class SILDebugLocation which represents the
combination of a SILLocation and a SILDebugScope.
Instead of storing an inline SILLocation and a SILDebugScope pointer,
SILInstruction now only has one SILDebugLocation pointer. The APIs of
SILBuilder and SILDebugLocation guarantees that every SILInstruction
has a nonempty SILDebugScope.
Developer-visible changes include:
SILBuilder
----------
In the old design SILBuilder populated the InsertedInstrs list to
allow setting the debug scopes of all built instructions in bulk
at the very end (as the responsibility of the user). In the new design,
SILBuilder now carries a "current debug scope" state and immediately
sets the debug scope when an instruction is inserted.
This fixes a use-after-free issue with with SIL passes that delete
instructions before destroying the SILBuilder that created them.
Because of this, SILBuilderWithScopes no longer needs to be a template,
which simplifies its call sites.
SILInstruction
--------------
It is neither possible or necessary to manually call setDebugScope()
on a SILInstruction any more. The function still exists as a private
method, but is only used when splicing instructions from one function
to another.
Efficiency
----------
In addition to dropping 20 bytes from each SILInstruction,
SILDebugLocations are now allocated in the SILModule's bump pointer
allocator and are uniqued by SILBuilder. Unfortunately repeat compiles
of the standard library already vary by about 5% so I couldn’t yet
produce reliable numbers for how much this saves overall.
rdar://problem/22017421
- If a @convention(block) function parameter was also marked @noescape, then during type-checking, we would accidentally propagate the convention directly onto a literal closure expr, instead of going through a function_conversion, which SILGen didn't handle. Fixes rdar://problem/23261912.
- If an Objective-C API declared a block parameter with a _Nonnull return of a bridged type, such as NSString *_Nonnull, then native-to-bridged thunking would fail to recognize this case, since we still bridge to an Optional type in the lowered ObjC interface. Fixes rdar://problem/23285766.
This improves support for promoting to and generating
unchecked_ref_cast so we no longer need unchecked_ref_bit_cast, which
will just go away in the next commit.
Swift SVN r32597
The CaptureInfo computed by Sema now records if the body of the
function uses any generic parameters from the outer context.
SIL type lowering only adds a generic signature if this is the
case, instead of unconditionally.
This might yield a marginal performance improvement in some cases,
but more interestingly will allow @convention(c) conversions from
generic context.
Swift SVN r32161
- Generalize::transformFunction() had a couple of little optimizations
for emitting convert_function or thin_to_thick_function instead of
a thunk, if possible -- move this into code shared by all
transforms
- Nuke Generalize since it doesn't do anything special anymore
Swift SVN r31423
If the compiler can prove that a throwing function actually does not throw it can
replace a try_apply with an "apply [nothrow]". Such an apply_inst calls a function
with an error result but does not have the overhead of checking for the error case.
Currently this flag is not set, yet.
Swift SVN r31151
The other part of rdar://problem/21444126. This is a little trickier since SIL doesn't track uses of witness tables in a principled way. Track uses in SILGen by putting a "SILGenBuilder" wrapper in front of SILBuilder, which marks conformances from apply, existential erasure, and metatype lookup instructions as used, so we can avoid emitting shared Clang importer witnesses when they aren't needed.
Swift SVN r29544
A few spot fixes here to code that until now assumed it never had to deal with initializers. First, we have to get the "self" metatype parameter correct in the curry thunk; "self" in the initializer body is semantically the instance being constructed, so we can't follow the body param patterns. Instead, we can mostly reuse the logic for curried enum element constructors. getNextUncurryLevelRef also needs a small tweak to correctly dynamically dispatch any kind of decl, not just FuncDecls.
Swift SVN r29345
This isn't as straightforward as it should be, since EnumElementDecls aren't AbstractFunctionDecls, but luckily there's only one trivial curry level with a thin metatype parameter.
Swift SVN r28991
Modules occupy a weird space in the AST now: they can be treated like
types (Swift.Int), which is captured by ModuleType. They can be
treated like values for disambiguation (Swift.print), which is
captured by ModuleExpr. And we jump through hoops in various places to
store "either a module or a decl".
Start cleaning this up by transforming Module into ModuleDecl, a
TypeDecl that's implicitly created to describe a module. Subsequent
changes will start folding away the special cases (ModuleExpr ->
DeclRefExpr, name lookup results stop having a separate Module case,
etc.).
Note that the Module -> ModuleDecl typedef is there to limit the
changes needed. Much of this patch is actually dealing with the fact
that Module used to have Ctx and Name public members that now need to
be accessed via getASTContext() and getName(), respectively.
Swift SVN r28284
Instead of immediately creating closures for local function declarations and treating them directly as capturable values, break function captures down and transitively capture the storage necessary to invoke the captured functions. Change the way SILGen emits calls to closures and local functions so that it treats the capture list as the first curry level of an invocation, so that full applications of closure literals or nested functions don't require a partial apply at all. This allows references among local functions with captures to work within the existing confines of partial_apply, and also has the nice benefit that circular references would work without creating reference cycles (though Sema unfortunately rejects them; something we arguably ought to fix.)
This fixes rdar://problem/11266246 and improves codegen of local functions. Full applications of functions, or immediate applications of closure literals like { }(), now never need to allocate a closure.
Swift SVN r28112
Keep track of a second set of "direct method reference" curry thunks that don't end in a dynamic dispatch in order to properly implement a partial application such as 'let foo = super.foo'. Fixes rdar://problem/20598526.
Swift SVN r27538
These aren't really orthogonal concerns--you'll never have a @thick @cc(objc_method), or an @objc_block @cc(witness_method)--and we have gross decision trees all over the codebase that try to hopscotch between the subset of combinations that make sense. Stop the madness by eliminating AbstractCC and folding its states into SILFunctionTypeRepresentation. This cleans up a ton of code across the compiler.
I couldn't quite eliminate AbstractCC's information from AST function types, since SIL type lowering transiently created AnyFunctionTypes with AbstractCCs set, even though these never occur at the source level. To accommodate type lowering, allow AnyFunctionType::ExtInfo to carry a SILFunctionTypeRepresentation, and arrange for the overlapping representations to share raw values.
In order to avoid disturbing test output, AST and SILFunctionTypes are still printed and parsed using the existing @thin/@thick/@objc_block and @cc() attributes, which is kind of gross, but lets me stage in the real source-breaking change separately.
Swift SVN r27095
The set of attributes that make sense at the AST level is increasingly divergent from those at the SIL level, so it doesn't really make sense for these to be the same. It'll also help prevent us from accidental unwanted propagation of attributes from the AST to SIL, which has caused bugs in the past. For staging purposes, start off with SILFunctionType's versions exactly the same as the FunctionType versions, which necessitates some ugly glue code but minimizes the potential disruption.
Swift SVN r27022