@@ -46,23 +46,31 @@ let lifetimeDependenceScopeFixupPass = FunctionPass(
46
46
}
47
47
}
48
48
49
- // Extend all access scopes that enclose `dependence`. If dependence is on an access scope in the caller, then return
50
- // the function argument that represents the dependence scope.
49
+ /// Extend all access scopes that enclose `dependence`. If dependence is on an access scope in the caller, then return
50
+ /// the function argument that represents the dependence scope.
51
51
private func extendAccessScopes( dependence: LifetimeDependence , _ context: FunctionPassContext ) -> FunctionArgument ? {
52
52
log ( " Scope fixup for lifetime dependent instructions: \( dependence) " )
53
53
54
54
guard case . access( let bai) = dependence. scope else {
55
55
return nil
56
56
}
57
+ let function = bai. parentFunction
57
58
var range = InstructionRange ( begin: bai, context)
58
- var walker = LifetimeDependenceScopeFixupWalker ( bai . parentFunction , context) {
59
+ var walker = LifetimeDependenceScopeFixupWalker ( function , context) {
59
60
range. insert ( $0. instruction)
60
61
return . continueWalk
61
62
}
62
63
defer { walker. deinitialize ( ) }
63
64
_ = walker. walkDown ( root: dependence. dependentValue)
64
65
defer { range. deinitialize ( ) }
65
66
67
+ // Lifetime dependenent uses may no be dominated by the access. The dependent value may be used by a phi or stored
68
+ // into a memory location. The access may be conditional relative to such uses. If this is the case, then the
69
+ // instruction range must include the function entry.
70
+ let firstInst = function. entryBlock. instructions. first!
71
+ if firstInst != bai, range. contains ( firstInst) {
72
+ return nil
73
+ }
66
74
if let arg = extendAccessScope ( beginAccess: bai, range: & range, context) {
67
75
// If the dependent value is returned, then return the FunctionArgument that it depends on.
68
76
return walker. dependsOnCaller ? arg : nil
0 commit comments