Commit Graph

637 Commits

Author SHA1 Message Date
Slava Pestov
9ec80df97e SIL: Remove curried SILDeclRefs 2020-03-19 02:20:21 -04:00
Erik Eckstein
ae93e60072 SIL: add a lazy_property_getter flag to SILFunction
It is set on getter-functions for lazy properties.
2020-03-13 09:49:55 +01: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
Joe Groff
dcd432a1bc Turn on substituted SILFunctionTypes by default 2020-02-24 12:14:21 -08:00
Michael Gottesman
1fb56db502 [ownership] Implement movable guaranteed scopes in ossa.
This patch implements movable guaranteed scopes in ossa. This pattern is
currently not generated anywhere in the compiler, but my hope is to begin
emitting these in SemanticARCOpts. The idea is that these model true phi nodes
and thus can be used to fuse multiple guaranteed scopes into one using br
instructions. This is treated similarly to how owned instructions are forwarded
through /all/ terminators. This will enable us to use the SILSSAUpdater with
guaranteed arguments as well as enable the expression of sets of borrow scopes
that minimally jointly-dominate a guaranteed argument. This will enable us to
express +0 merge points like the following:

```
bb1:
  %0a = begin_borrow %0 : $Klass
  br bb3(%0a : $Klass)

bb2:
  %1a = load_borrow %1 : $*Klass
  br bb3(%1a : $Klass)

bb3(%2 : @guaranteed $Klass)
  ...
  end_borrow %2 : $Klass
```

I describe below what the semantics of guaranteed block arguments were
previously, what they are now, and a little bit of interesting things from a
semantic perspective around implicit sub-scope users.

Before this patch in ossa, guaranteed block arguments had two different sets of
semantics:

1. Given a checked_cast_br or a switch_enum, the guaranteed block argument was
   treated like a forwarding instruction. As such, the guaranteed argument's did
   not require an end_borrow and its uses were validated as part of the use list
   of the switch_enum/checked_cast_br operand's borrow introducer. It also was
   not classified as a BorrowScopeValueIntroducer since it was not introducing a
   new scope.

2. Given any other predecessor terminator, we treated the guaranteed argument as
   a complete sub-scope of its incoming values. Thus we required the guaranteed
   argument to have its lifetime eneded by an end_borrow and that all incoming
   values of the guaranteed argument to come from a borrow introducer whose set
   of jointly post-dominating end_borrows also jointly post-dominates the set of
   end_borrows associated with the guaranteed argument itself. Consider the
   following example:

```
bb0:
  %1 = begin_borrow %foo : $Foo   // (1)
  %2 = begin_borrow %foo2 : $Foo2 // (2)
  cond_br ..., bb1, bb2

bb1:
  br bb3(%1 : $Foo)

bb2:
  br bb3(%2 : $Foo)

bb3(%3 : @guaranteed $Foo)
  ...
  end_borrow %3 : $Foo            // (3)
  end_borrow %2 : $Foo            // (4)
  end_borrow %1 : $Foo            // (5)
  ...
```

Notice how due to SSA, (1) and (2) must dominate (4) and (5) and thus must
dominate bb3, preventing the borrows from existing within bb1, bb2.

This dominance property is actively harmful to expressivity in SIL since it
means that guaranteed arguments can not be used to express (without contortion)
sil code patterns where an argument is jointly-dominated by a minimal set of
guaranteed incoming values. For instance, consider the following SIL example:

```
bb0:
  cond_br ..., bb1, bb2

bb1:
  %0 = load [copy] %globalAddr : $Foo
  br bb3(%0 : $Foo)

bb2:
  %1 = copy_value %guaranteedFunctionArg : $Foo
  br bb3(%1 : $Foo):

bb3(%2 : @owned $Foo):
  apply %useFoo(%2)
  destroy_value %2 : $Foo
```

As a quick proof: Assume the previous rules for guaranteed arguments. Then to
promote the load [copy] -> load_borrow and the copy_value to a begin_borrow, we
would need to place an end_borrow in bb3. But neither bb1 or bb2 dominates bb3,
so we would violate SSA dominance rules.

To enable SIL to express this pattern, we introduce a third rule for terminator
in ossa that applies only to branch insts. All other branches that obeyed the
previous rules (cond_br), still follow the old rule. This is not on purpose, I
am just being incremental and changing things as I need to. Specifically,
guaranteed arguments whose incoming values are defined by branch instructions
now act as a move on guaranteed values. The intuition here is that these
arguments are acting as true phis in an SSA sense and thus are just new names
for the incoming values. This implies since it is just a new name (not a
semantic change) that the guaranteed incoming value's guaranteed scopes should
be fused into one scope. The natural way to model this is by treating branch
insts as consuming guaranteed values. This then lets us express the example
above without using copies as follows:

```
bb0:
  cond_br ..., bb1, bb2

bb1:
  %0 = load_borrow %globalAddr : $Foo
  br bb3(%0 : $Foo) // consumes %0 and acts as %0's end_borrow.

bb2:
  // We need to introduce a new begin_borrow here since function
  // arguments are required to never be consumed.
  %1 = begin_borrow %guaranteedFunctionArg : $Foo
  br bb3(%1 : $Foo) // consumes %1 and acts as %1's end_borrow

// %2 continues the guaranteed scope of %0, %1. This time fused with one name.
bb3(%2 : @guaranteed $Foo):
  apply %useFoo(%2)
  // End the lifetime of %2 (which implicitly ends the lifetime of %0, %1).
  end_borrow %2 : $Foo
  ...
```

The main complication for users is that now when attempting to discover the set
of implicit users on an owned or guaranteed value caused by their usage as an
argument of a borrow introducer like begin_borrow. For those who are unaware, a
begin_borrow places an implicit requirement on its parent value that the parent
value is alive for the entire part of the CFG where this begin_borrow is
live. Previously, one could just look for the end_borrows of the
begin_borrow. Now one must additionally look for consuming branch insts. This is
because the original value that is being borrowed from must be alive over the
entire web of guaranteed values. That is the entire web of guaranteed values act
as a liveness requirement on the begin_borrow's operand.

The way this is implemented is given a use that we are validating, if the use is
a BorrowScopeOperand (1), we see if the borrow scope operand consumes the given
guaranteed scope and forwards it into a borrow scope introducer. If so, we add
the list of consuming uses of the borrow scope introducer to the worklist to
visit and then iterate.

In order to avoid working with cycles, for now, the ownership verifier bans
liveness requiring uses that have cycles in them. This still allows us to have
loop carried guaranteed values.

(1) A BorrowScopeOperand is a concept that represents an operand to a SIL
instruction that begins a guaranteed scope of some sort. All BorrowScopeOperand
are thus at a minimum able to compute a compile time the static region in which
they implicitly use their operands. NOTE: We do not require the scope to be
represented as a SILValue in the same function.

We achieve some nice benefit by introducing this. Specifically:

1. We can optimize the pattern I mentioned above. This is a common pattern in
   many frameworks that want to return a default object if a computation fails
   (with the default object usually being some sort of global or static
   var). This will let us optimize that case when the global is a let global.

2. The SSA Updater can now be used with guaranteed values without needing to
   introduce extra copies. This will enable predictable mem opts to introduce
   less copies and for semantic arc opts to optimize the remaining copies that
   PMO exposes but does not insert itself.

rdar://56720519
2020-02-17 00:29:49 -08:00
Hamish Knight
312f7ddc50 Parse Swift decls in one shot
Instead of interleaving typechecking and parsing
for SIL files, first parse the file for Swift
decls by skipping over any intermixed SIL decls.
Then we can perform type checking, and finally SIL
parsing where we now skip over Swift decls.

This is an intermediate step to requestifying the
parsing of a source file for its Swift decls.
2020-02-04 13:04:50 -08:00
Joe Groff
84e20b630e SIL parser support for substituted function types 2019-12-10 12:08:42 -08:00
Slava Pestov
53bfc767a3 SIL: Track target formal type for casts
SIL type lowering erases DynamicSelfType, so we generate
incorrect code when casting to DynamicSelfType. Fixing this
requires a fair amount of plumbing, but most of the
changes are mechanical.

Note that the textual SIL syntax for casts has changed
slightly; the target type is now a formal type without a '$',
not a SIL type.

Also, the unconditional_checked_cast_value and
checked_cast_value_br instructions now take the _source_
formal type as well, just like the *_addr forms they are
intended to replace.
2019-11-20 21:30:28 -05:00
Michael Gottesman
7ee5ad7318 [sil] Rename {,Strong}Copy{Unowned,Unmanaged}. 2019-10-26 17:03:47 -07:00
Jordan Rose
a6dd630ca3 Eliminate Builtin.UnknownObject as an AST type (#27378)
This removes it from the AST and largely replaces it with AnyObject
at the SIL and IRGen layers. Some notes:

- Reflection still uses the notion of "unknown object" to mean an
  object with unknown refcounting. There's no real reason to make
  this different from AnyObject (an existential containing a
  single object with unknown refcounting), but this way nothing
  changes for clients of Reflection, and it's consistent with how
  native objects are represented.

- The value witness table and reflection descriptor for AnyObject
  use the mangling "BO" instead of "yXl".

- The demangler and remangler continue to support "BO" because it's
  still in use as a type encoding, even if it's not an AST-level
  Type anymore.

- Type-based alias analysis for Builtin.UnknownObject was incorrect,
  so it's a good thing we weren't using it.

- Same with enum layout. (This one assumed UnknownObject never
  referred to an Objective-C tagged pointer. That certainly wasn't how
  we were using it!)
2019-09-26 17:48:04 -07:00
Ewa Matejska
4412a795bf Using %sil-opt is inconsistent with the rest of the tests in this directory which use %target-sil-opt. This causes problems if some lit systems don't recognize %sil-opt and only recognize %target-sil-opt. Updating for consistency. 2019-09-22 22:45:23 -07:00
Saleem Abdulrasool
5a4878214b test: disable SIL tests on Windows
`weak_imported` is not supported on Windows as it does not provide weak
linking semantics.  Disable the tests on Windows.
2019-09-08 09:01:12 -07:00
Slava Pestov
3a59e7c53a SIL: Serialize availability with the SIL function, not just a weak imported flag
The weak imported flag is now only set if the attribute is unconditionally
weak linked, which is the case when it or one of its parent contexts has a
@_weakLinked attribute.

To correctly handle weak linking based availability with serialized SIL
functions, we need to serialize the actual version tuple when the SIL function
was introduced. This is because the deployment target of the client app can
be older than the deployment target that the original module was built with.

Fixes <rdar://problem/52783668>.
2019-09-06 20:08:40 -04:00
Michael Gottesman
af565e7cc0 [sil-parser] Fix harmless bug when parsing ossa.
Specifically, we were preferring the always correct ownership kind specified by
the FunctionType and ignoring what we parsed from the argument. This PR changes
ossa to give a nice error when this is detected and fixes the places where this
tests were written incorrectly.
2019-08-27 10:18:49 -07:00
Michael Gottesman
5fc1d1d349 [ownership] Define a new instruction copy_unmanaged_value.
This provides a singular instruction for convert an unmanaged value to a ref,
then strong_retain it. I expanded the definition of UNCHECKED_REF_STORAGE to
include these copy like instructions. This instruction is valid in all SIL.

The reason why I am adding this instruction is that currently when we emit an
access to an unowned (unsafe) ivar, we use an unmanaged_to_ref and a strong
retain. This can look to the optimizer like a strong retain that can potentially
be optimized. By combining the two together into a new instruction, we can avoid
this potential problem since the pattern matching will break.
2019-08-25 21:26:40 -07:00
Erik Eckstein
f26a9b9163 tests: fix some memory lifetime violations in SIL lit tests. 2019-08-13 09:29:05 +02:00
Erik Eckstein
32c0feb577 SIL: add a [dynamic_lifetime] flag to alloc_stack and alloc_box
This flag is set by DefinitInitialization if the lifetime of the stored value is controlled dynamically.
If the flag is set, it's not (easily) possibly to statically calculate the lifetime of the stored value.
2019-08-13 09:29:05 +02:00
Erik Eckstein
237a3ef77f SIL: Extend cond_fail by a second operand, which is a static string literal, indicating the failure reason. 2019-07-16 12:31:10 +02:00
Brent Royal-Gordon
d5a2912a26 Revert "Better runtime failure messages (not yet enabled by default)" 2019-07-15 13:42:40 -07:00
Erik Eckstein
e2d313ef68 SIL: Extend cond_fail by a second operand, which is a static string literal, indicating the failure reason. 2019-07-12 14:03:13 +02:00
Slava Pestov
f681cbe264 SIL: Remove SILVTable::Entry::Linkage
This field would store the linkage of the original method, if it was
distinct from the linkage of a vtable thunk. It is no longer used.
2019-06-09 15:54:05 -07:00
Michael Gottesman
f854547c55 [ownership] Enable ownership verification by default.
I also removed the -verify-sil-ownership flag in favor of a disable flag
-disable-sil-ownership-verifier. I used this on only two tests that still need
work to get them to pass with ownership, but whose problems are well understood,
small corner cases. I am going to fix them in follow on commits. I detail them
below:

1. SILOptimizer/definite_init_inout_super_init.swift. This is a test case where
DI is supposed to error. The only problem is that we crash before we error since
the code emitting by SILGen to trigger this error does not pass ownership
invariants. I have spoken with JoeG about this and he suggested that I fix this
earlier in the compiler. Since we do not run the ownership verifier without
asserts enabled, this should not affect compiler users. Given that it has
triggered DI errors previously I think it is safe to disable ownership here.

2. PrintAsObjC/extensions.swift. In this case, the signature generated by type
lowering for one of the thunks here uses an unsafe +0 return value instead of
doing an autorelease return. The ownership checker rightly flags this leak. This
is going to require either an AST level change or a change to TypeLowering. I
think it is safe to turn this off since it is such a corner case that it was
found by a test that has nothing to do with it.

rdar://43398898
2019-03-25 00:11:52 -07:00
Michael Gottesman
7b0309b432 [ownership] Fix up some parse/serialization tests for ownership.
Since I am enabling ownership verification by default, rather than disabling it
on these tests I just fixed them to follow ownership invariants.
2019-03-24 22:24:46 -07:00
Michael Gottesman
0dfaa19f9f [ownership] Rename enable-sil-ownership => verify-sil-ownership.
I have been meaning to do this change for a minute, but kept on putting it off.
This describes what is actually happening and is a better name for the option.
2019-03-18 01:31:44 -07:00
Slava Pestov
1159af50d9 Rename -enable-resilience to -enable-library-evolution and make it a driver flag
Fixes <rdar://problem/47679085>.
2019-03-14 22:24:26 -04:00
Michael Gottesman
dfe65c20f1 [lit] Change all %target-swift-frontend invocations to verify ownership.
We are already doing this for most of the target-swift-frontend ones. In a
subsequent commit, I am going to remove the redundant ones.

NOTE: On Darwin, I have not enabled it on the %target-swift-frontend mock SDK
commands. I ran into an issue with one of the PrintAsObjC tests that I am still
tracking down. I would rather just get this turned on to prevent further
regressions.

I also updated a few tests that needed some small tweaks to pass
this. Specifically:

1. Some parser tests needed some extra ossa insts to pass the verifier. This
doesn't effect what they actually test.

2. IRGen tests that should never have processed ossa directly. Today, we are
working towards a world where IRGen never processes [ossa] directly. Instead we
lower first. If/when that changes, we should add back in specific [ossa] tests.

3. A singular SILOptimizer definite init test case where the ownership verifier
fails due to a case which DI already flags as illegal (we just crash earlier). I
am going to look into fixing that by putting in errors in the typechecker or in
SILGen (not sure yet). I changed it to use target-swiftc_driver which does not
have ownership verification enabled.
2019-03-12 20:17:20 -07:00
Joe Groff
bb67cf815c Merge pull request #21355 from technicated/tuple-keypaths-2
Tuple KeyPaths
2019-02-25 12:56:05 -08:00
technicated
1577afee80 Added more tests (related to generic tuples) 2019-02-18 10:19:43 +01:00
technicated
d7324b977e Added more tests
Testing SILGen & IRGen tuple keypath generation
Added tuple element type check in SILVerifier
2019-02-18 10:19:42 +01:00
Azoy
5af2663c57 Textualize assign init kind
Rename [assign] to [reassign]

fix some tests

AssignOwnershipQualifier

formatting

moar formatting
2019-02-12 20:16:25 -06:00
Arnold Schwaighofer
cb0c53abee SIL: Remove isEscapedByUser flag on convert_escape_to_noescape instruction
It was only used for materializeForSet and is now dead code.
2019-01-04 09:21:38 -08:00
John McCall
e674d65dfd When parsing SILDeclRefs, ignore declarations that lack the right accessor.
Fixed rdar://46650834.
2019-01-03 16:26:46 -05:00
Slava Pestov
2e635e9603 Sema: Add @_hasInitialValue and @_hasStorage in typeCheckDecl() not validateDecl()
We only ever use this in TBDGen and interface printing, and we only ever
generate TBD files or print interfaces for declarations in primary files,
so let's avoid unnecessary work in validateDecl().

Eventually we want validateDecl() to be replaced with a getInterfaceType()
request, so adding new attributes in this path (or other side effects in
general) is a big no-no.
2019-01-02 15:12:02 -05:00
Saleem Abdulrasool
bf7ea5b2e8 test: make the last SIL.Parse test pass on Windows
With the UUID conversion, this is the last SIL.Parse test failure on Windows due
to the DLLExport annotation.
2018-12-21 10:46:08 -08:00
Slava Pestov
fef729a2bc SIL: Set witness table linkage when parsing a witness table that already exists
I discovered this while testing the new commit, since it results in fewer
witness tables getting pre-declared.

There was a SIL test that relied on the old behavior; I'm going to explicitly
declare those witness tables as public_external to preserve behavior.
2018-12-20 17:36:38 -05:00
Michael Gottesman
4b95ca82b9 Merge pull request #21439 from gottesmm/pr-8067c5675a42d8ecfc248e2b2fe644ee2795fc06
[ownership] Eliminate -assume-parsing-unqualified-ownership-sil now that it is a no-op.
2018-12-19 17:35:40 -08:00
Michael Gottesman
fd4828e40a Eliminate -assume-parsing-unqualified-ownership-sil from tests.
I am doing this separately from the actual change to eliminate the option to
make it easier to review.
2018-12-19 12:54:13 -08:00
swift-ci
14dfa755a2 Merge pull request #21427 from brentdax/grading-tests-on-a-curve 2018-12-19 12:33:57 -08:00
Brent Royal-Gordon
7733cf27ca Switch swift-evolve XFAILs to UNSUPPORTEDs
These tests may not *reliably* fail with shuffled standard libraries, so we can’t use XFAIL, which fails if the test succeeds.
2018-12-18 16:25:12 -08:00
Michael Gottesman
40a09c9c21 Fixup tests for -assume-parsing-unqualified-ownership-sil => [ossa] transition. 2018-12-18 00:49:32 -08:00
Brent Royal-Gordon
7a3ed15846 Exclude/fix certain tests for swift-evolve (#21276)
* Add swift_evolve feature and disable several tests

This change adds a swift_evolve feature to our lit configuration and uses it to mark several tests as unsupported by swift_evolve.

One of these—test/api-digester/stability-stdlib-abi.swift—is actually pretty bad; we would really like to have it. But the digester has known issues exposed by swift-evolve.

* Remove order dependency in another test

* Tweaks from Jordan’s review

* Distinguish between tests which are intentionally unsupported and temporarily disabled.
* Add an explanation for one unsupproted test.
* Code nitpick.
2018-12-13 14:26:47 -08:00
Slava Pestov
aa747dcd81 Remove property behaviors 2018-12-07 20:38:33 -05:00
Michael Gottesman
0af0d5fddc [ownership] Replace ValueOwnershipKind::Trivial with ValueOwnershipKind::Any.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.

This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).

NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.

rdar://46294760
2018-12-04 23:01:43 -08:00
Karoy Lorentey
666a22feff [test] Modernize hashing throughout the test suite 2018-11-29 17:38:29 +00:00
Harlan Haskins
a1c23be91a [ParseableInterface] Standardize printing for accessors
We want to make sure we are consistent when printing accessors.
@jrose-apple and I landed on the following table for disambiguating all
the possible combinations of accessors:

\### Computed Properties

| Semantics  | Syntax                 |
|------------|------------------------|
| Read-only  | var x: T { get }       |
| Read-write | var x: T { get set }   |

\### Stored Properties

| Semantics                | Syntax                              |
|--------------------------|-------------------------------------|
| Immutable                | let x: T                            |
| Mutable (trivial setter) | var x: T                            |
| Mutable (custom setter)  | @_hasStorage var x: T { get set }   |
| Private(set)             | @_hasStorage var x: T { get }       |

This first commit enables printing @_hasStorage outside of SIL mode.
2018-11-26 18:40:37 -08:00
Harlan Haskins
66a61c5eca Rename @sil_stored to @_hasStorage 2018-11-12 11:32:32 -08:00
Arnold Schwaighofer
52c1903e54 Add SIL support for [dynamic_replacement_for: ] functions 2018-11-06 09:58:28 -08:00
Arnold Schwaighofer
5f4e183302 Add [dynamically_replacable] to SILFunctions
'dynamic' functions are marked as [dynamically_replaceable].
2018-11-06 09:53:21 -08:00
John McCall
abdba1d3f4 Change the integer-literal type from Int2048 to IntLiteral.
Part of SR-290.
2018-10-31 23:14:58 -04:00
Slava Pestov
ebe769a58c SIL: Stop imploding parameter list into a single value with opaque abstraction pattern
The constraint solver support for the Swift 3 function type behavior
has been removed, so it's no longer possible to pun the same value as
both a function taking multiple parameters and a function taking a
single tuple argument.

This means the entire parameter list is no longer a target for
substitution as a single value, so the most general form of a function
value passes each parameter indirectly instead of passing a single
tuple parameter indirectly.
2018-09-26 23:20:54 -07:00