Skip to content

Commit 9289d03

Browse files
committed
llvm makes good inlining choices with only the #[cold] attribute
1 parent 2b3642b commit 9289d03

File tree

1 file changed

+15
-19
lines changed

1 file changed

+15
-19
lines changed

src/libstd/thread/local.rs

+15-19
Original file line numberDiff line numberDiff line change
@@ -414,46 +414,42 @@ pub mod fast {
414414
}
415415

416416
// `try_initialize` is only called once per fast thread local variable,
417-
// except in corner cases where it is being recursively initialized.
417+
// except in corner cases where thread_local dtors reference other
418+
// thread_local's, or it is being recursively initialized.
419+
//
420+
// Macos: Inlining this function can cause two `tlv_get_addr` calls to
421+
// be performed for every call to `Key::get`. The #[cold] hint makes
422+
// that less likely.
423+
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
418424
#[cold]
419425
unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
420-
if mem::needs_drop::<T>() {
421-
self.try_initialize_drop(init)
422-
} else {
426+
if !mem::needs_drop::<T>() || self.try_register_dtor() {
423427
Some(self.inner.initialize(init))
428+
} else {
429+
None
424430
}
425431
}
426432

427-
// `try_initialize_drop` is only called once per fast thread local
433+
// `try_register_dtor` is only called once per fast thread local
428434
// variable, except in corner cases where thread_local dtors reference
429435
// other thread_local's, or it is being recursively initialized.
430-
//
431-
// Macos: Inlining this function causes two `tlv_get_addr` calls to be
432-
// performed for every call to `Key::get`.
433-
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
434-
#[inline(never)]
435-
#[cold]
436-
unsafe fn try_initialize_drop<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
437-
// We don't put a `needs_drop` check around this and call it a day
438-
// because this function is not inlined. Unwrapping code gets
439-
// generated for callers of `LocalKey::with` even if we always
440-
// return `Some` here.
436+
unsafe fn try_register_dtor(&self) -> bool {
441437
match self.dtor_state.get() {
442438
DtorState::Unregistered => {
443439
// dtor registration happens before initialization.
444440
register_dtor(self as *const _ as *mut u8,
445441
destroy_value::<T>);
446442
self.dtor_state.set(DtorState::Registered);
443+
true
447444
}
448445
DtorState::Registered => {
449446
// recursively initialized
447+
true
450448
}
451449
DtorState::RunningOrHasRun => {
452-
return None
450+
false
453451
}
454452
}
455-
456-
Some(self.inner.initialize(init))
457453
}
458454
}
459455

0 commit comments

Comments
 (0)