Commit Graph

6319 Commits

Author SHA1 Message Date
eeckstein
cf2c052628 Merge pull request #37315 from eeckstein/fix-abc-opt
ArrayBoundCheckOpts: introduce a limit for the maximum dominator tree recursion depth
2021-05-10 09:15:04 +02:00
John McCall
12a4d471c0 In DI, cache whether a memory object is a box.
Boxes tend to have a small number of uses, so frequently finding the
unique projection isn't too bad.  Non-boxes, however, can have a large
number of uses: for example, a class instance has expected uses
proportionate to the number of stored properties.  So if we do a linear
scan of the uses on a non-box instruction, we'll scale quadratically.

Fixes SR-14532.
2021-05-07 18:50:00 -04:00
Erik Eckstein
2a17d9a480 ArrayBoundCheckOpts: introduce a limit for the maximum dominator tree recursion depth
This is a quick fix for a stack overflow in case of very large functions.
TODO: Ideally this algorithm would be implemented as an iterative worklist algorithm.

rdar://77563057
2021-05-07 18:13:08 +02:00
Andrew Trick
b0dc18dd04 Fix an assert in exclusivity diagnostics when inouts escape.
An error found in DiagnoseInvalidEscapingCaptures can indicate invalid
SIL, which will cause DiagnoseStaticExclusivity to assert during SIL
verification. When the source-level closure captures an inout
argument, it appears in SIL to be a non-escaping closure. The SIL
verification then fails because the "nonescaping" closure actually
escapes.

Ensure that capture diagnostics run on closures before exclusivity
enforcement runs on the parent function. Bypass the SIL verification
assert if a diagnostic error was found.

Fixes rdar://75364904 (Crash with assertion `noescape partial_apply
has unexpected use`)
2021-05-05 17:06:30 -07:00
Michael Gottesman
617a0279fc Merge pull request #37208 from gottesmm/canonicalize-ossa-lifetimes-sil-combine
[sil-combine] Use canonicalizeOSSALifetimes to eliminate unnecessary copies inserted due to RAUWing
2021-05-04 09:52:31 -07:00
adrian-prantl
c472ce492c Merge pull request #37123 from adrian-prantl/75905336
Expose the LowerHopToActorPass as API so LLDB can schedule it
2021-05-03 10:51:39 -07:00
Michael Gottesman
e670d2b4de [sil-combine] Canonicalize copies using canonicalizeOSSALifetimes when moving newly created instructions into the worklist.
To be more explicit, canonicalizeOSSALifetimes is a utility that
re-canonicalizes all at once a set of defs that the caller found by applying
CanonicalizeOSSALifetime::getCanonicalCopiedDef(copy)). The reason why I am
doing this is that when we RAUW in OSSA, we sometimes insert additional copies
to make the problem easier for a utility to handle. This lets us canonicalize
away any copies before we even leave the pass.
2021-05-01 16:02:21 -07:00
Michael Gottesman
387806b9c6 [ownership] Add a simple helper wrapper called canonicalizeOSSALifetimes around CanonicalizeOSSALifetime that clean up extra copies inserted when RAUWing or promoting loads.
Based on code in CopyPropagation. It is assumed that the passed in set of defs
is unique and that all such defs were found by using
CanonicalizeOSSALifetime::getCanonicalCopiedDef(copy).
2021-05-01 16:01:45 -07:00
Michael Gottesman
3ab207c303 [copy-propagation] Finish plumbing through InstModCallbacks into one deletion utility that I missed. 2021-05-01 15:58:06 -07:00
Erik Eckstein
bd5d4276cd SILCombine: fix keypath optimization with optional chaining and classes
For optional chaining a swift_enum is created.
If the sub-projection is ending a begin_access in the some-branch, it also needs to be ended in the none-branch.

Fixes a compiler crash and/or a miscompile.

https://bugs.swift.org/browse/SR-14534
rdar://77224220
2021-04-30 21:47:42 +02: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
186c53000d Introduce basic support for custom executors.
- Introduce an UnownedSerialExecutor type into the concurrency library.
- Create a SerialExecutor protocol which allows an executor type to
  change how it executes jobs.
- Add an unownedExecutor requirement to the Actor protocol.
- Change the ABI for ExecutorRef so that it stores a SerialExecutor
  witness table pointer in the implementation field.  This effectively
  makes ExecutorRef an `unowned(unsafe) SerialExecutor`, except that
  default actors are represented without a witness table pointer (just
  a bit-pattern).
- Synthesize the unownedExecutor method for default actors (i.e. actors
  that don't provide an unownedExecutor property).
- Make synthesized unownedExecutor properties `final`, and give them
  a semantics attribute specifying that they're for default actors.
- Split `Builtin.buildSerialExecutorRef` into a few more precise
  builtins.  We're not using the main-actor one yet, though.

Pitch thread:
  https://forums.swift.org/t/support-custom-executors-in-swift-concurrency/44425
2021-04-30 03:11:56 -04:00
Erik Eckstein
5a7615444b DeadObjectAllocation: fix a use-after free crash
The optimization tried to optimized a keypath instruction which was already deleted in a previous iteration.

rdar://77180080
2021-04-29 18:59:12 +02:00
Adrian Prantl
38b2660043 Expose the LowerHopToActorPass as API so LLDB can schedule it
rdar://75905336
2021-04-28 18:16:22 -07:00
Pavel Prokofyev
f8baffafc8 [NFC][AutoDiff] Pass AutoDiffConfig by const ref. (#37074) 2021-04-27 13:40:18 -07:00
Michael Gottesman
b6bfea1f39 [sil-optimizer] Get rid of the InstModCallback constructors in favor of onDelete/onCreatedNewInst/etc.
Without this when constructing an InstModCallback it is hard to distinguish
which closure is meant for which operation when passed to the constructor of
InstModCallback (if this was in Swift, we could use argument labels, but we do
not have such things in c++).

This new value type sort of formulation makes it unambiguous which callback is
used for what when constructing one of these.
2021-04-26 23:33:33 -07:00
Michael Gottesman
5900a0fdac Merge pull request #37016 from gottesmm/pr-eb1b4b484d8990f6f5cb6706dba952b3e27cdc59
[sil-optimizer] Make InstructionDeleter and related APIs to use an InstModCallback instead of a notification callback.
2021-04-26 21:03:26 -07:00
Michael Gottesman
7b55cbc669 [sil-optimizer] Make InstructionDeleter and related APIs to use an InstModCallback instead of a notification callback.
I recently have been running into the issue that many of these APIs perform the
deletion operation themselves and notify the caller it is going to delete
instead of allowing the caller to specify how the instruction is deleted. This
causes interesting semantic issues (see the loop in deleteInstruction I
simplified) and breaks composition since many parts of the optimizer use
InstModCallbacks for this purpose.

To fix this, I added a notify will be deleted construct to InstModCallback. In a
similar way to the rest of it, if the notify is not set, we do not call any code
implying that we should have good predictable performance in loops since we will
always skip the function call.

I also changed InstModCallback::deleteInst() to notify before deleting so we
have a default safe behavior. All previous use sites of this API do not care
about being notified and the only new use sites of this API are in
InstructionDeleter that perform special notification behavior (it notifies for
certain sets of instructions it is going to delete before it deletes any of
them). To work around this, I added a bool to deleteInst to control this
behavior and defaulted to notifying. This should ensure that all other use sites
still compose correctly.
2021-04-26 16:37:43 -07:00
Pavel Prokofyev
eca2801229 [SR-13929][AutoDiff]: Enable [ossa] for all differentiation-generated thunks (#37054)
* [SR-13929][AutoDiff]: Enable [ossa] for Differentiation/Thunk.cpp:getOrCreateSubsetParametersThunkForLinearMap and promoteCurryThunkApplicationToDifferentiableFunction
2021-04-26 12:17:46 -07:00
Michael Gottesman
c3c2b84e48 [ownership] Change CanonicalOSSALifetime to use an InstModCallback.
This enables passes to use this as a utility that properly composes with how the
pass maintains its state. If an InstModCallback isn't passed in, we use the
default InstModCallback which should be cheap (always succeeding check for
nullptr + call inline default callback).
2021-04-21 22:09:55 -07:00
Andrew Trick
ed8b1b25dd Merge pull request #36970 from atrick/destructure-conversion
CanonicalizeOSSA: Destructure canonicalization and conslidate borrow scope support for destructure
2021-04-21 19:50:00 -07:00
Andrew Trick
340feb41df CanonicalOSSALifetime: rewrite consolidateBorrowScope
It now handles looking through forwarding consumes such as
destructures.

Expected to be NFC since borrow consolidation is still disabled by
default.

TODO: Write unit tests for various forwarding consumes in addition to
destructure.
2021-04-21 14:39:48 -07:00
Richard Wei
7e2d23896f Merge pull request #36974 from integralpro/SR-14290
[AutoDiff] Use correct debug scope for pullback trampoline block.
2021-04-21 01:02:05 -07:00
Erik Eckstein
48ca690d88 ClosureLifetimeFixup: support the startAsyncLet builtin.
When the closure of startAsyncLet is no-escaping, the captured values (= the partial_apply arguments) must be kept alive until the endAsyncLet builtin.
ClosureLifetimeFixup adds the generated mark_dependence as a second operand to endAsyncLet, which keeps all the arguments alive until this point.
2021-04-20 21:38:14 +02:00
Alejandro Alonso
444c35cf8d Merge pull request #36953 from Azoy/isType-isDeclType
[NFC] Introduce isDecl and getDeclType
2021-04-20 15:33:00 -04:00
Pavel Prokofyev
841618ea70 [AutoDiff] Use correct debug scope for pullback trampoline block.
Fixes:
[[SR-14290]: SIL verification fails when differentiating a function of [[Double]]](rdar://74876596)
[[SR-14298]: [AutoDiff] SIL verification failed: non-contiguous lexical scope at -Onone](rdar://75032457)
2021-04-20 12:10:54 -07:00
Luciano Almeida
ddeb1929c4 [DiagnosticQol][SR-14505] Use DeclDescriptive kind in missing return data flow diagnostics (#36952)
* [Diagnostics] Use DeclDescriptiveKind on data flow diagnostics to improve diagnostic message

* [tests] Add regression tests to SILOptimizer/return.swift

* [tests] Adapt other tests to changes of SR-14505

* [Diagnostics] Adapt message for missing return diagnostics, remove article

* [Diagnostics] Adapt message for missing return diagnostics to have a note with fix

* [tests] Adjust tests in validation suit
2021-04-20 08:16:32 -03:00
Andrew Trick
3c045a85d5 CanonicalOSSALifetime: Add convertExtractToDestructure utility
struct_extract and tuple_extract do not belong in OSSA (except to
workaround certain extreme cases). They completely defeat
simplification that OSSA provides for optimizing owned lifetimes.

Copy propagation uses this utility to canonicalize owned values before
canonicalizing their lifetime.
2021-04-19 23:26:16 -07:00
Azoy
9ed732f0ab Introduce isDecl and getDeclType
fix enum logic issue

fix tests

guard against null types
2021-04-20 02:22:16 -04:00
Konrad `ktoso` Malawski
64da78ca76 Merge branch 'main' into wip-cleaner-abi-asynclet 2021-04-20 10:40:22 +09:00
Michael Gottesman
8b9d7ae36b Merge pull request #36956 from gottesmm/pr-970ffad9db66fdff542712db9c300fa9fbe3d98f
[silmem2reg] Compute DomTreeLevels lazily.
2021-04-19 12:21:18 -07:00
Konrad `ktoso` Malawski
d3c5ebc9b7 [AsyncLet] reimplemented with new ABI and builtins 2021-04-19 10:06:23 +09:00
Konrad `ktoso` Malawski
ba615029c7 [Concurrency] Store child record when async let child task spawned 2021-04-19 10:06:23 +09:00
Michael Gottesman
8821621647 [silmem2reg] Compute DomTreeLevels lazily.
We previously were computing this eagerly meaning that if we did not actually
need the DomTreeLevel map, we would calculate it and additionally incur a
relatively large malloc for the DenseMap (which stores by default IIRC 64 key
value pairs).

Now, we do it lazily ensuring that we only compute this if we actually need it
(when promoting non-single block stack allocations).
2021-04-18 11:56:47 -07:00
Doug Gregor
26551b16e6 [SIL] Fix egregious errors in extract_executor handling.
Make sure it is properly treated as a SingleValueInstruction, and
don't blatantly read freed memory in the LowerHopToExecutor pass.
2021-04-14 23:33:51 -07:00
Michael Gottesman
8c9d4020e3 Merge pull request #36913 from gottesmm/pr-45e4affc7e9132e241abc77bc7eef73664feef8a
[sil-mem2reg] Add a simple scope data structure and use it to simplify some code.
2021-04-14 19:54:03 -07:00
Michael Gottesman
07b568d2d3 Merge pull request #36914 from gottesmm/pr-50f9fe327da8081f9050c5c892eb164aec334530
[ownership] Refactor out the composition type LoadOperation from CanonicalizeInstruction into OwnershipOptUtils.
2021-04-14 17:37:56 -07:00
Michael Gottesman
5019e1578f [ownership] Refactor out the composition type LoadOperation from CanonicalizeInstruction into OwnershipOptUtils.
This API is useful when writing compiler code that needs to handle ossa/non-ossa
as well as load_borrow/load while in OSSA. I am going to use this in
SILMem2Reg.
2021-04-14 11:43:20 -07:00
Michael Gottesman
c0e31d8dfc [sil-mem2reg] Add a simple scope data structure and use it to simplify some code.
We have for a long time talked about creating a scope like data structure for
use in the SILOptimizer. The discussion was whether or not to reuse the
infrastructure in SILGen that does this already. There were concerns about doing
so since the code in the SILOptimizer and SILGen can work differently.

With that in mind, I added a small AssertingScope class and built on top of that
a composition SIL level class called SILOptScope that one can use to add various
cleanups. One is able to both destructively pop at end of scope and pop along
early exits.

At an implementation level, I kept it simple and:

1. Represented a scope as a stack of Optional<Cleanup> which are just a wrapper
   around a std::function. The Optional is so that we can invalidate a cleanup.
2. Based all of these scopes around the idea that the user of the scope must
   invalidate the scope by hand. If not, the scope object will assert at the end
   of its RAII scope.
3. Rather than creating a whole class hierarchy, I just used std::function
   closures to keep things simple.
2021-04-14 11:42:31 -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
Doug Gregor
f7fb5a1a9f Merge pull request #36874 from DougGregor/dynamic-data-race-actor-isolation
[Concurrency] Introduce runtime detection of data races.
2021-04-13 14:56:02 -07:00
Erik Eckstein
b3a7792d1d Reinstate "SIL: add a StackList data structure with zero cost operations."
... with a fix for a non-assert build crash: I used the wrong ilist type for SlabList. This does not explain the crash, though. What I think happened here is that llvm miscompiled and put the llvm_unreachable from the Slab's deleteNode function unconditionally into the SILModule destructor.
Now by using simple_ilist, there is no need for a deleteNode at all.
2021-04-13 13:49:45 +02:00
Michael Gottesman
7d5178b1d7 [sil-mem2reg] Rather than pass around a shared builder, pass around a shared SILBuilderContext.
This is a pretty old style of code that we are trying to move away from.
Specifically, we use to always store a global SILBuilder and manually manipulate
its insertion point/other state when we moved places. This was very bugprone so
we instead now create new SILBuilders when we want to create instructions at a
new insertion point and pass down a SILBuilderContext for global state (like the
list of inserted instructions/etc) to each SILBuilder.

I went through and updated all of the code to now follow this pattern.
2021-04-12 18:10:42 -07:00
Doug Gregor
e77a27e8ed [Concurrency] Introduce runtime detection of data races.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.

Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:

  0 - disable checking
  1 - warn when a data race is detected
  2 - error and abort when a data race is detected

At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.

The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
2021-04-12 15:19:51 -07:00
Arnold Schwaighofer
ddfdf4779d Revert "SIL: add a StackList data structure with zero cost operations." 2021-04-12 12:48:16 -07:00
eeckstein
e4f406d330 Merge pull request #36862 from eeckstein/remove-mv-result-nodes
SIL: remove the sub-classes of MultipleValueInstructionResult
2021-04-12 08:23:08 +02:00
Erik Eckstein
09755659a1 SIL: remove the sub-classes of MultipleValueInstructionResult
They are not really needed, because they don't contain any stored properties and for isa-checks we can check the parent instruction.
2021-04-11 19:14:34 +02:00
Erik Eckstein
0456d95cb0 SIL: Use StackList in BasicBlockWorklist and BasicBlockSetVector
plus: I moved both data structures into a separate header file.
2021-04-11 14:07:26 +02:00
John McCall
2e8a19cdaf Merge pull request #36838 from rjmccall/task-group-abi-cleanup
Clean up the TaskGroup ABI
2021-04-09 20:15:41 -04:00
Michael Gottesman
9f08ae8d9b [mem2reg] Reorganize code into a utilities section, a single stack alloc promotion, and a generalized MemoryToRegisters.
This code organization already existed in the file in content, but all of the
routines were mixed together. This splits the code by topic providing to the eye
easy code locality when reading.
2021-04-09 13:40:47 -07:00