Skip to content

Commit cb61903

Browse files
authored
Merge pull request #67082 from eeckstein/fix-stack-promotion
StackPromotion: fix a problem with promoted allocations in dead-end regions
2 parents 3ab4e71 + 36c8229 commit cb61903

File tree

1 file changed

+7
-13
lines changed

1 file changed

+7
-13
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/StackPromotion.swift

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ private func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
6868
return false
6969
}
7070

71+
// The most important check: does the object escape the current function?
72+
if allocRef.isEscaping(context) {
73+
return false
74+
}
75+
7176
if deadEndBlocks.isDeadEnd(allocRef.parentBlock) {
7277

7378
// Allocations inside a code region which ends up in a no-return block may missing their
@@ -77,11 +82,8 @@ private func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
7782
// ...
7883
// unreachable // The end of %k's lifetime
7984
//
80-
// Also, such an allocation cannot escape the function, because the function does not
81-
// return after the point of allocation. So we can stack-promote it unconditionally.
82-
//
8385
// There is one exception: if it's in a loop (within the dead-end region) we must not
84-
// extend its lifetime. On the other hand we can be sure that its final release is not
86+
// extend its lifetime. In this case we can be sure that its final release is not
8587
// missing, because otherwise the object would be leaking. For example:
8688
//
8789
// bb1:
@@ -93,20 +95,12 @@ private func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
9395
//
9496
// Therefore, if the allocation is inside a loop, we can treat it like allocations in
9597
// non dead-end regions.
96-
if !isInLoop(block: allocRef.parentBlock, context),
97-
// TODO: for some reason this doesn't work for aysnc functions.
98-
// Maybe a problem with co-routine splitting in LLVM?
99-
!allocRef.parentFunction.isAsync {
98+
if !isInLoop(block: allocRef.parentBlock, context) {
10099
allocRef.setIsStackAllocatable(context)
101100
return true
102101
}
103102
}
104103

105-
// The most important check: does the object escape the current function?
106-
if allocRef.isEscaping(context) {
107-
return false
108-
}
109-
110104
// Try to find the top most dominator block which dominates all use points.
111105
// * This block can be located "earlier" than the actual allocation block, in case the
112106
// promoted object is stored into an "outer" object, e.g.

0 commit comments

Comments
 (0)