13
13
import SIL
14
14
15
15
fileprivate typealias Selection = ArgumentEffect . Selection
16
- fileprivate typealias Path = ArgumentEffect . Path
17
16
18
17
/// Computes effects for function arguments.
19
18
///
@@ -34,7 +33,7 @@ let computeEffects = FunctionPass(name: "compute-effects", {
34
33
var argsWithDefinedEffects = getArgIndicesWithDefinedEffects ( of: function)
35
34
36
35
struct IgnoreRecursiveCallVisitor : EscapeInfoVisitor {
37
- func visitUse( operand: Operand , path: Path , state : State ) -> UseResult {
36
+ func visitUse( operand: Operand , path: EscapePath ) -> UseResult {
38
37
return isOperandOfRecursiveCall ( operand) ? . ignore : . continueWalk
39
38
}
40
39
}
@@ -50,17 +49,17 @@ let computeEffects = FunctionPass(name: "compute-effects", {
50
49
if argsWithDefinedEffects. contains ( arg. index) { continue }
51
50
52
51
// First check: is the argument (or a projected value of it) escaping at all?
53
- if !escapeInfo. isEscapingWhenWalkingDown ( object: arg, path: Path ( . anything) ) {
54
- let selectedArg = Selection ( arg, pathPattern: Path ( . anything) )
52
+ if !escapeInfo. isEscapingWhenWalkingDown ( object: arg, path: SmallProjectionPath ( . anything) ) {
53
+ let selectedArg = Selection ( arg, pathPattern: SmallProjectionPath ( . anything) )
55
54
newEffects. push ( ArgumentEffect ( . notEscaping, selectedArg: selectedArg) )
56
55
continue
57
56
}
58
57
59
58
// Now compute effects for two important cases:
60
59
// * the argument itself + any value projections, and...
61
- if addArgEffects ( context: context, arg, argPath: Path ( ) , to: & newEffects, returnInst) {
60
+ if addArgEffects ( context: context, arg, argPath: SmallProjectionPath ( ) , to: & newEffects, returnInst) {
62
61
// * single class indirections
63
- _ = addArgEffects ( context: context, arg, argPath: Path ( . anyValueFields) . push ( . anyClassField) ,
62
+ _ = addArgEffects ( context: context, arg, argPath: SmallProjectionPath ( . anyValueFields) . push ( . anyClassField) ,
64
63
to: & newEffects, returnInst)
65
64
}
66
65
}
@@ -75,7 +74,7 @@ let computeEffects = FunctionPass(name: "compute-effects", {
75
74
76
75
/// Returns true if an argument effect was added.
77
76
private
78
- func addArgEffects( context: PassContext , _ arg: FunctionArgument , argPath ap: Path ,
77
+ func addArgEffects( context: PassContext , _ arg: FunctionArgument , argPath ap: SmallProjectionPath ,
79
78
to newEffects: inout Stack < ArgumentEffect > ,
80
79
_ returnInst: ReturnInst ? ) -> Bool {
81
80
// Correct the path if the argument is not a class reference itself, but a value type
@@ -91,18 +90,18 @@ func addArgEffects(context: PassContext, _ arg: FunctionArgument, argPath ap: Pa
91
90
var toSelection : Selection ?
92
91
var returnInst : ReturnInst ?
93
92
94
- mutating func visitUse( operand: Operand , path: Path , state : State ) -> UseResult {
93
+ mutating func visitUse( operand: Operand , path: EscapePath ) -> UseResult {
95
94
if operand. instruction == returnInst {
96
95
// The argument escapes to the function return
97
- if state . followStores {
96
+ if path . followStores {
98
97
// The escaping path must not introduce a followStores.
99
98
return . abort
100
99
}
101
100
if let ta = toSelection {
102
101
if ta. value != . returnValue { return . abort }
103
- toSelection = Selection ( . returnValue, pathPattern: path. merge ( with: ta. pathPattern) )
102
+ toSelection = Selection ( . returnValue, pathPattern: path. projectionPath . merge ( with: ta. pathPattern) )
104
103
} else {
105
- toSelection = Selection ( . returnValue, pathPattern: path)
104
+ toSelection = Selection ( . returnValue, pathPattern: path. projectionPath )
106
105
}
107
106
return . ignore
108
107
}
@@ -112,21 +111,21 @@ func addArgEffects(context: PassContext, _ arg: FunctionArgument, argPath ap: Pa
112
111
return . continueWalk
113
112
}
114
113
115
- mutating func visitDef( def: Value , path: Path , state : State ) -> DefResult {
114
+ mutating func visitDef( def: Value , path: EscapePath ) -> DefResult {
116
115
guard let destArg = def as? FunctionArgument else {
117
116
return . continueWalkUp
118
117
}
119
118
// The argument escapes to another argument (e.g. an out or inout argument)
120
- if state . followStores {
119
+ if path . followStores {
121
120
// The escaping path must not introduce a followStores.
122
121
return . abort
123
122
}
124
123
let argIdx = destArg. index
125
124
if let ta = toSelection {
126
125
if ta. value != . argument( argIdx) { return . abort }
127
- toSelection = Selection ( . argument( argIdx) , pathPattern: path. merge ( with: ta. pathPattern) )
126
+ toSelection = Selection ( . argument( argIdx) , pathPattern: path. projectionPath . merge ( with: ta. pathPattern) )
128
127
} else {
129
- toSelection = Selection ( . argument( argIdx) , pathPattern: path)
128
+ toSelection = Selection ( . argument( argIdx) , pathPattern: path. projectionPath )
130
129
}
131
130
return . walkDown
132
131
}
@@ -197,7 +196,7 @@ private func isOperandOfRecursiveCall(_ op: Operand) -> Bool {
197
196
/// there are no other arguments or escape points than `fromArgument`. Also, the
198
197
/// path at the `fromArgument` must match with `fromPath`.
199
198
private
200
- func isExclusiveEscape( context: PassContext , fromArgument: Argument , fromPath: Path , to toSelection: Selection ,
199
+ func isExclusiveEscape( context: PassContext , fromArgument: Argument , fromPath: SmallProjectionPath , to toSelection: Selection ,
201
200
_ returnInst: ReturnInst ) -> Bool {
202
201
switch toSelection. value {
203
202
@@ -207,25 +206,25 @@ func isExclusiveEscape(context: PassContext, fromArgument: Argument, fromPath: P
207
206
let fromArgument : Argument
208
207
let toSelection : Selection
209
208
let returnInst : ReturnInst
210
- let fromPath : Path
209
+ let fromPath : SmallProjectionPath
211
210
212
- mutating func visitUse( operand: Operand , path: Path , state : State ) -> UseResult {
211
+ mutating func visitUse( operand: Operand , path: EscapePath ) -> UseResult {
213
212
if operand. instruction == returnInst {
214
- if state . followStores { return . abort }
215
- if path. matches ( pattern: toSelection. pathPattern) {
213
+ if path . followStores { return . abort }
214
+ if path. projectionPath . matches ( pattern: toSelection. pathPattern) {
216
215
return . ignore
217
216
}
218
217
return . abort
219
218
}
220
219
return . continueWalk
221
220
}
222
221
223
- mutating func visitDef( def: Value , path: Path , state : State ) -> DefResult {
222
+ mutating func visitDef( def: Value , path: EscapePath ) -> DefResult {
224
223
guard let arg = def as? FunctionArgument else {
225
224
return . continueWalkUp
226
225
}
227
- if state . followStores { return . abort }
228
- if arg == fromArgument && path. matches ( pattern: fromPath) {
226
+ if path . followStores { return . abort }
227
+ if arg == fromArgument && path. projectionPath . matches ( pattern: fromPath) {
229
228
return . walkDown
230
229
}
231
230
return . abort
@@ -240,17 +239,17 @@ func isExclusiveEscape(context: PassContext, fromArgument: Argument, fromPath: P
240
239
case . argument( let toArgIdx) :
241
240
struct IsExclusiveArgumentEscapeVisitor : EscapeInfoVisitor {
242
241
let fromArgument : Argument
243
- let fromPath : Path
242
+ let fromPath : SmallProjectionPath
244
243
let toSelection : Selection
245
244
let toArg : FunctionArgument
246
245
247
- mutating func visitDef( def: Value , path: Path , state : State ) -> DefResult {
246
+ mutating func visitDef( def: Value , path: EscapePath ) -> DefResult {
248
247
guard let arg = def as? FunctionArgument else {
249
248
return . continueWalkUp
250
249
}
251
- if state . followStores { return . abort }
252
- if arg == fromArgument && path. matches ( pattern: fromPath) { return . walkDown }
253
- if arg == toArg && path. matches ( pattern: toSelection. pathPattern) { return . walkDown }
250
+ if path . followStores { return . abort }
251
+ if arg == fromArgument && path. projectionPath . matches ( pattern: fromPath) { return . walkDown }
252
+ if arg == toArg && path. projectionPath . matches ( pattern: toSelection. pathPattern) { return . walkDown }
254
253
return . abort
255
254
}
256
255
}
0 commit comments