Commit Graph

2053 Commits

Author SHA1 Message Date
Erik Eckstein
2dbd6cc56b SwiftCompilerSources: rework bridging
Introduce two modes of bridging:
* inline mode: this is basically how it worked so far. Using full C++ interop which allows bridging functions to be inlined.
* pure mode: bridging functions are not inlined but compiled in a cpp file. This allows to reduce the C++ interop requirements to a minimum. No std/llvm/swift headers are imported.

This change requires a major refactoring of bridging sources. The implementation of bridging functions go to two separate files: SILBridgingImpl.h and OptimizerBridgingImpl.h.
Depending on the mode, those files are either included in the corresponding header files (inline mode), or included in the c++ file (pure mode).

The mode can be selected with the BRIDGING_MODE cmake variable. By default it is set to the inline mode (= existing behavior). The pure mode is only selected in certain configurations to work around C++ interop issues:
* In debug builds, to workaround a problem with LLDB's `po` command (rdar://115770255).
* On windows to workaround a build problem.
2023-10-09 09:52:52 +02:00
swift-ci
b684ade6c2 Merge remote-tracking branch 'origin/main' into rebranch 2023-10-05 13:54:30 -07:00
Nate Chandler
ad33b5de34 [OSSALifetimeCompletion] Handle available boundary
Not every block in a region which begins with the non-lifetime-ending
boundary of a value and ending with unreachable-terminated blocks has
the value available.  If the unreachable-terminated blocks in this
boundary are not available, it is incorrect to insert destroys of the
value in them: it is an overconsume on some paths.  Previously,
however, destroys were simply being inserted at the unreachable.

Here, this is fixed by finding the boundary of availability within that
region and inserting destroys before the terminators of the blocks on
that boundary.

rdar://116255254
2023-10-05 09:15:58 -07:00
Nate Chandler
2824bf3125 [CanOSSALifetime] Record "unreachable" insts.
OSSALifetimeCompletion needs to insert not at unreachable instructions
that appear after the non-lifetime-ending boundary of a value but rather
at the terminators of the availability boundary of the value within that
region.  Once it does so, it will no longer be sufficient to check
whether the insertion point is an unreachable because such terminators
may be another terminator that appears on the availability boundary.
Prepare for that by recording the instructions that were found and
checking whether the destroy insertion point is such an instruction
before bailing rather than specifically checking for `unreachable`.
2023-10-04 16:48:06 -07:00
swift-ci
6cf1f90e79 Merge remote-tracking branch 'origin/main' into rebranch 2023-10-04 04:35:13 -07:00
Tony Allevato
5f5b24f96e [C++20] Make operator{==,!=}s const.
In C++20, the compiler will synthesize a version of the operator
with its arguments reversed to ease commutativity. This reversed
version is ambiguous with the hand-written operator when the
argument is const but `this` isn't.
2023-10-03 17:10:57 -04:00
swift-ci
6c89a2244b Merge remote-tracking branch 'origin/main' into rebranch 2023-09-28 08:58:02 -07:00
Michael Gottesman
8d46cc8c08 [isolation-regions] Rename Consume to Transfer.
Transfer is the terminology that we are using for something be transferred
across an isolation boundary, not consume. This also eliminates confusion with
consume which is a term being used around ownership.
2023-09-22 16:21:46 -05:00
swift-ci
764fecbc01 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-21 20:34:25 -07:00
nate-chandler
397a25c377 Merge pull request #68608 from nate-chandler/rdar115468707
[CanonicalizeOSSALifetime] Extend lexical lifetimes to unreachables.
2023-09-21 20:25:46 -07:00
swift-ci
c55b21f2b5 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-21 16:10:25 -07:00
Nate Chandler
6c6776234a [CanOSSALife] Lexical lifetimes go to unreachables
When canonicalizing the lifetime of a lexical value, deinit barriers are
respected. This is done by walking backwards from lifetime ends and
adding encountered deinit barriers to liveness.

Only destroy lifetime ends were walked back from under the assumption
that lifetimes would be complete. Without complete OSSA lifetimes,
however, it's necessary to also necessary to consider lifetimes that end
with unreachables. Unfortunately, we can't simply walk back from those
unreachables because there may be instructions which are secretly users
of the value being canonicalized (e.g. destroys of `partial_apply`s to
which a `begin_borrow` of the value was passed). Such uses don't appear
in the use list because lifetime canonicalization expects complete
lifetimes and only visits lifetime ends of `begin_borrow`s.

Here, instead, the instructions before the relevant unreachables are
added to liveness. In order to determine which unreachables are
relevant, it's necessary to have a liveness that includes the original
destroys. So a copy of liveness is created and those destroys are added
to it.

rdar://115468707
2023-09-21 14:02:43 -07:00
Kavon Farvardin
b688a1f4a1 [SILOpt] experimental async demotion pass
For chains of async functions where suspensions can be statically
proven to never be required, this pass removes all suspensions and
turns the functions into synchronous functions.

For example, this function does not actually require any suspensions,
once the correct executor is acquired upon initial entry:

```
func fib(_ n: Int) async -> Int {
  if n <= 1 { return n }
  return await fib(n-1) + fib(n-2)
}
```

So we can turn the above into this for better performance:

```
func fib() async -> Int {
  return fib_sync()
}

func fib_sync(_ n: Int) -> Int {
  if n <= 1 { return n }
  return fib(n-1) + fib(n-2)
}
```

while rewriting callers of `fib` to use the `sync` entry-point
when we can prove that it will be invoked on a compatible executor.

This pass is currently experimental and under development. Thus, it
is disabled by default and you must use
`-enable-experimental-async-demotion` to try it.
2023-09-21 12:21:02 -07:00
Kavon Farvardin
d0a9e78da0 [Mangling] Support function specializations that remove async 2023-09-21 12:20:24 -07:00
swift-ci
e59baf89ed Merge remote-tracking branch 'origin/main' into rebranch 2023-09-20 17:56:36 -07:00
Nate Chandler
9006be10e3 [CanOSSALifetime] Respect lexical lifetimes flag.
Don't respect deinit barriers when canonicalizing if lexical lifetimes
are disabled.
2023-09-20 13:40:08 -07:00
Kuba Mracek
7e213982e9 [embedded] Add SWIFT_IMPORT_UNSAFE annotation to specializeVTableForType 2023-09-20 09:48:08 -07:00
Kuba Mracek
89df0426e0 [embedded] Specialize vtables when processing instructions, not bulk 2023-09-20 09:41:09 -07:00
Kuba Mracek
03f927eca1 [embedded] Perform VTable specialization iteratively as part of MandatoryPerformanceOptimizations 2023-09-20 09:41:09 -07:00
swift-ci
c2d0ed607a Merge remote-tracking branch 'origin/main' into rebranch 2023-09-19 11:33:34 -07:00
Erik Eckstein
5bc036661c SIL optimizer: add the LetPropertyLowering pass
It lowers let property accesses of classes.
Lowering consists of two tasks:

* In class initializers, insert `end_init_let_ref` instructions at places where all let-fields are initialized.
  This strictly separates the life-range of the class into a region where let fields are still written during
  initialization and a region where let fields are truly immutable.

* Add the `[immutable]` flag to all `ref_element_addr` instructions (for let-fields) which are in the "immutable"
  region. This includes the region after an inserted `end_init_let_ref` in an class initializer, but also all
  let-field accesses in other functions than the initializer and the destructor.

This pass should run after DefiniteInitialization but before RawSILInstLowering (because it relies on `mark_uninitialized` still present in the class initializer).
Note that it's not mandatory to run this pass. If it doesn't run, SIL is still correct.

Simplified example (after lowering):

  bb0(%0 : @owned C):                           // = self of the class initializer
    %1 = mark_uninitialized %0
    %2 = ref_element_addr %1, #C.l              // a let-field
    store %init_value to %2
    %3 = end_init_let_ref %1                    // inserted by lowering
    %4 = ref_element_addr [immutable] %3, #C.l  // set to immutable by lowering
    %5 = load %4
2023-09-19 15:10:30 +02:00
Erik Eckstein
ad594f2713 Swift SIL: add some APIs
* `AssignInst`
* `Function.isDestructor`
* `MarkUninitializedInst.kind`
* `Type.isMoveOnly`
* `RefElementAddrInst.isImmutable` and `RefElementAddrInst.set(isImmutable:)`
* `BeginBorrowInst.endBorrows`
* `Context.hadError` and `Context.silStage`
2023-09-19 15:10:30 +02:00
swift-ci
26372e82a7 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-15 07:15:21 -07:00
Nate Chandler
e912c036f6 [Reachability] NFC: Split initial from barrier.
Although by analogy with def instructions as barrier instructions one
could understand how a block where the def appears as a phi could be
regarded as a barrier block, the analogy is nonobvious.

Reachability knows the difference between an initial block and a barrier
block.  Although most current clients don't care about this distinction,
one does.  Here, Reachability calls back with visitInitialBlock for the
former and visitBarrierBlock for the latter.

Most clients are updated to have the same implementation in both
visitBarrierBlock and visitInitialBlock.  The findBarriersBackward
client is updated to retain the distinction and pass it on to its
clients.  Its one client, CanonicalizeOSSALifetime is updated to have a
simpler handling for barrier edges and to ignore the initial blocks.
2023-09-14 17:11:20 -07:00
swift-ci
ae30cba296 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-13 10:20:48 -07:00
Kuba (Brecka) Mracek
b503f2831b Merge pull request #68461 from kubamracek/embedded-classes-generic
[embedded] Initial support for generic classes in embedded Swift
2023-09-13 10:01:50 -07:00
swift-ci
449f8e4910 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-13 07:20:11 -07:00
Evan Wilde
eba8c9ab57 Merge pull request #68476 from etcwilde/ewilde/include-variant 2023-09-13 07:04:22 -07:00
swift-ci
aeb4460bff Merge remote-tracking branch 'origin/main' into rebranch 2023-09-12 19:34:23 -07:00
Michael Gottesman
163d5bceff Merge pull request #68466 from gottesmm/actor-field-access-sns
[send-non-sendable] Treat final fields of actors and values returned from actor methods as non-transferrable
2023-09-12 19:28:22 -07:00
Evan Wilde
e088865a38 Include variant in AdjointValue.h
d971f125d9 added a usage of std::variant and std::holds_alternative to
SILOptimizer/Differentiation/AdjointValue.h, but did not include variant
directly. This caused issues while building on Linux.
2023-09-12 16:07:41 -07:00
swift-ci
84738eeae9 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-12 14:34:05 -07:00
Kshitij Jain
d971f125d9 [AutoDiff] Handle materializing adjoints with non-differentiable fields (#67319) 2023-09-12 14:22:41 -07:00
Michael Gottesman
82fbde0e04 [send-non-sendable] Ensure that we properly warn if a field of a final actor is transferred.
Previously, we were not recognizing that a ref_element_addr from an actor object
is equivalent to the actor object and we shouldn't allow for it to be consumed.

rdar://115132118
2023-09-12 12:46:37 -05:00
Michael Gottesman
3a377a3e51 [send-non-sendable] When logging the pseudo-ir dump out the root representative value associated with pseudo-ir ids.
Really, we should just be using representative values here in general since it
serves the same purpose and makes it easier to trace back values. But this in
the short term makes the output easier to reason about.
2023-09-12 12:11:44 -05:00
Michael Gottesman
42df9c4c72 [send-non-sendable] Cleanup logging a little.
Specifically:

1. Converted llvm::errs() -> llvm::dbgs() when using LLVM_DEBUG.
2. Converted a dump method on errs to be a print method on dbgs that is called from dump with print(llvm::dbgs()).
2023-09-12 12:11:44 -05:00
Kuba Mracek
d0c2a4ccf8 [embedded] Initial support for generic classes in embedded Swift
- VTableSpecializer, a new pass that synthesizes a new vtable per each observed concrete type used
- Don't use full type metadata refs in embedded Swift
- Lazily emit specialized class metadata (LazySpecializedClassMetadata) in IRGen
- Don't emit regular class metadata for a class decl if it's generic (only emit the specialized metadata)
2023-09-12 09:44:54 -07:00
Michael Gottesman
a1daf817f3 [send-non-sendable] Remove ASCII color from log output.
Not everyone uses color output and having to remove the ASCII color support is
annoying.
2023-09-11 09:07:29 -05:00
swift-ci
f52fc06ac7 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-06 18:14:46 -07:00
zoecarver
52cea4250e [embedded] 🚀 add Embedded expiremental feature.
Optimize all functions in embedded mode. Diagnose any uses of existentials or witness tables.
2023-09-06 10:48:17 -07:00
swift-ci
a77bcdc1eb Merge remote-tracking branch 'origin/main' into rebranch 2023-09-05 04:34:20 -07:00
Erik Eckstein
f6f9e75173 AliasAnalysis: use a complexity limit for the isObjReleased function
We already use a complexity limit for other functions in AliasAnalysis.
This is a workaround for quadratic complexity in ARCSequenceOpts.

Fixes a compile time problem
rdar://114352817
2023-09-04 19:52:57 +02:00
swift-ci
aae06b0943 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-31 22:54:14 -07:00
Allan Shortlidge
255d5d4670 SILOptimizer: Compute ClassHierarchyAnalysis cache lazily.
When serializing modules with `-experimental-skip-all-function-bodies`, this
analysis was eagerly populating a cache that would go unused since there is no
optimization to do. With `-experimental-lazy-typecheck`, this work would also
trigger unnecessary typechecking requests. NFC.
2023-08-31 10:58:56 -07:00
Allan Shortlidge
e8ae38365d SILOptimizer: Compute ProtocolConformanceAnalysis cache lazily.
When serializing modules with `-experimental-skip-all-function-bodies`, this
analysis was eagerly populating a cache that would go unused since there is no
optimization to do. With `-experimental-lazy-typecheck`, this work would also
trigger unnecessary typechecking requests. NFC.
2023-08-31 10:58:56 -07:00
swift-ci
4fe55c5732 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-11 00:35:20 -07:00
swift-ci
2667df0799 Merge pull request #67760 from atrick/fix-closure-moveonly-arg
Fix compiler crashes with consuming and borrowing keywords.
2023-08-11 00:32:41 -07:00
Andrew Trick
f46d79149d ClosureLifetimeFixup review feedback 2023-08-10 18:51:48 -07:00
swift-ci
18d09ab835 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-10 11:55:59 -07:00
Andrew Trick
9c24933bd4 Fix compiler crashes with consuming and borrowing keywords.
Without this fix, the new 'consuming' and 'borrowing' keywords cannot
be used with trivial types. Which means, for example, they can't be
used in macro expansions that work on various types.

Fixes patterns like:

public func test1(i: consuming Int) -> Int {
  takeClosure { [i = copy i] in i }
}

public func test2(i: borrowing Int) -> Int {
  takeClosure { [i = copy i] in i }
}

public func test3(i: consuming Int) -> Int {
  takeClosure { i }
}

// Sadly, test4 is still incorrectly diagnosed.
public func test4(i: borrowing Int) -> Int {
  takeClosure { i }
}

Fixes rdar://112795074 (Crash compiling function that has a macro annotation and uses `consuming`)
2023-08-10 11:17:45 -07:00