mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Generalize and fix SinkAddressProjections.
Fixes a potential real bug in the case that SinkAddressProjections moves
projections without notifying SimplifyCFG of the change. This could
fail to update Analyses (probably won't break anything in practice).
Introduce SILInstruction::isPure. Among other things, this can tell
you if it's safe to duplicate instructions at their
uses. SinkAddressProjections should check this before sinking uses. I
couldn't find a way to expose this as a real bug, but it is a
theoretical bug.
Add the SinkAddressProjections functionality to the BasicBlockCloner
utility. Enable address projection sinking for all BasicBlockCloner
clients (the four different kinds of jump-threading that use it). This
brings the compiler much closer to banning all address phis.
The "bugs" were originally introduced a week ago here:
commit f22371bf0b (fork/fix-address-phi, fix-address-phi)
Author: Andrew Trick <atrick@apple.com>
Date: Tue Sep 17 16:45:51 2019
Add SIL SinkAddressProjections utility to avoid address phis.
Enable this utility during jump-threading in SimplifyCFG.
Ultimately, the SIL verifier should prevent all address-phis and we'll
need to use this utility in a few more places.
Fixes <rdar://problem/55320867> SIL verification failed: Unknown
formal access pattern: storage
This commit is contained in:
@@ -43,8 +43,8 @@ public class C<R> {
|
||||
let r : R
|
||||
init(_ _r: R) { r = _r }
|
||||
|
||||
// SIL: // C.f<A>(_:)
|
||||
// IR: define {{.*}} @"$s1A1CC1fyyqd__lF"
|
||||
// SIL-LABEL: // C.f<A>(_:)
|
||||
// IR-LABEL: define {{.*}} @"$s1A1CC1fyyqd__lF"
|
||||
#sourceLocation(file: "f.swift", line: 1)
|
||||
public func f<S>(_ s: S) {
|
||||
// SIL: debug_value_addr %0 : $*S, let, name "s", argno 1,{{.*}} scope [[F]]
|
||||
@@ -57,7 +57,13 @@ public class C<R> {
|
||||
// IR: call {{.*}}3use
|
||||
#sourceLocation(file: "f.swift", line: 2)
|
||||
g(s)
|
||||
// IR: dbg.value({{.*}}, metadata ![[GR_T:[0-9]+]]
|
||||
// Jump-threading removes the basic block containing debug_value
|
||||
// "t" before the second call to `g(r)`. When this happens, the
|
||||
// ref_element_addr in that removed block is left with a single
|
||||
// debug_value use, so they are both deleted. This means we have
|
||||
// no debug value for "t" in the call to `g(r)`.
|
||||
// dbg.value({{.*}}, metadata ![[GR_T:[0-9]+]]
|
||||
|
||||
// IR: dbg.value({{.*}}, metadata ![[GR_U:[0-9]+]]
|
||||
// IR: call {{.*}}3use
|
||||
#sourceLocation(file: "f.swift", line: 3)
|
||||
@@ -81,6 +87,8 @@ public class C<R> {
|
||||
g(false)
|
||||
}
|
||||
}
|
||||
// SIL-LABEL: } // end sil function '$s1A1CC1fyyqd__lF'
|
||||
// IR-LABEL: ret void
|
||||
|
||||
// IR: ![[BOOL:[0-9]+]] = !DICompositeType({{.*}}name: "Bool"
|
||||
// IR: ![[LET_BOOL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[BOOL]])
|
||||
@@ -96,9 +104,12 @@ public class C<R> {
|
||||
// IR: ![[SP_GS_T]] = {{.*}}linkageName: "$s1A1gyyxlFqd___Ti5"
|
||||
// IR: ![[GS_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GS_U:[0-9]+]], {{.*}} type: ![[LET_TAU_1_0]])
|
||||
// IR: ![[SP_GS_U]] = {{.*}}linkageName: "$s1A1hyyxlFqd___Ti5"
|
||||
// IR: ![[GR_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GR_T:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
|
||||
|
||||
// Debug info for this variable is removed. See the note above the call to g(r).
|
||||
// ![[GR_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GR_T:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
|
||||
// S has the same generic parameter numbering s T and U.
|
||||
// IR: ![[SP_GR_T]] = {{.*}}linkageName: "$s1A1gyyxlF"
|
||||
// ![[SP_GR_T]] = {{.*}}linkageName: "$s1A1gyyxlF"
|
||||
|
||||
// IR: ![[GR_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GR_U:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
|
||||
// IR: ![[SP_GR_U]] = {{.*}}linkageName: "$s1A1hyyxlF"
|
||||
// IR: ![[GRS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GRS_T:[0-9]+]], {{.*}}type: ![[LET_TUPLE:[0-9]+]]
|
||||
|
||||
Reference in New Issue
Block a user