std/sys/unix/time: make it easier for LLVM to optimize Instant
subtraction.
This commit is contained in:
parent
8e21bd0633
commit
a7ad899f9d
1 changed files with 20 additions and 8 deletions
|
@ -20,17 +20,29 @@ impl Timespec {
|
||||||
|
|
||||||
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
|
||||||
if self >= other {
|
if self >= other {
|
||||||
Ok(if self.t.tv_nsec >= other.t.tv_nsec {
|
// NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
|
||||||
Duration::new(
|
// to optimize it into a branchless form (see also #75545):
|
||||||
(self.t.tv_sec - other.t.tv_sec) as u64,
|
//
|
||||||
(self.t.tv_nsec - other.t.tv_nsec) as u32,
|
// 1. `self.t.tv_sec - other.t.tv_sec` shows up as a common expression
|
||||||
)
|
// in both branches, i.e. the `else` must have its `- 1`
|
||||||
|
// subtraction after the common one, not interleaved with it
|
||||||
|
// (it used to be `self.t.tv_sec - 1 - other.t.tv_sec`)
|
||||||
|
//
|
||||||
|
// 2. the `Duration::new` call (or any other additional complexity)
|
||||||
|
// is outside of the `if`-`else`, not duplicated in both branches
|
||||||
|
//
|
||||||
|
// Ideally this code could be rearranged such that it more
|
||||||
|
// directly expresses the lower-cost behavior we want from it.
|
||||||
|
let (secs, nsec) = if self.t.tv_nsec >= other.t.tv_nsec {
|
||||||
|
((self.t.tv_sec - other.t.tv_sec) as u64, (self.t.tv_nsec - other.t.tv_nsec) as u32)
|
||||||
} else {
|
} else {
|
||||||
Duration::new(
|
(
|
||||||
(self.t.tv_sec - 1 - other.t.tv_sec) as u64,
|
(self.t.tv_sec - other.t.tv_sec - 1) as u64,
|
||||||
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.t.tv_nsec as u32,
|
||||||
)
|
)
|
||||||
})
|
};
|
||||||
|
|
||||||
|
Ok(Duration::new(secs, nsec))
|
||||||
} else {
|
} else {
|
||||||
match other.sub_timespec(self) {
|
match other.sub_timespec(self) {
|
||||||
Ok(d) => Err(d),
|
Ok(d) => Err(d),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue