Commit Graph

2610 Commits

Author SHA1 Message Date
Meghana Gupta
c46acc0f9c OSSA: SimplifyCFG. Only jump thread for trivial dest block args.
Support for non-trivial args will be added separately.
2021-07-17 18:31:25 -07:00
Andrew Trick
8a45b5fa2c OSSA: Support SimplifyCFG tryJumpThreading for testing.
This will be gated by a testing flag while tests are staged in.
2021-07-17 18:31:25 -07:00
Andrew Trick
459271d58b Fix ArrayElementPropagation handling of negative index
Convert an incorrect assert into correct code.

Fixes rdar://80444607 (Swift compiler segfault on “[1][-1]”)
2021-07-13 19:43:47 -07:00
Andrew Trick
cd55abba2c Merge pull request #38220 from atrick/rewrite-borrow-forward
Copy propagation redesign and the CanonicalizeBorrowScopes utility
2021-07-11 19:05:56 -07:00
Meghana Gupta
51ca7a1c9f Merge pull request #38315 from meg-gupta/dceendlifetime
Add support for end_lifetime in DCE
2021-07-09 19:16:06 -07:00
Michael Gottesman
398d07fade Merge pull request #38321 from gottesmm/pr-133b8c9dd74d4509715057594806f34d67caf2a0
[assembly-vision] If a nominal type is marked with @_assemblyVision emit AssemblyVisionRemarks for all of the nominal type's methods.
2021-07-08 20:25:00 -07:00
Meghana Gupta
5cb144f2d7 Merge pull request #38265 from meg-gupta/alternatemem2regfix2
Cleanup dead phis in SILMem2Reg for OSSA
2021-07-08 15:11:36 -07:00
Michael Gottesman
79211d4869 [assembly-vision] If a nominal type is marked with @_assemblyVision emit AssemblyVisionRemarks for all of the nominal type's methods.
This is implemented by checking if a function has a self parameter and if the
self parameter is a nominal type, checking for the relevant attribute.
2021-07-08 15:08:38 -07:00
Meghana Gupta
0d16eda695 Add support for end_lifetime in DCE 2021-07-08 13:53:03 -07:00
Meghana Gupta
dc57d6b3e9 Disable Mem2Reg in ossa for alloc_stack [dynamic_lifetime]
With such alloc_stack we can pass over-consumed values to a
proactively added phi. Even though such a SIL does not have
issues at runtime, they raise an ownership verification error.
2021-07-08 00:33:23 -07:00
Meghana Gupta
42863d4090 Cleanup dead phis in SILMem2Reg for OSSA
Mem2Reg creates phis proactively that may be unnecessary.
Unnecessary phis are those without uses or operands to other
proactive phis that are unnecessary.

Even though this does not translate to a real issue at runtime, we can
see ownership verification errors. This PR identifies such phis and deletes them.
2021-07-08 00:33:18 -07:00
Erik Eckstein
88a74a288c StringOptimization: optimize interpolated C strings.
Optimize code like:

   puts("\(String.self)")

Optimizing string interpolation and optimizing C-strings are both done in StringOptimization.
A second run of the StringOptimization is needed in the pipeline to optimize such code, because the result of the interpolation-optimization must be cleaned up so that the C-String optimization can kick in.

Also, StringOptimization must handle struct_extract(struct(literal)), where the struct_extract may be in a called function.
To solve a phase ordering problem with inlining String semantics and inlining the `String(stringInterpolation: DefaultStringInterpolation)` constructor, we do a simple analysis of the callee. Doing this simple "interprocedural" analysis avoids relying on inlining that String constructor.

rdar://74941849
2021-07-06 16:25:03 +02:00
Meghana Gupta
2c3f1ac7e7 Rename misleading using BlockSet to BlockSetVector 2021-07-05 17:05:43 -07:00
OneUpWallStreet
25df5d2c48 Fixed some common grammatical errors in the comments. (#38248) 2021-07-05 01:00:48 -07:00
Michael Gottesman
37be1f2f85 Merge pull request #38217 from gottesmm/pr-4acf599c8ec4a79b006ea0873129b68adb749de1
[assembly-vision] Change release to do backwards then forwards when inferring source locs.
2021-07-02 22:10:34 -07:00
Michael Gottesman
804bcac1e6 [assembly-vision] Change release to do backwards then forwards when inferring source locs.
TLDR: I fixed a whole in the assembly-vision opt-remark pass where we were not
emitting a remark for end of scope instructions at the beginning of blocks. Now
all of these instructions (strong_release, end_access) should always reliably
have a remark emitted for them.

----

I think that this is a pragmatic first solution to the problem of
strong_release, release_value being the first instruction of a block. For those
who are unaware, this issue is that for a long time we have searched backwards
first for "end of scope" like instructions. This then allows us to identify the
"end of scope" instruction as happening at the end of the previous statement
which is where the developer thinks it should be:

```
var global: Klass
func bar() -> @owned Klass { global }
func foo() {
   // We want the remark for the
   bar()                          // expected-remark {{retain}}
}
```

This makes sense since we want to show end of scope instructions as being
applied to the earlier code whose scope it is ending. We can be clear that it is
at the end of the statement by placing the carrot on the end of statement
SourceLoc so there isn't any confusion upon whether or not

That generally has delivered nice looking results, but what if our release is
the first instruction in the block? In that case, we do not have any instruction
that we can immediately use, so traditionally we just gave up and didn't emit
anything. This is not an acceptable solution! We should be able to emit
something for every retain/release in the program if we want users to be able to
rely upon this! Thus we need to be able to get source location information from
somewhere around

First before we begin, my approach here is informed by my seeing over time that
the optimizer does a pretty good job of not breaking SourceLoc info for
terminators.

With that in mind, there are two possible approaches here: using the terminator
from the previous block and searching forward at worst taking the SourceLoc of
the current block's terminator (or earlier if we find a good SourceLoc). I
wasn't sure what the correct thing to do was at the time so I didn't fix the
issue. After some thought, I realized that the correct solution is to if we fail
a backwards search, search forwards. The reason why is that since our remarks
runs late in the optimization pipeline, there is a very high likelihood that if
we aren't folded into our previous block that there is a true need in the
program for conditional control flow here. We want to avoid placing the release
out of such pieces of code since it is misleading to the user:

```

In this example there is a release inside the case for .x but none for .y. In
that case it is possible that we get a release for .f since payload is passed in
at +1 at SILGen time. In such a case, using the terminator of the previous block
would mean that we would have the release be marked as on payload instead of
inside the case of .x. By using the terminator of the releases block, we can

switch payload {
case let .x(f):
  ...
case let .y:
  ...
}
```

So using the terminator from the previous block would be
  misleading to the user. Instead it is better to pick a location after the release that way
  we know at least the instruction we are inferring from must in some sense be

With this fix, we should not emit locations for all retains, releases. We may
not identify a good source loc for all of them, but we will identify them.

optimization pipeline, if our block was not folded into the previous block there
is a very high liklihood that there is some sort of conditional control flow
that is truly necessary in the program. If we

this
generally implies that there is a real side effect in the program that is
requiring conditional code execution (since the optimizer would have folded it).

The reason why is that we are at least going to hit a terminator or a
side-effect having instruction that generally have debug info preserved by the
optimizer.
2021-07-02 11:51:09 -07:00
Andrew Trick
2c6d5afd28 Copy propagation redesign
This rewrites functionality that was mostly disabled but is now ready
to be enabled.

Allow lifetime canonicalization of owned values and function arguments
as a simple stand-alone utility. This is now being called from within
SILCombine, so we should only do the kind of canonicalization that
makes sense in that context.

Canonicalizing other borrow scopes should *not* be invoked as a
single-value cleanup because it affects other lifetimes outside the
borrow scope boundary. It is a somewhat complicated process that
hoists and sinks forwarding instructions and can generate surrounding
compensation code. The copy propagation pass knows how to post-process
the related lifetimes in just the right order. So borrow scope
rewriting should only be done in the copy propagation pass.

Similarly, only do simple canonicalization of owned values and
function arguments at -Onone.

The feature to canoncalize borrow scopes is now ready to be
enabled (-canonical-ossa-rewrite-borrows), but flipping the switch
should be a separate commit. So most of the functionality that was
affected is not exposed by this PR.

Changes:

Split canonicalization of owned lifetimes vs. borrowed lifetimes into
separate utilities. The owned lifetime utility is now back to being
the simple utility that I originally envisioned. So not much happened
to it other than removing complexity.

We now have a separate entry point for finding the starting point for
rewriting borrow scopes:
CanonicalizeBorrowScope::getCanonicalBorrowedDef.

We now have a utility that defines forwarding instructions that we can
treat consistently as part of a guaranteed lifetime,
CanonicalizeBorrowScope::isRewritableOSSAForward.

We now have a utility that defines the uses of a borrowed value that
are considered part of its lifetime,
CanonicalizeBorrowScope::visitBorrowScopeUses. This single utility is
used to implement three different parts of the alogrithm:

1. Find any uses of the borrowed value that need to be propagated
outside the borrow scope

2. RewriteInnerBorrowUses for SILFunction arguments and borrow scopes
with no outer uses.

3. RewriteOuterBorrowUses for borrow scopes with outer uses. Handling
these involves creating new copies outside the borrow scope and
hoisting forwarding instructions.

The end result is that a lot of borrow scopes can be eliminated and
owned values can be forwarded to destructures, reducing copies and
destroys.

If we stop generating borrow scopes for all interior pointers, then
we'll need to design a comparable optimization that works on
"implicit" borrow scopes:

  %ownedDef = ...
  %element struct_extract %ownedDef
  %copy = copy_value %element
  apply(@guaranteed %element)
  apply(@owned %copy)
  destroy %ownedDef

Should be:

  %ownedDef = ...
  %borrowedElement = destructure_struct @guaranteed %ownedDef
  apply(@guaranteed %borrowedElement)
  %ownedElement = destructure_struct %ownedDef
  apply(@owned %copy)
2021-07-01 21:17:27 -07:00
Meghana Gupta
7a35c478b6 CSE: While optimizing lazy property getters, don't inline non-ossa to ossa function (#38184)
Fixes rdar://79781904
2021-07-01 16:44:57 -07:00
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