Avoid emitting unnecessary basic block for cleanup chains. This is a
general approach that handles all cases while simplifying SILGen
emission and keeping the CFG in a valid state during SILGen.
ASTWalker visits a lazy_initializer_expr once within its associated
var_decl (by way of the parent nominal type). However, SILGen visits the
lazy_initializer_expr while inside of the var_decl's getter. The result
is that there is no coverage mapping information for the contents of the
lazy init within the getter's SILProfiler.
Fixing this will require reworking how profile counters are assigned to
be more in line with what SILGen needs.
As a stop-gap, this patch prevents SILGen from asserting that coverage
mappings are complete with a defensive check which prevents a crash seen
in SR-8429.
rdar://42792053
This initial implementation just delegates from SILGenFunctionBuilder to
SILFunctionBuilder. I was going to start transforming verbose uses of
SILFunctionBuilder into higher level APIs on SILGenFunctionBuilder, but I have
run out of time.
This is a good incremental step forward that will let me hide the constructor of
SILFunctionBuilder after I update the optimizer and thus ensure that
SILFunctionBuilder is only used through appropriate composition APIs.
rdar://42301529
Introduce ExtensionDecl::getExtendedNominal() to provide the nominal
type declaration that the extension declaration extends. Move most
of the existing callers of the callers to getExtendedType() over to
getExtendedNominal(), because they don’t need the full type information.
ExtensionDecl::getExtendedNominal() is itself not very interesting yet,
because it depends on getExtendedType().
Switch a number of callers of the Type-based lookupQualified() over to
the newer (and preferred) declaration-based lookupQualified(). These are
the easy ones; NFC.
This commit does not modify those APIs or their usage. It just:
1. Moves the APIs onto SILFunctionBuilder and makes SILFunctionBuilder a friend
of SILModule.
2. Hides the APIs on SILModule so all users need to use SILFunctionBuilder to
create/destroy functions.
I am doing this in order to allow for adding/removing function notifications to
be enforced via the type system in the SILOptimizer. In the process of finishing
off CallerAnalysis for FSO, I discovered that we were not doing this everywhere
we need to. After considering various other options such as:
1. Verifying after all passes that the notifications were sent correctly and
asserting. Turned out to be expensive.
2. Putting a callback in SILModule. This would add an unnecessary virtual call.
I realized that by using a builder we can:
1. Enforce that users of SILFunctionBuilder can only construct composed function
builders by making the composed function builder's friends of
SILFunctionBuilder (notice I did not use the word subclass, I am talking
about a pure composition).
2. Refactor a huge amount of code in SILOpt/SILGen that involve function
creation onto a SILGenFunctionBuilder/SILOptFunctionBuilder struct. Many of
the SILFunction creation code in question are straight up copies of each
other with small variations. A builder would be a great way to simplify that
code.
3. Reduce the size of SILModule.cpp by 25% from ~30k -> ~23k making the whole
file easier to read.
NOTE: In this commit, I do not hide the constructor of SILFunctionBuilder since
I have not created the derived builder structs yet. Once I have created those in
a subsequent commit, I will hide that constructor.
rdar://42301529
This saves us from having to do overload resolution on the overlay module, which fails if an overlay declaration exactly matches the imported signature of the original ObjC declaration. Fixes rdar://problem/42352695 harder.
The overlay may add overloads for UIApplicationMain for various reasons. When we generate the special `main` implementation for a `@UIApplicationMain` class, we want to call the original function from Objective-C, so pick that one where there are multiple overloads to choose from. Fixes rdar://problem/42352695.
The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.
AccessStrategy has become a bit more explicit about how exactly the
access should be implemented. For example, the accessor-based kinds
now carry the exact accessor intended to be used. Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants. This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.
Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path. This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch. That is... really regrettable. The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
SubstitutionMaps are now just a trivial pointer-sized value, so
pass them by value instead.
I did have to move a couple of functors from Type.h to SubstitutionMap.h
to resolve some issues with forward declarations.
SIL optimizations may rewrite profiling intrinsics in a way that IRGen
can't lower (r://39146527). Don't claim that a coverage mapping has a
guaranteed associated symbol table entry when this happens.
I have not added a test, as this is a defensive workaround until we can
land add a SIL verifier check that prevents profiling intrinsics from
being rewritten.
rdar://40133800
* [Coverage] Only instrument ClosureExprs once
ClosureExprs should only be visited for profiling purposes once, when
the SILFunction definition for the closure is being emitted.
This fixes an issue where the coverage tooling can't figure out how to
attribute the code coverage data of a closure to the right function.
rdar://39200851
* [Coverage] Assert that we don't emit duplicate coverage mappings
While generating SIL for a function with a default argument, we don't
need to emit two identical coverage mappings for the function body. The
same goes for functions which reference foreign functions.
This PR introduces an assertion which should catch similar problems in
the future.
rdar://39297172
* [Coverage] Only instrument nested functions once
Coverage counters for a nested function can be assigned once (in its
parent's scope), and then again (in its own scope). Nested functions
should only be visited for coverage mapping purposes once.
This is related to r://39200851, which is the same bug but for closures.
* [Coverage] Remove special handling of autoclosures
Treating AutoClosureExprs the same as ClosureExprs allows for some nice
code simplifications, and should be more robust.
* [Coverage] Only instrument curried instance methods once
Another fix related to r://39297172, in which we avoid instrumenting the
function associated with a curried thunk more than once.
There are a bunch of methods in this area that do not use ManagedValues, but
that should. This is another step towards unwinding the hairball.
rdar://34222540
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
A default argument generator must not return a @noescape function type.
Returning a @noescape function is nonsense. That means the function escapes.
* Assert that we don't return @noescape function types
* Fix for throwing default arguments
* Add more test cases
* Adapt to mangling changes
Part of:
SR-5441
rdar://36116691
This patch moves the ownership of profiling state from SILGenProfiling
to SILFunction, where it always belonged. Similarly, it moves ownership
of the profile reader from SILGenModule to SILModule.
The refactor sets us up to fix a few outstanding code coverage bugs and
does away with sad hacks like ProfilerRAII. It also allows us to locally
guarantee that a profile counter increment actually corresponds to the
SILFunction at hand.
That local guarantee causes a bugfix to accidentally fall out of this
refactor: we now set up the profiling state for delayed functions
correctly. Previously, we would set up a ProfilerRAII for the delayed
function, but its counter increment would never be emitted :(. This fix
constitutes the only functional change in this patch -- the rest is NFC.
As a follow-up, I plan on removing some dead code in the profiling
logic and fixing a few naming inconsistencies. I've left that for later
to keep this patch simple.
This patch moves the ownership of profiling state from SILGenProfiling
to SILFunction, where it always belonged. Similarly, it moves ownership
of the profile reader from SILGenModule to SILModule.
The refactor sets us up to fix a few outstanding code coverage bugs and
does away with sad hacks like ProfilerRAII. It also allows us to locally
guarantee that a profile counter increment actually corresponds to the
SILFunction at hand.
That local guarantee causes a bugfix to accidentally fall out of this
refactor: we now set up the profiling state for delayed functions
correctly. Previously, we would set up a ProfilerRAII for the delayed
function, but its counter increment would never be emitted :(. This fix
constitutes the only functional change in this patch -- the rest is NFC.
As a follow-up, I plan on removing some dead code in the profiling
logic and fixing a few naming inconsistencies. I've left that for later
to keep this patch simple.
We need to borrow guaranteed values with sil ownership and need to
distinguish between @callee_guaranteed and other context conventions in
a few places.
SR-5441
rdar://33255593
ground work for the syntactic bridging peephole.
- Pass source and dest formal types to the bridging routines in addition
to the dest lowered type. The dest lowered type is still necessary
in order to handle non-standard abstraction patterns for the dest type.
- Change bridging abstraction patterns to store bridged formal types
instead of the formal type.
- Improve how SIL type lowering deals with import-as-member patterns.
- Fix some AST bugs where inadequate information was being stored in
various expressions.
- Introduce the idea of a converting SGFContext and use it to regularize
the existing id-as-Any conversion peephole.
- Improve various places in SILGen to emit directly into contexts.
through a few places.
This patch should be NFC for existing patterns, but it's preparing for
using SILGen's built-in bridging capabilities for more things.
* The SILBuilder could potentially reference itself during its own
initialization if a valid insertion point was left around and a
new basic block was created. Move basic block creation after the
initializer instead.
* CSDiag was comparing canonical types for equality directly, which
leads to mixed-type comparisons if one side of the comparison is nullptr.
Use isEqual instead.
All we need to store is whether the SILDeclRef directly
references the declaration, or if it references a curry
thunk, and we already have an isCurried bit for that.
I put in a simple fixup pass (MarkUninitializedFixup) for staging purposes. I
don't expect it to be in tree long. I just did not feel comfortable fixing up in
1 commit all of the passes up to DI.
rdar://31521023
Refactoring stored property initializers to reuse the codegen for default argument generators caused them to accidentally inherit this additional bit of policy we don't want. Fixes SR-4325.
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.
This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.