The specific problem here is that we are setting the insertion point of a
SILBuilder and not unsetting it. I fixed the problem by creating a separate
builder so the original builder stays put.
I originally came across this in my work on moving ownership stripping after the
diagnostic passes. This patch fixes it without my other changes to ease
cherry-picking to 5.1.
I also added more test coverage by expanding the test case to also handle
copy_on_success and take_always.
rdar://51093557
If the keypath argument of a keypath access function is a keypath literal instruction, generate the projection inline and remove the access function.
For example, replaces (simplified SIL):
%kp = keypath ... stored_property #Foo.bar
apply %keypath_runtime_function(%root_object, %kp, %addr)
with:
%addr = struct_element_addr %root_object, #Foo.bar
load/store %addr
Currently this only handles stored property patterns.
rdar://problem/36244734
Previously, any function marked [dynamically_replaceable] that was
partially applied and captured by address would not be diagnosed.
This is a rare thing. For example:
struct S {
var x = 0
public mutating func testCallDynamic() {
dynamic func bar(_ i: inout Int) {
i = 1
x = 2
}
bar(&x)
}
}
Fixes <rdar://problem/50972786> Fix exclusivity diagnostics to be
aware of [dynamically_replaceable].
As a follow-up to reviewing the dynamically replaceable
implementation, document the place where this analysis will likely
crash in the future once we start optimizing non-escaping closure
captures.
Fixes the following warning:
```console
third_party/unsupported_toolchains/swift/src/swift/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp:396:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
```
This is needed now that const expr handles string operations/etc. There aren't
tests for this now since I would need to stub out the stdlib. But these are
pretty simple changes overall, I do not expect any problems, and I plan on
enabling this relatively soon.
The specific case where this happened here is:
```
// Worklist = [
%0 = struct $Int (...)
%1 = $Klass
%2 = tuple (%0, %1)
(%3, %4) = destructure_tuple %2
store %3 to [trivial] %3stack
store %4 to [init] %4stack
```
What would happen is we would visit the destructure_tuple, replace %3 with %0
but fail to propagate %4:
```
%0 = struct $Int (...)
%1 = $Klass
%2 = tuple (%0, %1)
(%3, %4) = destructure_tuple %2
store %0 to [trivial] %3stack
store %4 to [init] %4stack
```
This then causes the tuple to be added to the worklist. When we visit the tuple,
we see that we have a destructure_tuple that is a user of the tuple, we see that
it still has that Struct as a user despite us having constant propagated that
component of the tuple. This then causes us to add the struct back to the
worklist despite that tuple component having no uses. Then when we visit the
struct. Which causes us to visit the tuple, etc.
rdar://49947112
An inout capture of 'self' is not lowered as a SIL argument inside
an initializer, so add a new check to handle this case.
Fixes <rdar://problem/50412872>.
1. During identifyAccess, determine if there are either any
identical accesses or an accesses that aren't already marked
no_nested_storage. If there are neither, then skip the subsequent
data flow analysis.
2. In the new StorageSet, indicate whether identical storage was
seen elsewhere in the function. During dataflow, only add an access
to the out-of-scope access set if was marked as having identical
storage with another access.
3. During data flow, don't track in scope conflicts for
instructions already marked [no_nested_conflict].
- code simplification critical for comprehension
- substantially improves the overhead of AccessedStorage comparison
- as a side effect improves precision of analysis in some cases
AccessedStorage is meant to be an immutable value type that identifies
a storage location with minimal representation. It is used in many global
interprocedural data structures.
The RefElementAddress instruction that it was derived from does not
contribute to the uniqueness of the storage location. It doesn't
belong here. It was being used to create a ProjectionPath, which is an
extremely inneficient way to compare access paths.
Just delete all the code related to that extra field.