summaryrefslogtreecommitdiff
path: root/absl/base/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/base/internal')
-rw-r--r--absl/base/internal/bits.h35
-rw-r--r--absl/base/internal/periodic_sampler.cc6
-rw-r--r--absl/base/internal/periodic_sampler.h62
3 files changed, 70 insertions, 33 deletions
diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h
index b0780f2d..450b923f 100644
--- a/absl/base/internal/bits.h
+++ b/absl/base/internal/bits.h
@@ -50,10 +50,22 @@ namespace base_internal {
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) {
int zeroes = 60;
- if (n >> 32) zeroes -= 32, n >>= 32;
- if (n >> 16) zeroes -= 16, n >>= 16;
- if (n >> 8) zeroes -= 8, n >>= 8;
- if (n >> 4) zeroes -= 4, n >>= 4;
+ if (n >> 32) {
+ zeroes -= 32;
+ n >>= 32;
+ }
+ if (n >> 16) {
+ zeroes -= 16;
+ n >>= 16;
+ }
+ if (n >> 8) {
+ zeroes -= 8;
+ n >>= 8;
+ }
+ if (n >> 4) {
+ zeroes -= 4;
+ n >>= 4;
+ }
return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
}
@@ -95,9 +107,18 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) {
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) {
int zeroes = 28;
- if (n >> 16) zeroes -= 16, n >>= 16;
- if (n >> 8) zeroes -= 8, n >>= 8;
- if (n >> 4) zeroes -= 4, n >>= 4;
+ if (n >> 16) {
+ zeroes -= 16;
+ n >>= 16;
+ }
+ if (n >> 8) {
+ zeroes -= 8;
+ n >>= 8;
+ }
+ if (n >> 4) {
+ zeroes -= 4;
+ n >>= 4;
+ }
return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
}
diff --git a/absl/base/internal/periodic_sampler.cc b/absl/base/internal/periodic_sampler.cc
index 439745d0..69656c8a 100644
--- a/absl/base/internal/periodic_sampler.cc
+++ b/absl/base/internal/periodic_sampler.cc
@@ -36,13 +36,13 @@ bool PeriodicSamplerBase::SubtleConfirmSample() noexcept {
// Check if this is the first call to Sample()
if (ABSL_PREDICT_FALSE(stride_ == 1)) {
- stride_ = -1 - GetExponentialBiased(current_period);
- if (stride_ < -1) {
+ stride_ = static_cast<uint64_t>(-1 - GetExponentialBiased(current_period));
+ if (static_cast<int64_t>(stride_) < -1) {
++stride_;
return false;
}
}
- stride_ = -1 - GetExponentialBiased(current_period);
+ stride_ = static_cast<uint64_t>(-1 - GetExponentialBiased(current_period));
return true;
}
diff --git a/absl/base/internal/periodic_sampler.h b/absl/base/internal/periodic_sampler.h
index 2c0600f0..23879742 100644
--- a/absl/base/internal/periodic_sampler.h
+++ b/absl/base/internal/periodic_sampler.h
@@ -111,33 +111,49 @@ class PeriodicSamplerBase {
// Returns the current period of this sampler. Thread-safe.
virtual int period() const noexcept = 0;
- int64_t stride_ = 0;
+ // Keep and decrement stride_ as an unsigned integer, but compare the value
+ // to zero casted as a signed int. clang and msvc do not create optimum code
+ // if we use signed for the combined decrement and sign comparison.
+ //
+ // Below 3 alternative options, all compiles generate the best code
+ // using the unsigned increment <---> signed int comparison option.
+ //
+ // Option 1:
+ // int64_t stride_;
+ // if (ABSL_PREDICT_TRUE(++stride_ < 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/R5MzzA
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/z7NZAt
+ // Clang x64 (BAD): https://gcc.godbolt.org/z/t4gPsd
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/rE6s8W
+ // MSVC x64 (OK) : https://gcc.godbolt.org/z/ARMXqS
+ //
+ // Option 2:
+ // int64_t stride_ = 0;
+ // if (ABSL_PREDICT_TRUE(--stride_ >= 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/jSQxYK
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/VJdYaA
+ // Clang x64 (BAD): https://gcc.godbolt.org/z/Xm4NjX
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/4snaFd
+ // MSVC x64 (BAD): https://gcc.godbolt.org/z/BgnEKE
+ //
+ // Option 3:
+ // uint64_t stride_;
+ // if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) { ... }
+ //
+ // GCC x64 (OK) : https://gcc.godbolt.org/z/bFbfPy
+ // GCC ppc (OK) : https://gcc.godbolt.org/z/S9KkUE
+ // Clang x64 (OK) : https://gcc.godbolt.org/z/UYzRb4
+ // ICC x64 (OK) : https://gcc.godbolt.org/z/ptTNfD
+ // MSVC x64 (OK) : https://gcc.godbolt.org/z/76j4-5
+ uint64_t stride_ = 0;
ExponentialBiased rng_;
};
inline bool PeriodicSamplerBase::SubtleMaybeSample() noexcept {
- // We explicitly count up and not down, as the compiler does not generate
- // ideal code for counting down. See also https://gcc.godbolt.org/z/FTPDSM
- //
- // With `if (ABSL_PREDICT_FALSE(++stride_ < 0))`
- // add QWORD PTR fs:sampler@tpoff+8, 1
- // jns .L15
- // ret
- //
- // With `if (ABSL_PREDICT_FALSE(--stride_ > 0))`
- // mov rax, QWORD PTR fs:sampler@tpoff+8
- // sub rax, 1
- // mov QWORD PTR fs:sampler@tpoff+8, rax
- // test rax, rax
- // jle .L15
- // ret
- // add QWORD PTR fs:sampler@tpoff+8, 1
- // jns .L15
- // ret
- //
- // --stride >= 0 does work, but makes our logic slightly harder as in that
- // case we have less convenient zero-init and over-run values.
- if (ABSL_PREDICT_FALSE(++stride_ < 0)) {
+ // See comments on `stride_` for the unsigned increment / signed compare.
+ if (ABSL_PREDICT_TRUE(static_cast<int64_t>(++stride_) < 0)) {
return false;
}
return true;