Commit Graph

156 Commits

Author SHA1 Message Date
Holly Borla
1d56338ed6 [SILOptimizer] Use the constraint type in ExistentialSpecializer when
finding the protocol decl for an existential type.
2022-01-13 19:30:44 -08:00
Holly Borla
a7fa4695b2 [GenericSignature] Don't allow conformance requirements with explicit
existential types.
2022-01-13 19:30:44 -08:00
zoecarver
036361d1e4 [cxx-interop] Add SIL function representation cxx_method; Support extending C++ types.
There are three major changes here:
    1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
    2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
    3. Clang decls are now marked as foreign witnesses.

These are all steps towards being able to have C++ protocol conformance.
2022-01-06 14:26:47 -08:00
Pavel Yaskevich
4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Robert Widmann
22405cefea Plumb the "Is Type Sequence" Bit Through the Surface AST 2021-11-08 13:48:30 -08:00
Slava Pestov
f38f25a3de AST: Factor out AbstractGenericSignatureRequest into a new buildGenericSignature() function
This is slightly cleaner.
2021-10-30 00:35:59 -04:00
Robert Widmann
1329f3cfbd [NFC] Lift getGenericEnvironment() into GenericSignature 2021-07-22 23:33:02 -07:00
Robert Widmann
d86551de67 Lift Requirement and Parameter Accessors up to GenericSignature
Start treating the null {Can}GenericSignature as a regular signature
with no requirements and no parameters. This not only makes for a much
safer abstraction, but allows us to simplify a lot of the clients of
GenericSignature that would previously have to check for null before
using the abstraction.
2021-07-22 23:27:05 -07:00
Erik Eckstein
6ec788ff09 SIL: remove the SILOpenedArchetypesTracker
Instead, put the archetype->instrution map into SIlModule.

SILOpenedArchetypesTracker tried to maintain and reconstruct the mapping locally, e.g. during a use of SILBuilder.
Having a "global" map in SILModule makes the whole logic _much_ simpler.

I'm wondering why we didn't do this in the first place.

This requires that opened archetypes must be unique in a module - which makes sense. This was the case anyway, except for keypath accessors (which I fixed in the previous commit) and in some sil test files.
2021-04-14 08:36:10 +02:00
Meghana Gupta
ad02d91f50 Fix a minor issue in ExistentialSpecializer for OSSA (#36180)
While cloning arguments for existential specializer, do not create copy
for object types. Currently, for guaranteed parameter types it
unnecessarily creates a copy and cleans it up with a destroy. The
discrepency is seen when cloning an instruction like open_existential_ref
which was previously using guaranteed operand and had guaranteed
forwarding ownership, is now replaced to have the owned copy as its
operand during cloning.
2021-03-24 15:43:09 -07:00
Meghana Gupta
7bef31751f Fix a crash in DeadArgmentTransform (#35486)
When there are no non-type dead args, DeadArgumentTransform should not
specialize the function. While marking dead type args as not dead, make
sure we go over all the args.
If not, a dead type arg will be attempted to be deleted later on in
FunctionSignatureTransform::DeadArgumentFinalizeOptimizedFunction.
2021-01-20 13:20:26 -08:00
Erik Eckstein
b7351780f7 SIL: move all the block-list modifying APIs to SILFunction.
... and remove SILFunction::getBlocks().

It's just a cleanup, NFC.
2021-01-14 17:35:31 +01:00
Andrew Trick
f24658fe9e Fix ExistentialSpecializer to detect repeated specialization.
Add handling for repeated specialization and remove an incorrect
assertion in
ExistentialTransform::createExistentialSpecializedFunctionName():
assert(!F->getModule().hasFunction(MangledName));

The ExistentialSpecializer replaces the original function with a thunk
to a newly specialized function. Repeated attempts to specialize the
same function bail out because the pass avoids reoptimizing thunks.

Ultimately, the intention is that the thunks will all be inlined into
their callers. Dead function elimination will then remove the
thunks. If the original function was itself a specialization, then the
GenericSpecialize may regenerate the original again in non-thunk form.

Consider the pipeline:
- GenericSpecializer
- ExistentialSpecializer
- Inliner
- DeadFunctionElimination
- GenericSpecializer
- ExistentialSpecializer

This is not a problem with the ExistentialSpecializer itself. In fact,
it may respecialize the same function in different ways, for example
specializing more of the arguments each time. Each different
specialization transforms the original function into a thunk, that
thunk is inlined, and the newly specialized code is called directly.

Of course, the ExistentialSpecializer may also decide to respecialize
a function the same way as before. When doing this, it still needs to
produce the thunk, which was dead function eliminated since last
specialization of the same function. However, it can simply reuse the
previous specialization by performing a name lookup first.

The design problem is that the SILModule makes assumptions about
duplicate symbols when managing symbol memory but does not provide a
robust way to protect against such duplicate symbols. That will be
improved in a separate commit.

Minimal fix for: rdar://72135512 The ExistentialSpecializer crashes
2020-12-14 16:15:23 -08:00
Michael Gottesman
c026e95cce [ownership] Extract out SILOwnershipKind from ValueOwnershipKind into its own type and rename Invalid -> Any.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
2020-11-10 14:29:11 -08:00
Nate Chandler
94b5f76654 Revert "[SIL] Add SILFunctionType flag for async."
This reverts commit 9b8828848d.
2020-08-25 13:37:26 -07:00
Nate Chandler
9b8828848d [SIL] Add SILFunctionType flag for async. 2020-08-19 11:29:58 -07:00
Michael Gottesman
6017ef5d2e [ownership] Begin updating existential specializer.
I can not update all of the tests until I fix SILCombine and we move the
ownership lowering to right before the existential specializer (the sil tests
depend on the former and the swift tests depend on both). But this at least
begins updating the tests and ensures that the updates do not break the pass
when we run it on non-ossa code.
2020-08-04 14:36:24 -07:00
Luciano Almeida
59add19684 Merge pull request #32056 from LucianoPAlmeida/minor-typos
[NFC][test] Minor typo corrections on test messages
2020-06-17 07:14:27 -03:00
Luciano Almeida
6d3f53a417 [NFC][test] Minor corrections on test messages 2020-06-05 06:36:09 -03:00
Meghana Gupta
4804616fc1 Fix an edge case in ExistentialSpecializer
ExistentialSpecializer could be building the function type from a
witness_method. We cannot attach a witnessProtocolConformance to the
newly specialized thin function.
2020-06-02 10:13:28 -07:00
Erik Eckstein
e3ac98cdbf FunctionSignatureTransforms: add a semantics attribute to prevent the owned-to-guarantee transformation.
If a function is annotated with @_semantics("optimize.sil.specialize.owned2guarantee.never") its arguments will not be converted from owned to guaranteed.
2020-05-26 18:01:17 +02:00
Michael Gottesman
6049ce629c [fso] Do not try to specialize pseudo-generic functions today.
This is just fixing an assert violation. I also needed to add support for
target-sil-opt(mock-sdk: ...) so I added support to lit for that here.

<rdar://problem/62262811>
2020-05-21 15:48:55 -07:00
Saleem Abdulrasool
cebe79d482 SIL: use object libraries instead of globbing
This simplifies the handling of the subdirectories in the SIL and
SILOptimizer paths.  Create individual libraries as object libraries
which allows the analysis of the source changes to be limited in scope.
Because these are object libraries, this has 0 overhead compared to the
previous implementation.  However, string operations over the filenames
are avoided.  The cost for this is that any new sub-library needs to be
added into the list rather than added with the special local function.
2020-05-18 18:56:34 +00:00
Arnold Schwaighofer
147144baa6 SIL: Thread type expansion context through to function convention apis
This became necessary after recent function type changes that keep
substituted generic function types abstract even after substitution to
correctly handle automatic opaque result type substitution.

Instead of performing the opaque result type substitution as part of
substituting the generic args the underlying type will now be reified as
part of looking at the parameter/return types which happens as part of
the function convention apis.

rdar://62560867
2020-05-04 13:53:30 -07:00
Erik Eckstein
0c3e6e2291 FunctionSignatureOpts: fix a crash due to a missing argument declaration
The existential -> generic transformation in FSO didn't preserve the argument declaration.
This caused an assert to hit in a later FSO transformation.

rdar://problem/61206439
https://bugs.swift.org/browse/SR-12487
2020-04-15 20:52:30 +02:00
pi1024e
c8fa56600f Make booleans const 2020-03-21 12:56:56 -04:00
Andrew Trick
80d502c8ef Move the FSO bailout to the beginning of the pass.
This way we catch the DeadFunctionArgs optimization too, which is a
separate sub-pass.
2020-03-17 23:35:02 -07:00
John McCall
ceff414820 Distinguish invocation and pattern substitutions on SILFunctionType.
In order to allow this, I've had to rework the syntax of substituted function types; what was previously spelled `<T> in () -> T for <X>` is now spelled `@substituted <T> () -> T for <X>`.  I think this is a nice improvement for readability, but it did require me to churn a lot of test cases.

Distinguishing the substitutions has two chief advantages over the existing representation.  First, the semantics seem quite a bit clearer at use points; the `implicit` bit was very subtle and not always obvious how to use.  More importantly, it allows the expression of generic function types that must satisfy a particular generic abstraction pattern, which was otherwise impossible to express.

As an example of the latter, consider the following protocol conformance:

```
protocol P { func foo() }
struct A<T> : P { func foo() {} }
```

The lowered signature of `P.foo` is `<Self: P> (@in_guaranteed Self) -> ()`.  Without this change, the lowered signature of `A.foo`'s witness would be `<T> (@in_guaranteed A<T>) -> ()`, which does not preserve information about the conformance substitution in any useful way.  With this change, the lowered signature of this witness could be `<T> @substituted <Self: P> (@in_guaranteed Self) -> () for <A<T>>`, which nicely preserves the exact substitutions which relate the witness to the requirement.

When we adopt this, it will both obviate the need for the special witness-table conformance field in SILFunctionType and make it far simpler for the SILOptimizer to devirtualize witness methods.  This patch does not actually take that step, however; it merely makes it possible to do so.

As another piece of unfinished business, while `SILFunctionType::substGenericArgs()` conceptually ought to simply set the given substitutions as the invocation substitutions, that would disturb a number of places that expect that method to produce an unsubstituted type.  This patch only set invocation arguments when the generic type is a substituted type, which we currently never produce in type-lowering.

My plan is to start by producing substituted function types for accessors.  Accessors are an important case because the coroutine continuation function is essentially an implicit component of the function type which the current substitution rules simply erase the intended abstraction of.  They're also used in narrower ways that should exercise less of the optimizer.
2020-03-07 16:25:59 -05:00
Andrew Trick
b38ca0c37b Disable ExistentialSpecializer on generic functions.
This is not implemented--we don't substitute the original archetypes
properly or even create a well-formed generic signature.

It doesn't make sense to me for the ExistentialSpecializer to work on
a generic before it has been fully specialized anyway. The premise of
this pass is that the generic specializer will be able to fully
specialize after generating a new "temporary" generic parameter.

Fixes rdar://56923071; [SR-11714]: Compiler crash when generic class is passed as
a parameter to a function accepting a generic class
2020-02-21 00:10:57 -08:00
Michael Gottesman
68960005f6 [gardening] Remove unused variable. 2019-12-18 13:54:11 -08:00
Michael Gottesman
df47eb2c1f [sil] Use SILNodes.def to define ARGKIND##ArrayRef instead of hard coding names.
I also changed all of the places that vended these to use SILNodes.def as well
so that when new argument kinds are added, things just work.
2019-12-02 14:39:02 -08:00
Andrew Trick
8052a61a56 Merge pull request #28430 from atrick/fix-existential-conformance
Fix ExistentialSpecializer: inherited conformance
2019-11-22 09:13:21 -08:00
Andrew Trick
7d0a772542 Fix ExistentialSpecializer: inherited conformance
The ExistentialSpecializer incorrectly assumed that an existential's conformances match an opened archetype. They don't. Opened archetypes strip inherited conformances per the ABI for generic argument passing. Existential values retain those inherited conformances (for some inexplicable reason).

- Rename ASTContext::getExistentialSignature() to
  getOpenedArchetypeSiganture() because it was doing exactly the wrong
  thing for existentials.

- Fix ConcreteExistentialInfo to produce the correct SubstitutionMap.

- Fix ExistentialSpecializer to generate the correct conformances for
  init_existential by adding a collectExistentialConformances() helper.

Fixes <rdar://problem/57025861> "Assertion failed: (conformances.size() == numConformanceRequirements)" in ExistentialSpecializer on inlined code
2019-11-22 01:56:20 -08:00
Michael Gottesman
5224218a1d [existential-specializer] Do not process callees with ownership as well as callers without ownership.
I already turned this off for callers. I just didn't do it for callees. Just an
oversight.

rdar://57291312
2019-11-20 14:21:06 -08:00
Arnold Schwaighofer
8aaa7b4dc1 SILOptimizer: Pipe through TypeExpansionContext 2019-11-11 14:21:52 -08:00
Brent Royal-Gordon
17169fc1fe Merge pull request #27950 from brentdax/dumpster-fire
[NFC] Standardize dump() methods in frontend
2019-10-31 20:36:26 -07:00
Brent Royal-Gordon
99faa033fc [NFC] Standardize dump() methods in frontend
By convention, most structs and classes in the Swift compiler include a `dump()` method which prints debugging information. This method is meant to be called only from the debugger, but this means they’re often unused and may be eliminated from optimized binaries. On the other hand, some parts of the compiler call `dump()` methods directly despite them being intended as a pure debugging aid. clang supports attributes which can be used to avoid these problems, but they’re used very inconsistently across the compiler.

This commit adds `SWIFT_DEBUG_DUMP` and `SWIFT_DEBUG_DUMPER(<name>(<params>))` macros to declare `dump()` methods with the appropriate set of attributes and adopts this macro throughout the frontend. It does not pervasively adopt this macro in SILGen, SILOptimizer, or IRGen; these components use `dump()` methods in a different way where they’re frequently called from debugging code. Nor does it adopt it in runtime components like swiftRuntime and swiftReflection, because I’m a bit worried about size.

Despite the large number of files and lines affected, this change is NFC.
2019-10-31 18:37:42 -07:00
Robert Widmann
37e82a6133 [NFC] getWitnessMethodConformanceOrNone -> getWitnessMethodConformanceOrInvalid 2019-10-29 16:56:20 -07:00
Robert Widmann
3e1a61f425 [NFC] Fold The Tri-State In Optional<ProtocolConformanceRef>
ProtocolConformanceRef already has an invalid state.  Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it.  Mechanically
translate all of the callers and callsites to use this new
representation.
2019-10-29 16:55:56 -07:00
Saleem Abdulrasool
3ced35855e Merge pull request #27897 from apple/remove-todo-wip
remove todo warnings, oops
2019-10-26 13:49:06 -07:00
Joe Groff
dc0f770364 remove todo warnings, oops 2019-10-26 10:49:47 -07:00
Joe Groff
1a1d9e63f7 Merge pull request #27887 from jckarter/subst-sil-function-type-interface
SIL: Add fields to SILFunctionType for substituted function types.
2019-10-26 10:44:48 -07:00
Joe Groff
03c7919b4a SIL: Add fields to SILFunctionType for substituted function types.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
2019-10-25 13:38:51 -07:00
Michael Gottesman
26a734e58e [sil] Rename ValueOwnershipKind::{Any,None} 2019-10-25 10:28:25 -07:00
Jordan Rose
171ff440fc Remove swift::reversed in favor of llvm::reverse (#27610)
The former predates the latter, but we don't need it anymore! The
latter has more features anyway.

No functionality change.
2019-10-10 17:16:09 -07:00
Andrew Trick
bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Robert Widmann
5a8d0744c3 [NFC] Adopt TypeBase-isms for GenericSignature
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase.  In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
2019-09-30 14:04:36 -07:00
nate-chandler
b9b4196470 Merge pull request #27239 from nate-chandler/39957093-argument-explosion-heuristic
[SILOptimizer] Alter FSO arg explosion heuristic.
2019-09-26 09:19:15 -07:00
Nate Chandler
9567bd4341 [SILOptimizer] Alter FSO arg explosion heuristic.
The new rule is that an argument will be exploded if one of the
following sets of conditions hold:

(1) (a) Specializing the function will result in a thunk.  That is, the
        thunk that is generated cannot be inlined everywhere.
    (b) The argument has dead non-trivial leaves.
    (c) The argument has fewer than three live leaves.

(2) (a) Specializing the function will not result in a thunk.  That is,
        the thunk that is generated will be inlined everywhere and
        eliminated as dead code.
    (b) The argument has dead potentially trivial leaves.
    (c) The argument has fewer than six live leaves.

This change is based heavily on @gottesm's
https://github.com/apple/swift/pull/16756 .

rdar://problem/39957093
2019-09-24 15:59:28 -07:00
Adrian Prantl
5b92814a0e Debug Info: Add missing debug info propagation to SILCloner.
While tightening the requirements of the debug info generator in
IRGenSIL I noticed that SILCloner didn't correctly transfer variable
debug info on alloc_box and alloc_stack instructions. In order to make
these mistakes easier to find I added an assertion to SILBuilder and
fixed all issues uncovered by that assertion, too.

The result is a moderate increase in debug info coverage in optimized code.

On stdlib/public/core/OSX/x86_64/Swift.o "variables with location"
increases from 60134 to 60299.
2019-09-24 14:10:25 -07:00