Commit Graph

11 Commits

Author SHA1 Message Date
Michael Gottesman
734f057ce8 [concurrency] Fix optimize_hop_to_executor so that we take advantage of the new nonisolated(nonsending) ABI in post 6.2.
Specifically:

1. We assume in nonisolated(nonsending) that we are already on the relevant
actor. This lets us always eliminate the initial hop_to_executor.

2. We stopped treating nonisolated(nonsending) functions as suspension points
since we are guaranteed to always be on the same actor when we enter/return.

3. Now that nonisolated(nonsending) is no longer a suspension point, I could
sink the needs executor nonisolated(nonsending) specific code into the needs
executor code. For those unfamiliar it is that we: a. treat a
nonisolated(nonsending) callee as a needs executor since we are no longer
guaranteed to hop in callees and b. treat returns from nonisolated(nonsending)
functions as being a needs executor instruction since we are no longer
guaranteed to hop in the caller after such a function returns.

rdar://155465878
2025-08-10 14:58:25 -07:00
Michael Gottesman
b3942424c8 [concurrency] Make optimize hop to executor more conservative for 6.2 around caller isolation inheriting functions.
Specifically for 6.2, we are making optimize hop to executor more conservative
around caller isolation inheriting functions. This means that we are:

1. No longer treating calls to caller isolation inheriting functions as having a
hop in their prologue. In terms of this pass, it means that when determining
dead hop to executors, we no longer think that a caller isolation inheriting
function means that an earlier hop to executor is not required.

2. Treating returns from caller isolation inheriting callees as requiring a
hop. The reason why we are doing this is that we can no longer assume that our
caller will hop after we return.

Post 6.2, there are three main changes we are going to make:

* Forward Dataflow

Caller isolation inheriting functions will no longer be treated as suspension
points meaning that we will be able to propagate hops over them and can assume
that we know the actor that we are on when we enter the function. Practically
this means that trees of calls that involve just nonisolated(nonsending) async
functions will avoid /all/ hop to executor calls since we will be able to
eliminate all of them since the dataflow will just propagate forward from the
entrance that we are already on the actor.

* Backwards Dataflow

A caller isolation inheriting call site will still cause preceding
hop_to_executor functions to be live. This is because we need to ensure that we
are on the caller isolation inheriting actor before we hit the call site. If we
are already on that actor, the hop will be eliminated by the forward pass. But
if the hop has not been eliminated, then the hop must be needed to return us to
the appropriate actor.

We will also keep the behavior that returns from a caller isolation inheriting
function are considered to keep hop to executors alive. If we were able to
propagate to a hop to executor before the return inst with the forward dataflow,
then we know that we are guaranteed to still be on the relevant actor. If the
hop to executor is still there, then we need it to ensure that our caller can
treat the caller isolation inheriting function as a non-suspension point.

rdar://155905383
2025-07-15 17:03:49 -07:00
Nate Chandler
252b5638eb [OptHopToExecutor] Borrows don't need executors.
Although they currently have MemoryBehavior::MayHaveSideEffects, the
begin_borrow and end_borrow instructions do not have side-effects of
interest to this pass.
2023-07-11 17:20:25 -07:00
Doug Gregor
eeeea49764 Remove -enable-experimental-concurrency almost everywhere. 2021-07-26 21:24:43 -07:00
Andrew Trick
c4f1f56ea7 Add Builtin.hopToActor
SILGen this builtin to a mandatory hop_to_executor with an actor type
operand.

e.g.

    Task.detached {
      Builtin.hopToActor(MainActor.shared)
      await suspend()
    }

Required to fix a bug in _runAsyncMain.
2021-06-13 23:44:30 -07:00
John McCall
ec5215bf4f Remove the implicit nil inhabitant of Builtin.Executor,
and traffic in Optional<Builtin.Executor> in various places.
2021-04-30 03:11:56 -04:00
John McCall
57c0c787db Make Builtin.getCurrentExecutor conservatively not readnone.
Fixes a miscompile where the hop_to_executor optimizer would
remove hop_to_executor before a getCurrentExecutor.
2021-04-08 12:57:11 -04:00
Evan Wilde
8b80331c3d Updating tests to use actor
This patch updates the `actor class` spelling to `actor` in almost all
of the tests. There are places where I verify that we sanely handle
`actor` as an attribute though. These include:

 - test/decl/class/actor/basic.swift
 - test/decl/protocol/special/Actor.swift
 - test/SourceKit/CursorInfo/cursor_info_concurrency.swift
 - test/attr/attr_objc_async.swift
 - test/ModuleInterface/actor_protocol.swift
2021-02-10 08:09:13 -08:00
Daniel Rodríguez Troitiño
748339a83a [test] Mark concurrency tests with appropiate REQUIRES. (#35624)
The Python build system always enables concurrency, but CMake has it
disable by default. Collaborators that do not use the Python build
system and use directly CMake will have it disable, unless they
explicitely enable it. If the tests are not marked as requiring the
concurrency features, the tests will fail to execute when concurrency is
disabled.

The changes add the `REQUIRES: concurrency` line to many tests that deal
with concurrency, but wasn't marked as such.
2021-02-01 11:45:15 -08:00
Erik Eckstein
a19ae5c1c5 [concurrency] Correctly handle dead-end and unreachable blocks in OptimizeHopToExecutor
Fixes an infinite loop.

rdar://problem/71544153
2020-11-19 13:10:50 +01:00
Erik Eckstein
a47ebabe54 [concurrency] SILOptimizer: optimize hop_to_executor instructions.
* Redundant hop_to_executor elimination: if a hop_to_executor is dominated by another hop_to_executor with the same operand, it is eliminated:

      hop_to_executor %a
      ... // no suspension points
      hop_to_executor %a // can be eliminated

* Dead hop_to_executor elimination: if a hop_to_executor is not followed by any code which requires to run on its actor's executor, it is eliminated:

      hop_to_executor %a
      ... // no instruction which require to run on %a
      return

rdar://problem/70304809
2020-11-05 18:48:22 +01:00