Skip to content

[EscapeAnalysis] Handle atomic instructions in escape analysis #71997

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
Mar 5, 2024

Conversation

Azoy
Copy link
Contributor

@Azoy Azoy commented Feb 29, 2024

Given the following simple use of the new Atomic type:

func something() -> Int {
  let x = Atomic(0)
  return x.load(ordering: .relaxed)
}

we generate the following SIL:

// something()
sil hidden @something: $@convention(thin) () -> Int {
[global: read,write,copy,destroy,allocate,deinit_barrier]
bb0:
  %0 = alloc_stack [lexical] $Atomic<Int>, let, name "x" // users: %7, %9, %12, %13
  %1 = integer_literal $Builtin.Int64, 0          // user: %4
  %2 = alloc_stack $Atomic<Int>                   // users: %5, %8, %7, %3
  %3 = builtin "zeroInitializer"<Atomic<Int>>(%2 : $*Atomic<Int>) : $()
  %4 = struct $_Atomic64BitStorage (%1 : $Builtin.Int64) // user: %6
  %5 = unchecked_addr_cast %2 : $*Atomic<Int> to $*_Atomic64BitStorage // user: %6
  store %4 to %5 : $*_Atomic64BitStorage          // id: %6
  copy_addr [take] %2 to [init] %0 : $*Atomic<Int> // id: %7
  dealloc_stack %2 : $*Atomic<Int>                // id: %8
  %9 = address_to_pointer %0 : $*Atomic<Int> to $Builtin.RawPointer // user: %10
  %10 = builtin "atomicload_monotonic_Int64"(%9 : $Builtin.RawPointer) : $Builtin.Int64 // user: %11
  %11 = struct $Int (%10 : $Builtin.Int64)        // user: %14
  destroy_addr %0 : $*Atomic<Int>                 // id: %12
  dealloc_stack %0 : $*Atomic<Int>                // id: %13
  return %11 : $Int                               // id: %14
} // end sil function '$s4main8testLoadSiyF'

TempLValueOpt is unable to eliminate the temporary because of the atomic builtin instruction acting as a barrier for escape analysis to determine if the zero initializer escapes the lexical alloc stack instruction. Handle them by walking down their result uses.

This results in the following new SIL:

// something
sil hidden @something : $@convention(thin) () -> Int {
[global: read,write,copy,destroy,allocate,deinit_barrier]
bb0:
  %0 = alloc_stack [lexical] $Atomic<Int>, let, name "x" // users: %4, %2, %6, %9, %10
  %1 = integer_literal $Builtin.Int64, 0          // user: %3
  %2 = builtin "zeroInitializer"<Atomic<Int>>(%0 : $*Atomic<Int>) : $()
  %3 = struct $_Atomic64BitStorage (%1 : $Builtin.Int64) // user: %5
  %4 = unchecked_addr_cast %0 : $*Atomic<Int> to $*_Atomic64BitStorage // user: %5
  store %3 to %4 : $*_Atomic64BitStorage          // id: %5
  %6 = address_to_pointer %0 : $*Atomic<Int> to $Builtin.RawPointer // user: %7
  %7 = builtin "atomicload_monotonic_Int64"(%6 : $Builtin.RawPointer) : $Builtin.Int64 // user: %8
  %8 = struct $Int (%7 : $Builtin.Int64)          // user: %11
  destroy_addr %0 : $*Atomic<Int>                 // id: %9
  dealloc_stack %0 : $*Atomic<Int>                // id: %10
  return %8 : $Int                                // id: %11
} // end sil function 'something'

Now, we should be able to optimize away the zero initializer entirely, but that's work for a different optimization pass.

@Azoy Azoy requested a review from nate-chandler February 29, 2024 23:53
@Azoy Azoy requested a review from eeckstein as a code owner February 29, 2024 23:53
@Azoy
Copy link
Contributor Author

Azoy commented Feb 29, 2024

@swift-ci please test

@Azoy Azoy force-pushed the fix-zero-init-escape branch from a88c90f to 42ac155 Compare March 5, 2024 01:18
@Azoy
Copy link
Contributor Author

Azoy commented Mar 5, 2024

@swift-ci please test

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@Azoy Azoy force-pushed the fix-zero-init-escape branch from 42ac155 to 32141d6 Compare March 5, 2024 16:31
Split atomic loads/stores

no more guard

invert condition
@Azoy Azoy force-pushed the fix-zero-init-escape branch from 32141d6 to 254e4f0 Compare March 5, 2024 16:33
@Azoy
Copy link
Contributor Author

Azoy commented Mar 5, 2024

@swift-ci please test

@Azoy Azoy merged commit 1752b48 into swiftlang:main Mar 5, 2024
@Azoy Azoy deleted the fix-zero-init-escape branch March 5, 2024 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants