Skip to content

Commit bed80ee

Browse files
committed
[NFC] LifetimeDependence computeAddressRange comments and test case
1 parent ac31a2f commit bed80ee

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,10 @@ extension LifetimeDependence.Scope {
428428
///
429429
/// Returns nil if the dependence scope covers the entire function. Returns an empty range for an unknown scope.
430430
///
431+
/// When this Scope is live on unreachable paths, the returned range may include blocks that are not dominated by the
432+
/// scope introducer. Even though 'range.isValid == false' for such a range, it is still valid for checking that
433+
/// dependencies are in scope since we already know that the Scope introducer dominates all dependent uses.
434+
///
431435
/// Ignore the lifetime of temporary trivial values (with .initialized and .unknown scopes). Temporaries have an
432436
/// unknown Scope, which means that LifetimeDependence.Scope did not recognize a VariableScopeInstruction. This is
433437
/// important to promote mark_dependence instructions emitted by SILGen to [nonescaping] (e.g. unsafeAddressor). It
@@ -568,11 +572,16 @@ extension LifetimeDependence.Scope {
568572
var forwardUnreachableWalk = BasicBlockWorklist(context)
569573
defer { forwardUnreachableWalk.deinitialize() }
570574

575+
// TODO: ensure complete dealloc_stack on all paths in SIL verification, then assert exitBlock.isEmpty.
571576
for exitBlock in range.exitBlocks {
572577
forwardUnreachableWalk.pushIfNotVisited(exitBlock)
573578
}
574579
while let b = forwardUnreachableWalk.pop() {
575580
if let unreachableInst = b.terminator as? UnreachableInst {
581+
// Note: 'unreachableInst' is not necessarilly dominated by 'initializingStore'. This marks the range invalid,
582+
// but leaves it in a usable state that includes all blocks covered by the temporary allocation. The extra
583+
// blocks (backward up to the function entry) are irrelevant becase we already know that 'initializingStore'
584+
// dominates dependent uses.
576585
range.insert(unreachableInst)
577586
}
578587
for succBlock in b.successors {

test/SILOptimizer/lifetime_dependence/verify_diagnostics.sil

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,42 @@ bb2(%error : @owned $any Error):
381381
destroy_value [dead_end] %md
382382
unreachable
383383
}
384+
385+
// Test dependence on the temporary stack address of a trivial value. computeAddressableRange must extend the lifetime
386+
// of %tempAddr into the unreachable.
387+
//
388+
// Note that the computed instruction range is marked Invalid because it does not have a single dominating
389+
// block. Nonetheless, the range still include all blocks in which the stack allocation is live, which is all we care
390+
// about.
391+
sil hidden [ossa] @testTempAddressNondominatedUnreachable : $@convention(thin) (@in_guaranteed InlineInt) -> () {
392+
bb0(%0 : $*InlineInt):
393+
cond_br undef, bb1, bb2
394+
395+
bb1:
396+
br bb5
397+
398+
bb2:
399+
%loadArg = load [trivial] %0
400+
%tempAddr = alloc_stack $InlineInt
401+
store %loadArg to [trivial] %tempAddr
402+
403+
%f1 = function_ref @getInlineSpan : $@convention(thin) (@in_guaranteed InlineInt) -> @lifetime(borrow address 0) @owned RawSpan
404+
%call = apply %f1(%tempAddr) : $@convention(thin) (@in_guaranteed InlineInt) -> @lifetime(borrow address 0) @owned RawSpan
405+
%md = mark_dependence [unresolved] %call on %tempAddr
406+
407+
%f2 = function_ref @useRawSpan : $@convention(thin) (@guaranteed RawSpan) -> @error any Error
408+
try_apply %f2(%md) : $@convention(thin) (@guaranteed RawSpan) -> @error any Error, normal bb3, error bb4
409+
410+
bb3(%void : $()):
411+
destroy_value %md
412+
dealloc_stack %tempAddr
413+
%99 = tuple ()
414+
return %99
415+
416+
bb4(%error : @owned $any Error):
417+
destroy_value [dead_end] %md
418+
br bb5
419+
420+
bb5:
421+
unreachable
422+
}

test/SILOptimizer/lifetime_dependence/verify_diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ func returnTempBorrow() -> Borrow<Int> {
405405
// store %arg to [trivial] temp
406406
// apply %get_span(%temp)
407407
//
408-
// If we use InlineArray instead, we get a store_borrow, which is a completely different situatio.
408+
// If we use InlineArray instead, we get a store_borrow, which is a completely different situation.
409409
func test(inline: InlineInt) {
410410
inline.span.withUnsafeBytes { _ = $0 }
411411
}

0 commit comments

Comments
 (0)