Commit Graph

2592 Commits

Author SHA1 Message Date
Doug Gregor
e7e922ea77 Introduce a createAsyncTaskInGroup SIL builtin.
Rather than using group task options constructed from the Swift parts
of the _Concurrency library and passed through `createAsyncTask`'s
options, introduce a separate builtin that always takes a group. Move
the responsibility for creating the options structure into IRGen, so
we don't need to expose the TaskGroupTaskOptionRecord type in Swift.
2021-06-24 07:53:18 -07:00
Doug Gregor
76959b1d4f Remove CreateAsyncTaskGroupFuture and swift_task_create_group_future.
We've moved everything over to `CreateAsyncTask` now.
2021-06-24 07:53:18 -07:00
Doug Gregor
a61adace85 Remove CreateAsyncTaskFuture and swift_task_create_future.
We no longer need these entry points.
2021-06-24 07:53:18 -07:00
Doug Gregor
c7edfa3ba9 Centralize non-group task creation on swift_task_create[_f].
Introduce a builtin `createAsyncTask` that maps to `swift_task_create`,
and use that for the non-group task creation operations based on the
task-creation flags. `swift_task_create` and the thin function version
`swift_task_create_f` go through the dynamically-replaceable
`swift_task_create_common`, where all of the task creation logic is
present.

While here, move copying of task locals and the initial scheduling of
the task into `swift_task_create_common`, enabling by separate flags.
2021-06-24 07:53:17 -07:00
Erik Eckstein
edc600f754 DeadObjectElimination: handle dead arrays for which the destructor is not inlined
So far, DeadObjectElimination could remove dead arrays if the destructor of the buffer is inlined and the "destroyArray" builtin is visible in the array's user list.
Now, don't rely of inlining the destructor, but instead extend the destructor analysis to find the "destroyArray".

https://bugs.swift.org/browse/SR-14774
rdar://79302972
2021-06-22 07:28:04 +02:00
Michael Gottesman
18670fc389 [assembly-vision] Rename opt remark generator to assembly vision remark generator.
TLDR: The reason why I am doing this is that often times people confuse assembly
vision remarks for normal opt remarks. I want to accentuate that this is
actually trying to do something different than a traditional opt remark. To that
end I renamed things in the compiler and added a true attribute
`@_assemblyVision` to trigger the compiler to emit these remarks to help
everyone remember what this is in their ontology. I explain below the
difference.

----

Normal opt remarks work by the optimizer telling you if it succeeded or failed
to perform an optimization. Another way of putting this is that opt remarks is
trying to give back feedback to the user from an expert system about why it did
or not do something. There is inherently an act of interpretation in the
optimizer about whether or not to report an 'action' that it perpetrated to the
user.

Assembly Vision Remarks is instead trying to be an expert tool that acts like an
xray. Instead of telling the user about what the optimizer did, it is instead a
simple visitor that visits the IR and emits SourceLocations for where specific
hazards ending up in the program. In this sense it is just telling the user
where certain instructions ended up and using heuristics to relate this to
information at the IR level. To a get a sense of this difference, consider the
following Swift Code:

```
public class Klass {
    func doSomething() {}
}

var global: Klass = Klass()

@inline(__always)
func bar() -> Klass { global }

@_assemblyVision
@inline(never)
func foo() {
  bar().doSomething()
}
```

In this case, we will emit the following remarks:

```
test.swift:16:5: remark: begin exclusive access to value of type 'Klass'
    bar().doSomething()
    ^
test.swift:7:5: note: of 'global'
var global: Klass = Klass()
    ^
test.swift:16:9: remark: end exclusive access to value of type 'Klass'
    bar().doSomething()
        ^
test.swift:7:5: note: of 'global'
var global: Klass = Klass()
    ^
test.swift:16:11: remark: retain of type 'Klass'
    bar().doSomething()
          ^
test.swift:7:5: note: of 'global'
var global: Klass = Klass()
    ^
test.swift:16:23: remark: release of type 'Klass'
    bar().doSomething()
                      ^
test.swift:7:5: note: of 'global'
var global: Klass = Klass()
    ^
```

Notice how the begin/end exclusive access are marked as actually being before
the retain, release of global. That seems weird since exclusive access to memory
seems like something that should not escape an exclusivity scope... but in fact
this corresponds directly to what we eventually see in the SIL:

```
// test.sil
sil hidden [noinline] [_semantics "optremark"] @$ss3fooyyF : $@convention(thin) () -> () {
bb0:
  %0 = global_addr @$ss6globals5KlassCvp : $*Klass
  %1 = begin_access [read] [dynamic] [no_nested_conflict] %0 : $*Klass
  %2 = load %1 : $*Klass
  end_access %1 : $*Klass
  %4 = class_method %2 : $Klass, #Klass.doSomething : (Klass) -> () -> (), $@convention(method) (@guaranteed Klass) -> ()
  strong_retain %2 : $Klass
  %6 = apply %4(%2) : $@convention(method) (@guaranteed Klass) -> ()
  strong_release %2 : $Klass
  %8 = tuple ()
  return %8 : $()
} // end sil function '$ss3fooyyF'
```

and assembly,

```
// test.S
_$ss3fooyyF:
	pushq	%rbp
	movq	%rsp, %rbp
	pushq	%r13
	pushq	%rbx
	subq	$32, %rsp
	leaq	_$ss6globals5KlassCvp(%rip), %rdi
	leaq	-40(%rbp), %rsi
	xorl	%edx, %edx
	xorl	%ecx, %ecx
	callq	_swift_beginAccess
	movq	_$ss6globals5KlassCvp(%rip), %r13
	movq	(%r13), %rax
	movq	80(%rax), %rbx
	movq	%r13, %rdi
	callq	_swift_retain
	callq	*%rbx
	movq	%r13, %rdi
	callq	_swift_release
	addq	$32, %rsp
	popq	%rbx
	popq	%r13
	popq	%rbp
	retq
```

so as one can see what we are trying to do is inform the user of hazards in the
code without trying to reason about it, automated a task that users often have
to perform by hand: inspection of assembly to determine where runtime calls and
other hazards ended up.
2021-06-12 15:09:46 -07:00
Michael Gottesman
0fccbcbba6 Merge pull request #37862 from gottesmm/pr-9969928599acd8930617276fc98b23b453906931
[opt-remark] Teach opt-remark how to emit remarks for retain/release of @_emptyArrayStorage.
2021-06-10 21:50:59 -07:00
Michael Gottesman
713e403968 [opt-remark] Teach opt-remark how to emit remarks for retain/release of @_emptyArrayStorage.
This just involved teaching opt-remark-gen how to pattern match the following
SIL:

```
%0 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage
%1 = address_to_pointer %0 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer
%2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $__EmptyArrayStorage
```

Now we produce the following remark:

```
./swift/test/SILOptimizer/opt_remark/opt_remark_generator.sil:105:3: remark: retain of type 'EmptyArrayStorage'
  strong_retain %2 : $EmptyArrayStorage // expected-remark {{retain of type 'EmptyArrayStorage'}}
  ^
./swift/test/SILOptimizer/opt_remark/opt_remark_generator.sil:42:5: note: of 'swiftEmptyArrayStorage'
var swiftEmptyArrayStorage: _SwiftEmptyArrayStorage
    ^
```
2021-06-10 08:30:29 -07:00
Erik Eckstein
6fe719624a libswift: implement the MergeCondFail pass in libswift
But keeping the old pass as legacy pass
2021-06-09 11:33:41 +02:00
Erik Eckstein
8ad3a89cc6 SILOptimizer: remove a few unused includes and declarations
NFC
2021-06-04 19:48:48 +02:00
Erik Eckstein
76ab1c37be DeadObjectElimination: use InstructionDeleter to solve the instruction iterator invalidation problem
This simplifies the instruction iteration in processFunction().
2021-06-03 17:20:56 +02:00
Andrew Trick
0407a4e34a Add UpdatingInstructionIterator.
Track in-use iterators and update them both when instructions are
deleted and when they are added.

Safe iteration in the presence of arbitrary changes now looks like
this:

    for (SILInstruction *inst : deleter.updatingRange(&bb)) {
      modify(inst);
    }
2021-06-02 07:38:27 -07:00
Andrew Trick
0f88e0f3cc Rewrite instruction deletion logic in many passes
Fix innumerable latent bugs with iterator invalidation and callback invocation.

Removes dead code earlier and chips away at all the redundant copies the compiler generates.
2021-06-02 07:38:27 -07:00
eeckstein
bb6b2712e4 Merge pull request #37668 from eeckstein/temprvalueopt-yield
TempRValueOpt: Support yield
2021-05-31 08:58:19 +02:00
Konrad `ktoso` Malawski
6008b32789 [Distributed] initial distributed support, fixed availability (#37650)
* [Distributed] Initial distributed checking

* [Distributed] initial types shapes and conform to DistributedActor

* [Distributed] Require Codable params and return types

* [Distributed] initial synthesis of fields and constructors

* [Distributed] Field and initializer synthesis

* [Distributed] Codable requirement on distributed funcs; also handle <T: Codable>

* [Distributed] handle generic type params which are Codable in dist func

[Distributed] conformsToProtocol after all

* [Distributed] Implement remote flag on actors

* Implement remote flag on actors

* add test

* actor initializer that sets remote flag

[Distributed] conformances getting there

* [Distributed] dont require async throws; cleanup compile tests

* [Distributed] do not synthesize default implicit init, only our special ones

* [Distributed] properly synth inits and properties; mark actorTransport as _distributedActorIndependent

Also:

- do not synthesize default init() initializer for dist actor

* [Distributed] init(transport:) designated and typechecking

* [Distributed] dist actor initializers MUST delegate to local-init

* [Distributed] check if any ctors in delegation call init(transport:)

* [Distributed] check init(transport:) delegation through many inits; ban invoking init(resolve:using:) explicitly

* [Distributed] disable IRGen test for now

* [Distributed] Rebase cleanups

* [Concurrent] transport and address are concurrent value

* [Distributed] introduce -enable-experimental-distributed flag

* rebase adjustments again

* rebase again...

* [Distributed] distributed functions are implicitly async+throws outside the actor

* [Distributed] implicitly throwing and async distributed funcs

* remove printlns

* add more checks to implicit function test

* [Distributed] resolve initializer now marks the isRemote actor flag

* [Distributed] distributedActor_destroy invoked instead, rather than before normal

* [Distributed] Generate distributed thunk for actors

* [distributed] typechecking for _remote_ functions existing, add tests for remote funcs

* adding one XFAIL'ed task & actor lifetime test

The `executor_deinit1` test fails 100% of the time
(from what I've seen) so I thought we could track
and see when/if someone happens to fix this bug.

Also, added extra coverage for #36298 via `executor_deinit2`

* Fix a memory issue with actors in the runtime system, by @phausler

* add new test that now passes because of patch by @phausler

See previous commit in this PR.
Test is based on one from rdar://74281361

* fix all tests that require the _remote_ function stubs

* Do not infer @actorIndependent onto `let` decls

* REVERT_ME: remove some tests that hacky workarounds will fail

* another flaky test, help build toolchain

* [Distributed] experimental distributed implies experimental concurrency

* [Distributed] Allow distributed function that are not marked async or throws

* [Distributed] make attrs SIMPLE to get serialization generated

* [Distributed] ActorAddress must be Hashable

* [Distributed] Implement transport.actorReady call in local init

* cleanup after rebase

* [Distributed] add availability attributes to all distributed actor code

* cleanup - this fixed some things

* fixing up

* fixing up

* [Distributed] introduce new Distributed module

* [Distributed] diagnose when missing 'import _Distributed'

* [Distributed] make all tests import the module

* more docs on address

* [Distributed] fixup merge issues

* cleanup: remove unnecessary code for now SIMPLE attribute

* fix: fix getActorIsolationOfContext

* [Distributed] cmake: depend on _concurrency module

* fixing tests...

* Revert "another flaky test, help build toolchain"

This reverts commit 83ae6654dd.

* remove xfail

* clenup some IR and SIL tests

* cleanup

* [Distributed] fix cmake test and ScanDependencies/can_import_with_map.swift

* [Distributed] fix flags/build tests

* cleanup: use isDistributed wherever possible

* [Distributed] don't import Dispatch in tests

* dont link distributed in stdlib unittest

* trying always append distributed module

* cleanups

* [Distributed] move all tests to Distributed/ directory

* [lit] try to fix lit test discovery

* [Distributed] update tests after diagnostics for implicit async changed

* [Distributed] Disable remote func tests on Windows for now

* Review cleanups

* [Distributed] fix typo, fixes Concurrency/actor_isolation_objc.swift

* [Distributed] attributes are DistributedOnly (only)

* cleanup

* [Distributed] cleanup: rely on DistributedOnly for guarding the keyword

* Update include/swift/AST/ActorIsolation.h

Co-authored-by: Doug Gregor <dgregor@apple.com>

* introduce isAnyThunk, minor cleanup

* wip

* [Distributed] move some type checking to TypeCheckDistributed.cpp

* [TypeCheckAttr] remove extra debug info

* [Distributed/AutoDiff] fix SILDeclRef creation which caused AutoDiff issue

* cleanups

* [lit] remove json import from lit test suite, not needed after all

* [Distributed] distributed functions only in DistributedActor protocols

* [Distributed] fix flag overlap & build setting

* [Distributed] Simplify noteIsolatedActorMember to not take bool distributed param

* [Distributed] make __isRemote not public

* [Distributed] Fix availability and remove actor class tests

* [actorIndependent] do not apply actorIndependent implicitly to values where it would be illegal to apply

* [Distributed] disable tests until issue fixed

Co-authored-by: Dario Rexin <drexin@apple.com>
Co-authored-by: Kavon Farvardin <kfarvardin@apple.com>
Co-authored-by: Doug Gregor <dgregor@apple.com>
2021-05-28 07:22:03 +09:00
Erik Eckstein
f494f370a5 TempRValueOpt: Support yield
This is one step of eliminating a copy_addr in the Array's subscript read coroutine

rdar://53996328
2021-05-27 09:59:34 +02:00
Erik Eckstein
4977850092 SIL: remove the notifyDeleteHandlers mechanism
It's not needed anymore with delayed instruction deletion.
It was used for two purposes:
1. For analysis, which cache instructions, to avoid dangling instruction pointers
2. For passes, which maintain worklists of instructions, to remove a deleted instructions from the worklist. This is now done by checking SILInstruction::isDeleted().
2021-05-26 21:57:54 +02:00
Erik Eckstein
d2fc6eb3b5 AliasAnalysis: make AliasAnalysis a function analysis and simplify the cache keys
Instead of caching alias results globally for the module, make AliasAnalysis a FunctionAnalysisBase which caches the alias results per function.
Why?
* So far the result caches could only grow. They were reset when they reached a certain size. This was not ideal. Now, they are invalidated whenever the function changes.
* It was not possible to actually invalidate an alias analysis result. This is required, for example in TempRValueOpt and TempLValueOpt (so far it was done manually with invalidateInstruction).
* Type based alias analysis results were also cached for the whole module, while it is actually dependent on the function, because it depends on the function's resilience expansion. This was a potential bug.

I also added a new PassManager API to directly get a function-base analysis:
    getAnalysis(SILFunction *f)

The second change of this commit is the removal of the instruction-index indirection for the cache keys. Now the cache keys directly work on instruction pointers instead of instruction indices. This reduces the number of hash table lookups for a cache lookup from 3 to 1.
This indirection was needed to avoid dangling instruction pointers in the cache keys. But this is not needed anymore, because of the new delayed instruction deletion mechanism.
2021-05-26 21:57:54 +02:00
Erik Eckstein
24799e1526 SIL: defer instruction deletion to the end of a pass run.
When an instruction is "deleted" from the SIL, it is put into the SILModule::scheduledForDeletion list.
The instructions in this list are eventually deleted for real in SILModule::flushDeletedInsts(), which is called by the pass manager after each pass run.
In other words: instruction deletion is deferred to the end of a pass.

This avoids dangling instruction pointers within the run of a pass and in analysis caches.
Note that the analysis invalidation mechanism ensures that analysis caches are invalidated before flushDeletedInsts().
2021-05-26 21:57:54 +02:00
Konrad `ktoso` Malawski
0c75bd2a39 Revert Initial distributed, some issues to be fixed first (#37556)
* Revert "[Distributed] disable tests until issue fixed"

This reverts commit 0a04278920.

* Revert "[Distributed] Initial `distributed` actors and functions and new module (#37109)"

This reverts commit 814ede0cf3.
2021-05-21 19:28:48 +09:00
eeckstein
d001b1da06 Merge pull request #37473 from eeckstein/aliasanalysis-immutable-scopes
AliasAnalysis: check for immutable scopes.
2021-05-21 08:28:55 +02:00
Konrad `ktoso` Malawski
814ede0cf3 [Distributed] Initial distributed actors and functions and new module (#37109)
* [Distributed] Initial distributed checking

* [Distributed] initial types shapes and conform to DistributedActor

* [Distributed] Require Codable params and return types

* [Distributed] initial synthesis of fields and constructors

* [Distributed] Field and initializer synthesis

* [Distributed] Codable requirement on distributed funcs; also handle <T: Codable>

* [Distributed] handle generic type params which are Codable in dist func

[Distributed] conformsToProtocol after all

* [Distributed] Implement remote flag on actors

* Implement remote flag on actors

* add test

* actor initializer that sets remote flag

[Distributed] conformances getting there

* [Distributed] dont require async throws; cleanup compile tests

* [Distributed] do not synthesize default implicit init, only our special ones

* [Distributed] properly synth inits and properties; mark actorTransport as _distributedActorIndependent

Also:

- do not synthesize default init() initializer for dist actor

* [Distributed] init(transport:) designated and typechecking

* [Distributed] dist actor initializers MUST delegate to local-init

* [Distributed] check if any ctors in delegation call init(transport:)

* [Distributed] check init(transport:) delegation through many inits; ban invoking init(resolve:using:) explicitly

* [Distributed] disable IRGen test for now

* [Distributed] Rebase cleanups

* [Concurrent] transport and address are concurrent value

* [Distributed] introduce -enable-experimental-distributed flag

* rebase adjustments again

* rebase again...

* [Distributed] distributed functions are implicitly async+throws outside the actor

* [Distributed] implicitly throwing and async distributed funcs

* remove printlns

* add more checks to implicit function test

* [Distributed] resolve initializer now marks the isRemote actor flag

* [Distributed] distributedActor_destroy invoked instead, rather than before normal

* [Distributed] Generate distributed thunk for actors

* [distributed] typechecking for _remote_ functions existing, add tests for remote funcs

* adding one XFAIL'ed task & actor lifetime test

The `executor_deinit1` test fails 100% of the time
(from what I've seen) so I thought we could track
and see when/if someone happens to fix this bug.

Also, added extra coverage for #36298 via `executor_deinit2`

* Fix a memory issue with actors in the runtime system, by @phausler

* add new test that now passes because of patch by @phausler

See previous commit in this PR.
Test is based on one from rdar://74281361

* fix all tests that require the _remote_ function stubs

* Do not infer @actorIndependent onto `let` decls

* REVERT_ME: remove some tests that hacky workarounds will fail

* another flaky test, help build toolchain

* [Distributed] experimental distributed implies experimental concurrency

* [Distributed] Allow distributed function that are not marked async or throws

* [Distributed] make attrs SIMPLE to get serialization generated

* [Distributed] ActorAddress must be Hashable

* [Distributed] Implement transport.actorReady call in local init

* cleanup after rebase

* [Distributed] add availability attributes to all distributed actor code

* cleanup - this fixed some things

* fixing up

* fixing up

* [Distributed] introduce new Distributed module

* [Distributed] diagnose when missing 'import _Distributed'

* [Distributed] make all tests import the module

* more docs on address

* [Distributed] fixup merge issues

* cleanup: remove unnecessary code for now SIMPLE attribute

* fix: fix getActorIsolationOfContext

* [Distributed] cmake: depend on _concurrency module

* fixing tests...

* Revert "another flaky test, help build toolchain"

This reverts commit 83ae6654dd.

* remove xfail

* clenup some IR and SIL tests

* cleanup

* [Distributed] fix cmake test and ScanDependencies/can_import_with_map.swift

* [Distributed] fix flags/build tests

* cleanup: use isDistributed wherever possible

* [Distributed] don't import Dispatch in tests

* dont link distributed in stdlib unittest

* trying always append distributed module

* cleanups

* [Distributed] move all tests to Distributed/ directory

* [lit] try to fix lit test discovery

* [Distributed] update tests after diagnostics for implicit async changed

* [Distributed] Disable remote func tests on Windows for now

* Review cleanups

* [Distributed] fix typo, fixes Concurrency/actor_isolation_objc.swift

* [Distributed] attributes are DistributedOnly (only)

* cleanup

* [Distributed] cleanup: rely on DistributedOnly for guarding the keyword

* Update include/swift/AST/ActorIsolation.h

Co-authored-by: Doug Gregor <dgregor@apple.com>

* introduce isAnyThunk, minor cleanup

* wip

* [Distributed] move some type checking to TypeCheckDistributed.cpp

* [TypeCheckAttr] remove extra debug info

* [Distributed/AutoDiff] fix SILDeclRef creation which caused AutoDiff issue

* cleanups

* [lit] remove json import from lit test suite, not needed after all

* [Distributed] distributed functions only in DistributedActor protocols

* [Distributed] fix flag overlap & build setting

* [Distributed] Simplify noteIsolatedActorMember to not take bool distributed param

* [Distributed] make __isRemote not public

Co-authored-by: Dario Rexin <drexin@apple.com>
Co-authored-by: Kavon Farvardin <kfarvardin@apple.com>
Co-authored-by: Doug Gregor <dgregor@apple.com>
2021-05-21 09:12:29 +09:00
Erik Eckstein
4affa11604 OwnershipUtils: let visitTransitiveEndBorrows work with a BorrowedValue.
... and not only with a begin_borrow
2021-05-18 08:56:22 +02: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
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
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
Alejandro Alonso
444c35cf8d Merge pull request #36953 from Azoy/isType-isDeclType
[NFC] Introduce isDecl and getDeclType
2021-04-20 15:33:00 -04: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
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
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
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
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
Arnold Schwaighofer
ddfdf4779d Revert "SIL: add a StackList data structure with zero cost operations." 2021-04-12 12:48:16 -07: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
Michael Gottesman
aaffd9aef7 [mem2reg] Make style consistently new swift style before adding support for borrows.
This is code that was written at the very beginning of Swift and has some early
style remaining interspirsed with newer swift style code. Since I am going to be
touching this and I don't expect other people to touch it for a while, I am
fixing up the formatting/reorganizing rather than leaving the style inconsistent.
2021-04-09 13:40:47 -07:00
John McCall
efeb818161 Clean up the TaskGroup ABI:
- stop storing the parent task in the TaskGroup at the .swift level
- make sure that swift_taskGroup_isCancelled is implied by the parent
  task being cancelled
- make the TaskGroup structs frozen
- make the withTaskGroup functions inlinable
- remove swift_taskGroup_create
- teach IRGen to allocate memory for the task group
- don't deallocate the task group in swift_taskGroup_destroy

To achieve the allocation change, introduce paired create/destroy builtins.

Furthermore, remove the _swiftRetain and _swiftRelease functions and
several calls to them.  Replace them with uses of the appropriate builtins.
I should probably change the builtins to return retained, since they're
working with a managed type, but I'll do that in a separate commit.
2021-04-09 03:06:31 -04:00
Stephen Canon
511b50e511 Implement shufflevector builtin. (#36650)
This isn't _terribly_ useful as-is, because the only constant mask you can get at from Swift at present is the zeroinitializer, but even that is quite useful for optimizing the repeating: intializer on SIMD. At some future point we should wire up generating constant masks for the .even, .odd, .high and .low properties (and also eventually make shufflevector take non-constant masks in LLVM). But this is enough to be useful, so let's get it in.
2021-04-04 23:23:53 -04:00
Erik Eckstein
f3d1c34eb5 StringOptimization: don't constant fold dynamic Self type names.
This wrongly results in "Self" instead of the real type name.

rdar://76113269
2021-04-02 08:41:01 +02:00
Michael Gottesman
2e32a7cd64 Merge pull request #36632 from gottesmm/opt_remark_runtime_cast_remark
[opt-remark] Add support for emitting remarks about runtime casts.
2021-03-31 18:30:28 -07:00
Michael Gottesman
753f7ab8f3 [opt-remark] Add remarks for casts that go through the runtime and aren't optimized away.
Now we get opt-remarks like the following:

```
public func condCast5<NS, T>(_ ns: NS) -> T? {
  // Make sure the colon info is right so that the arrow is under the a.
  //
  // Today, we lose that x was assigned.
  if let x = ns as? T {  // expected-remark @:17 {{conditional runtime cast of value with type 'NS' to 'T'}}
    return x             // expected-note @-5:32 {{of 'ns'}}
  }
  return nil
}
```
2021-03-30 18:58:27 -07:00