Skip to content

StackPromotion: fix a problem with promoted allocations in dead-end regions #67082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ private func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
return false
}

// The most important check: does the object escape the current function?
if allocRef.isEscaping(context) {
return false
}

if deadEndBlocks.isDeadEnd(allocRef.parentBlock) {

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

// The most important check: does the object escape the current function?
if allocRef.isEscaping(context) {
return false
}

// Try to find the top most dominator block which dominates all use points.
// * This block can be located "earlier" than the actual allocation block, in case the
// promoted object is stored into an "outer" object, e.g.
Expand Down