@@ -299,7 +299,7 @@ private struct CollectedEffects {
299299 if let calleePath = calleeEffect. destroy { addEffects ( . destroy, to: argument, fromInitialPath: calleePath) }
300300 } else {
301301 let convention = callee. getArgumentConvention ( for: calleeArgIdx)
302- let wholeArgument = argument. at ( SmallProjectionPath ( . anything ) )
302+ let wholeArgument = argument. at ( defaultPath ( for : argument ) )
303303 let calleeEffects = callee. getSideEffects ( forArgument: wholeArgument,
304304 atIndex: calleeArgIdx,
305305 withConvention: convention)
@@ -313,8 +313,12 @@ private struct CollectedEffects {
313313 ///
314314 /// If the value comes from an argument (or mutliple arguments), then the effects are added
315315 /// 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+
316320 private mutating func addEffects( _ effects: SideEffects . GlobalEffects , to value: Value ,
317- fromInitialPath: SmallProjectionPath ? = nil ) {
321+ fromInitialPath: SmallProjectionPath ) {
318322
319323 /// Collects the (non-address) roots of a value.
320324 struct GetRootsWalker : ValueUseDefWalker {
@@ -346,10 +350,7 @@ private struct CollectedEffects {
346350
347351 var findRoots = GetRootsWalker ( context)
348352 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)
353354 switch accessPath. base {
354355 case . stack:
355356 // We don't care about read and writes from/to stack locations (because they are
@@ -369,16 +370,7 @@ private struct CollectedEffects {
369370 }
370371 }
371372 } 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)
382374 }
383375 // Because of phi-arguments, a single (non-address) `value` can come from multiple arguments.
384376 while let ( arg, path) = findRoots. roots. pop ( ) {
@@ -391,6 +383,16 @@ private struct CollectedEffects {
391383 }
392384}
393385
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+
394396/// Checks if an argument escapes to some unknown user.
395397private struct ArgumentEscapingWalker : ValueDefUseWalker , AddressDefUseWalker {
396398 var walkDownCache = WalkerCache < UnusedWalkingPath > ( )
0 commit comments