@@ -299,7 +299,7 @@ private struct CollectedEffects {
299
299
if let calleePath = calleeEffect. destroy { addEffects ( . destroy, to: argument, fromInitialPath: calleePath) }
300
300
} else {
301
301
let convention = callee. getArgumentConvention ( for: calleeArgIdx)
302
- let wholeArgument = argument. at ( SmallProjectionPath ( . anything ) )
302
+ let wholeArgument = argument. at ( defaultPath ( for : argument ) )
303
303
let calleeEffects = callee. getSideEffects ( forArgument: wholeArgument,
304
304
atIndex: calleeArgIdx,
305
305
withConvention: convention)
@@ -313,8 +313,12 @@ private struct CollectedEffects {
313
313
///
314
314
/// If the value comes from an argument (or mutliple arguments), then the effects are added
315
315
/// to the corrseponding `argumentEffects`. Otherwise they are added to the `global` effects.
316
+ private mutating func addEffects( _ effects: SideEffects . GlobalEffects , to value: Value ) {
317
+ addEffects ( effects, to: value, fromInitialPath: defaultPath ( for: value) )
318
+ }
319
+
316
320
private mutating func addEffects( _ effects: SideEffects . GlobalEffects , to value: Value ,
317
- fromInitialPath: SmallProjectionPath ? = nil ) {
321
+ fromInitialPath: SmallProjectionPath ) {
318
322
319
323
/// Collects the (non-address) roots of a value.
320
324
struct GetRootsWalker : ValueUseDefWalker {
@@ -346,10 +350,7 @@ private struct CollectedEffects {
346
350
347
351
var findRoots = GetRootsWalker ( context)
348
352
if value. type. isAddress {
349
- // If there is no initial path provided, select all value fields.
350
- let path = fromInitialPath ?? SmallProjectionPath ( . anyValueFields)
351
-
352
- let accessPath = value. getAccessPath ( fromInitialPath: path)
353
+ let accessPath = value. getAccessPath ( fromInitialPath: fromInitialPath)
353
354
switch accessPath. base {
354
355
case . stack:
355
356
// We don't care about read and writes from/to stack locations (because they are
@@ -369,16 +370,7 @@ private struct CollectedEffects {
369
370
}
370
371
}
371
372
} else {
372
- // Handle non-address `value`s which are projections from a direct arguments.
373
- let path : SmallProjectionPath
374
- if let fromInitialPath = fromInitialPath {
375
- path = fromInitialPath
376
- } else if value. type. isClass {
377
- path = SmallProjectionPath ( . anyValueFields) . push ( . anyClassField)
378
- } else {
379
- path = SmallProjectionPath ( . anyValueFields) . push ( . anyClassField) . push ( . anyValueFields)
380
- }
381
- _ = findRoots. walkUp ( value: value, path: path)
373
+ _ = findRoots. walkUp ( value: value, path: fromInitialPath)
382
374
}
383
375
// Because of phi-arguments, a single (non-address) `value` can come from multiple arguments.
384
376
while let ( arg, path) = findRoots. roots. pop ( ) {
@@ -391,6 +383,16 @@ private struct CollectedEffects {
391
383
}
392
384
}
393
385
386
+ private func defaultPath( for value: Value ) -> SmallProjectionPath {
387
+ if value. type. isAddress {
388
+ return SmallProjectionPath ( . anyValueFields)
389
+ }
390
+ if value. type. isClass {
391
+ return SmallProjectionPath ( . anyValueFields) . push ( . anyClassField)
392
+ }
393
+ return SmallProjectionPath ( . anyValueFields) . push ( . anyClassField) . push ( . anyValueFields)
394
+ }
395
+
394
396
/// Checks if an argument escapes to some unknown user.
395
397
private struct ArgumentEscapingWalker : ValueDefUseWalker , AddressDefUseWalker {
396
398
var walkDownCache = WalkerCache < UnusedWalkingPath > ( )
0 commit comments