Commit Graph

2592 Commits

Author SHA1 Message Date
Andrew Trick
903697675b Fix EagerSpecializer to avoid critical edges. 2020-11-06 08:31:23 -08:00
swift_jenkins
6c8d31207e Merge remote-tracking branch 'origin/main' into next 2020-11-05 21:34:59 -08:00
swift_jenkins
edac49f12a Merge remote-tracking branch 'origin/main' into next 2020-11-05 16:05:42 -08:00
Doug Gregor
c291eb596b [Concurrency] Add cancelAsyncTask() builtin.
Implement a new builtin, `cancelAsyncTask()`, to cancel the given
asynchronous task. This lowers down to a call into the runtime
operation `swift_task_cancel()`.

Use this builtin to implement Task.Handle.cancel().
2020-11-05 13:50:17 -08:00
Doug Gregor
ed9a548c9f [Concurrency] Return getCurrentAsyncTask() as owned.
Rather than produce an "unowned" result from `getCurrentAsyncTask()`,
take advantage of the fact that the task is effectively guaranteed in
the scope. Do so be returning it as "unowned", and push an
end_lifetime cleanup to end the lifetime. This eliminates unnecessary
ref-count traffic as well as introducing another use of unowned.

Approach is thanks to Michael Gottesman, bugs are mine.
2020-11-05 12:18:49 -08:00
swift_jenkins
c145199093 Merge remote-tracking branch 'origin/main' into next 2020-11-04 15:00:00 -08:00
Arnold Schwaighofer
3797809cea Add struct CfgTraitsFor<swift::SILBasicBlock> 2020-11-04 14:30:25 -08:00
Meghana Gupta
483321c360 Enable ArrayElementValuePropagation on ownership SIL 2020-11-04 11:54:47 -08:00
Andrew Trick
e5755c6010 Merge pull request #33113 from atrick/silopt-critedge
SILCloner: fix critical edge handling; remove previous workarounds
2020-11-03 18:12:17 -08:00
Andrew Trick
223ee10939 EdgeThreadingCloner. Remove splitCriticalEdges calls. 2020-11-03 01:40:00 -08:00
Andrew Trick
824cf85165 Fix SimplifyCFG jump-threading to cleanup after itself.
Avoid extra blocks and/or extra iterations in the simplify loop.
2020-11-03 01:40:00 -08:00
Andrew Trick
8278332a92 SILCloner should not introduce new critical edges.
Also, it must update the DomTree for any CFG changes except for the
addition of cloned blocks.
2020-11-03 01:30:58 -08:00
Andrew Trick
f5b51474a7 Fix the SimplifyCFG ThreadInfo broken abstraction.
In a blatant abuse of OO style, the logic for manipulating the CFG was
encapsulated inside a descriptor of the CFG edge, making it impossible
to work with.
2020-11-03 01:28:21 -08:00
Andrew Trick
51dfc63d51 SimplifyCFG: fix indentation so subsequent diffs are clean. 2020-11-03 01:10:30 -08:00
Meghana Gupta
e602aa5de7 Merge pull request #34500 from meg-gupta/fixmem2regassert
SILMem2Reg : Delete phi args added by Mem2Reg if there are no uses
2020-11-02 13:08:43 -08:00
Meghana Gupta
39b5ec2a49 SILMem2Reg : Delete phi args added by Mem2Reg if there are no uses
Fixes rdar://70617096
2020-10-29 21:43:36 -07:00
Andrew Trick
871518ca1a SimplifyCFG; add jump-threading successors to the worklist.
This is required for SimplifyCFG to iterate over simplified blocks
when it does critical edge splitting.
2020-10-29 15:25:20 -07:00
Andrew Trick
8991192793 SimplifyCFG; trampoline cleanup
Remove a pile of crufty "trampoline" elimination code that didn't make
sense.
2020-10-29 15:25:20 -07:00
Andrew Trick
b1fbc2b389 Rewrite SimplifyCFG's trampoline removal.
Avoid introducing new critical edges. Passes will end up resplitting
them, forcing SimplifyCFG to continually rerun. Also, we want to allow
SIL utilities to assume no critical edges, and avoid the need for
several passes to internally split edges and modify the CFG for no
reason.

Also, handle arbitrary block arguments which may be trivial and
unrelated to the real optimizations that trampoline removal exposes,
such as "unwrapping" enumeration-type arguments.

The previous code was an example of how to write an unstable
optimization. It could be defeated by other code in the function that
isn't directly related to the SSA graph being optimized. In general,
when an optimization can be defeated by unrelated code in the
function, that leads to instability which can be very hard to track
down (I spent multiple full days on this one). In this case, we have
enum-type branch args which need to be simplified by unwrapping
them. But, the existence of a trivial and entirely unrelated block
argument would defeat the optimization.
2020-10-29 15:25:20 -07:00
Andrew Trick
d8dcf61026 Improve SimplifyCFG: remove conditional branches to the same target. 2020-10-26 13:12:22 -07:00
Andrew Trick
d82e0ff781 SILInliner: Critical edges have no code size impact.
I think unconditional branches should be free, period. They will
mostly be removed during LLVM code gen. However, fixing this requires
signficant adjustments to inlining heuristics to avoid microbenchmark
regressions at -Osize. So, instead I am just making this less
sensitive to critical edges for the sake of pipeline stability.
2020-10-26 10:49:18 -07:00
Michael Gottesman
bdd7b42633 [copy-propagation] Since this runs on OSSA and we have formalized consuming there, use that instead of our own handrolled consuming use impl.
This is in preparation for adding a run of this around ownership lowering in
order to eliminate extra copies that passes may introduce as they transform IR.

The tests for the pass all still pass in the exact same way so no updates were
needed.
2020-10-23 16:09:15 -07:00
Meghana Gupta
a79043928e Merge pull request #34276 from meg-gupta/mem2regossa
[ownership] Enable SILMem2Reg for OSSA
2020-10-21 12:00:03 -07:00
Meghana Gupta
0ea5d055a2 Delete debug_value_addr of stack location, if a debug_value of the RunningVal is already found 2020-10-20 20:44:59 -07:00
Meghana Gupta
83474707ee Enable SILMem2Reg for OSSA
SILMem2Reg has roughly 2 central algorithms, removal of alloc_stack with uses in a
single block vs multiple blocks. While replacing loads and stores to the
stack location in each of the 2 algorithms, new handling of qualifiers
like [assign], [copy] and [take] which are new to OSSA are needed.

Also Disable SILMem2Reg when we see this pattern:
load [take] (struct_element_addr/tuple_element_addr %ASI)

Convert SILMem2Reg tests into ossa
And add new SILMem2Reg tests for non-trivial values.
Thanks to zoecarver for additional tests.
2020-10-20 20:44:54 -07:00
Andrew Trick
fd8f723f60 Merge pull request #34126 from atrick/add-accesspath
Add an AccessPath abstraction and formalize memory access
2020-10-19 10:17:27 -07:00
Andrew Trick
f6b32aedcd Add AccessedStorageWithBase to conviently recover the base's VarDecl 2020-10-16 15:00:10 -07:00
Andrew Trick
6f2cda1390 Add AccessUseVisitor and cleanup related APIs.
Add AccesssedStorage::compute and computeInScope to mirror AccessPath.

Allow recovering the begin_access for Nested storage.

Adds AccessedStorage.visitRoots().
2020-10-16 15:00:10 -07:00
Andrew Trick
85ff15acd3 Add indexTrieRoot to the SILModule to share across Analyses.
...and avoid reallocation.

This is immediately necessary for LICM, in addition to its current
uses. I suspect this could be used by many passes that work with
addresses. RLE/DSE should absolutely migrate to it.
2020-10-16 15:00:09 -07:00
Erik Eckstein
1e5f3bd253 TempRValueOpt: only do the check for "unusual" temp object destruction in non-OSSA mode.
In OSSA, memory locations are always destroyed in a "visible" way, e.g. with destroy_addr or load [take].
2020-10-16 17:27:32 +02:00
Erik Eckstein
262c7b251f TempRValueOpt: don't allow copy_addr [take] from a projection of the temporary.
This fixes a memory lifetime failure.
2020-10-16 17:27:32 +02:00
Erik Eckstein
4557f151b1 TempRValueOpt: fix the placement of destroy_addr in case of a copy_addr [take]
Instead of reusing the existing destroy_addr (or load/copy_addr [take]) of the temporary, insert a new destroy_addr - at the correct location.
This fixes a memory lifetime failure in case the copy-source is modified (actually: re-initialized) after the last use of the temporary: E.g. (before copy elimination):

copy_addr [take] %src to [initialization] %temp
%x = load %temp // last use of %temp
store %y to [init] %src
destroy_addr %temp

The correct location for the destroy_addr is after the last use (after copy elimination):

%x = load %src
destroy_addr %src
store %y to [init] %src

rdar://problem/69757314
2020-10-16 17:27:32 +02:00
Erik Eckstein
6310dfcc93 TempRValueOpt: fix the handling of load [take]
load [take] was not considered as a use and it was not detected if it's in a different basic block.
This fixes a miscompile in case there is a modification of the copy-source before a load [take].

rdar://problem/69757314
2020-10-16 16:32:48 +02:00
Erik Eckstein
7c293d8de9 TempRValueOpt: fix the handling of begin_access
Consider the related end_access instructions as uses to correctly mark the end of the lifetime of the temporary.
This fixes a miscompile in case there is a modification of the copy-source between an begin_access and end_access.
2020-10-16 16:32:48 +02:00
Erik Eckstein
d569031f1a TempRValueOpt: move the mayWrite-check for applies from collectLoads to checkNoSourceModification
... where it belongs.
This is mostly refactoring, but it also fixes a bug: we don't recurse into a begin_access in collectLoads.
If there is an apply in such a scope, the mayWrite-check wouldn't be done.
In checkNoSourceModification all instructions are visited, so the check is always done.
2020-10-16 16:32:48 +02:00
Erik Eckstein
673b8873ab TempRValueOpt: refactoring: simplify the signature of collectLoads
It's sufficient to pass the operand instead of the operand, the user and the operand value.
NFC.
2020-10-16 16:32:48 +02:00
Erik Eckstein
68db2e7c6c TempRValueOpt: don't use collectLoads in tryOptimizeStoreIntoTemp
This refactoring removes a lot of special-casing in collectLoads and also makes tryOptimizeStoreIntoTemp simpler.
It's a NFC.
2020-10-16 16:32:48 +02:00
Erik Eckstein
6c85f267bf SimplifyCFG: fix a crash caused by an unreachable CFG cycles with block arguments.
When SimplifyCFG (temporarily) produces an unreachable CFG cycle, some other transformations in SimplifyCFG didn't deal with this situation correctly.

Unfortunately I couldn't create a SIL test case for this bug, so I just added a swift test case.

https://bugs.swift.org/browse/SR-13650
rdar://problem/69942431
2020-10-15 15:04:16 +02:00
Robert Widmann
6125d25cb4 [NFC] Silence Non-Exhaustive Switch Warnings on Windows 2020-10-14 13:26:09 -07:00
Arnold Schwaighofer
b994bf3191 Add support for _specialize(exported: true, ...)
This attribute allows to define a pre-specialized entry point of a
generic function in a library.

The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.

```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```

Pre-specializations of internal `@inlinable` functions are allowed.

```
@usableFromInline
internal struct GenericThing<T> {
  @_specialize(exported: true, where T == Int)
  @inlinable
  internal func genericMethod(_ t: T) {
  }
}
```

There is syntax to pre-specialize a method from a different module.

```
import ModuleDefiningGenericFunc

@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }

```

Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).

```
import ModuleDefiningGenericThing
public struct Something {}

@_specializeExtension
extension GenericThing {
  @_specialize(exported: true, target: genericMethod(_:), where T == Something)
  func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```

rdar://64993425
2020-10-12 09:19:29 -07:00
Meghana Gupta
7cea31ba3c SILMem2Reg: Don't add dead values as phi arguments
A dealloc_stack ends the lifetime of an alloc_stack on a path. We don't
have to pass RunningVal beyond the dealloc_stack as phi argument to the
post dominating block.
2020-10-12 00:07:15 -07:00
Erik Eckstein
9f85cb8576 TempRValueElimination: handle potential modifications of the copy-source in a called functions correctly.
This fixes a miscompile in case the source of the optimized copy_addr is modified in a called function with to a not visible alias.
This can happen with class properties or global variables.

This fix removes the special handling of function parameters, which was just wrong.
Instead it simply uses the alias analysis API to check for modifications of the source object.

The fix makes TempRValueElimination more conservative and this can cause some performance regressions, but this is unavoidable.

rdar://problem/69605657
2020-10-09 20:54:59 +02:00
Joe Groff
a664a33b52 SIL: Add instructions to represent async suspend points.
`get_async_continuation[_addr]` begins a suspend operation by accessing the continuation value that can resume
the task, which can then be used in a callback or event handler before executing `await_async_continuation` to
suspend the task.
2020-10-01 14:21:52 -07:00
eeckstein
f6c008fb48 Merge pull request #34115 from eeckstein/enum-optimizations
SILOptimizer: two optimization improvements for address-only enums
2020-09-30 20:44:27 +02:00
Erik Eckstein
0a71d0fbea SimplifyCFG: allow jump-threading for switch_enum_data_addr instructions.
If the branch-block injects a certain enum case and the destination switches on that enum, it's worth jump threading. E.g.

  inject_enum_addr %enum : $*Optional<T>, #Optional.some
  ... // no memory writes here
  br DestBB
DestBB:
  ... // no memory writes here
  switch_enum_addr %enum : $*Optional<T>, case #Optional.some ...

This enables removing all code with optionals in a loop, which iterates over an array of address-only elements, e.g.

  func test<T>(_ items: [T]) {
    for i in items {
      print(i)
    }
  }
2020-09-30 16:44:58 +02:00
Michael Gottesman
d1f43032fc [ownership] Move ownership passed TempLValueOpt for the stdlib and add an ossa test case. 2020-09-29 16:36:12 -05:00
Andrew Trick
ea0da3fcdb Merge pull request #34074 from atrick/make-fieldidx-unique
Change SIL ref_element_addr getFieldNo() to return a unique index.
2020-09-25 14:38:46 -07:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Varun Gandhi
6dfdb7b548 [NFC] Clean up construction of ExtInfo(Builder). 2020-09-24 00:38:45 -07:00
Hamish Knight
cb099454d6 Allow SILGen to emit only a specific set of SILDeclRefs
Extend ASTLoweringDescriptor to store a set of
SILDeclRefs to emit through `emitFunctionDefinition`.
2020-09-15 19:20:11 +01:00