Commit e741d8ef authored by Roger Kim's avatar Roger Kim Committed by Facebook GitHub Bot

Replace if-statements with `if constexpr` statements

Summary:
We have found that BitVectorCoding.h incorrectly outputs
-Wdivision-by-zero errors when another file that includes it fails to compile.
In the absence of other compilation errors, the -Wdivision-by-zero error does
not appear (since the compiler correctly can tell that "division by zero" is
not an issue in the code).

In order to get rid of these erroneous error logs, we decided to replace the
if-statements that surround the divisions (and check that the divisor is not
zero) with `if constexpr` statements since those will stop the compiler from
mistakenly thinking that division by zero is possible.

Reviewed By: ot, philippv, luciang

Differential Revision: D26961916

fbshipit-source-id: f65ef6d7782c94e58d6d28b9f8b053f205e3b7c1
parent 28799ed1
...@@ -128,7 +128,7 @@ struct BitVectorEncoder { ...@@ -128,7 +128,7 @@ struct BitVectorEncoder {
folly::Bits<folly::Unaligned<uint64_t>>::set( folly::Bits<folly::Unaligned<uint64_t>>::set(
reinterpret_cast<folly::Unaligned<uint64_t>*>(block), inner); reinterpret_cast<folly::Unaligned<uint64_t>*>(block), inner);
if (skipQuantum != 0) { if constexpr (skipQuantum != 0) {
size_t nextSkipPointerSize = value / skipQuantum; size_t nextSkipPointerSize = value / skipQuantum;
while (skipPointersSize_ < nextSkipPointerSize) { while (skipPointersSize_ < nextSkipPointerSize) {
auto pos = skipPointersSize_++; auto pos = skipPointersSize_++;
...@@ -137,7 +137,7 @@ struct BitVectorEncoder { ...@@ -137,7 +137,7 @@ struct BitVectorEncoder {
} }
} }
if (forwardQuantum != 0) { if constexpr (forwardQuantum != 0) {
if (size_ != 0 && (size_ % forwardQuantum == 0)) { if (size_ != 0 && (size_ % forwardQuantum == 0)) {
const auto pos = size_ / forwardQuantum - 1; const auto pos = size_ / forwardQuantum - 1;
folly::storeUnaligned<SkipValueType>( folly::storeUnaligned<SkipValueType>(
...@@ -183,11 +183,11 @@ struct BitVectorEncoder<Value, SkipValue, kSkipQuantum, kForwardQuantum>:: ...@@ -183,11 +183,11 @@ struct BitVectorEncoder<Value, SkipValue, kSkipQuantum, kForwardQuantum>::
size_t bitVectorSizeInBytes = (upperBound / 8) + 1; size_t bitVectorSizeInBytes = (upperBound / 8) + 1;
layout.bits = bitVectorSizeInBytes; layout.bits = bitVectorSizeInBytes;
if (skipQuantum != 0) { if constexpr (skipQuantum != 0) {
size_t numSkipPointers = upperBound / skipQuantum; size_t numSkipPointers = upperBound / skipQuantum;
layout.skipPointers = numSkipPointers * sizeof(SkipValueType); layout.skipPointers = numSkipPointers * sizeof(SkipValueType);
} }
if (forwardQuantum != 0) { if constexpr (forwardQuantum != 0) {
size_t numForwardPointers = size / forwardQuantum; size_t numForwardPointers = size / forwardQuantum;
layout.forwardPointers = numForwardPointers * sizeof(SkipValueType); layout.forwardPointers = numForwardPointers * sizeof(SkipValueType);
} }
...@@ -305,7 +305,8 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>, ...@@ -305,7 +305,8 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
position_ += n; position_ += n;
// Use forward pointer. // Use forward pointer.
if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) { if constexpr (Encoder::forwardQuantum > 0) {
if (n > Encoder::forwardQuantum) {
const size_t steps = position_ / Encoder::forwardQuantum; const size_t steps = position_ / Encoder::forwardQuantum;
const size_t dest = folly::loadUnaligned<SkipValueType>( const size_t dest = folly::loadUnaligned<SkipValueType>(
this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType)); this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
...@@ -313,6 +314,7 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>, ...@@ -313,6 +314,7 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
reposition(dest); reposition(dest);
n = position_ + 1 - steps * Encoder::forwardQuantum; n = position_ + 1 - steps * Encoder::forwardQuantum;
} }
}
size_t cnt; size_t cnt;
// Find necessary block. // Find necessary block.
...@@ -351,7 +353,8 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>, ...@@ -351,7 +353,8 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
return true; return true;
} }
if (Encoder::skipQuantum > 0 && v - value_ > Encoder::skipQuantum) { if constexpr (Encoder::skipQuantum > 0) {
if (v - value_ > Encoder::skipQuantum) {
size_t q = v / Encoder::skipQuantum; size_t q = v / Encoder::skipQuantum;
auto skipPointer = folly::loadUnaligned<SkipValueType>( auto skipPointer = folly::loadUnaligned<SkipValueType>(
this->skipPointers_ + (q - 1) * sizeof(SkipValueType)); this->skipPointers_ + (q - 1) * sizeof(SkipValueType));
...@@ -359,6 +362,7 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>, ...@@ -359,6 +362,7 @@ class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
reposition(q * Encoder::skipQuantum); reposition(q * Encoder::skipQuantum);
} }
}
// Find the value. // Find the value.
size_t outer = v / 64 * sizeof(uint64_t); size_t outer = v / 64 * sizeof(uint64_t);
......
...@@ -411,7 +411,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -411,7 +411,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
position_ += n; // n 1-bits will be read. position_ += n; // n 1-bits will be read.
// Use forward pointer. // Use forward pointer.
if (Encoder::forwardQuantum > 0 && UNLIKELY(n > Encoder::forwardQuantum)) { if constexpr (Encoder::forwardQuantum > 0) {
if (UNLIKELY(n > Encoder::forwardQuantum)) {
const size_t steps = position_ / Encoder::forwardQuantum; const size_t steps = position_ / Encoder::forwardQuantum;
const size_t dest = loadUnaligned<SkipValueType>( const size_t dest = loadUnaligned<SkipValueType>(
this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType)); this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
...@@ -419,6 +420,7 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -419,6 +420,7 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
reposition(dest + steps * Encoder::forwardQuantum); reposition(dest + steps * Encoder::forwardQuantum);
n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0. n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0.
} }
}
size_t cnt; size_t cnt;
// Find necessary block. // Find necessary block.
...@@ -442,8 +444,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -442,8 +444,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
DCHECK_GE(v, value_); DCHECK_GE(v, value_);
// Use skip pointer. // Use skip pointer.
if (Encoder::skipQuantum > 0 && if constexpr (Encoder::skipQuantum > 0) {
UNLIKELY(v >= value_ + Encoder::skipQuantum)) { if (UNLIKELY(v >= value_ + Encoder::skipQuantum)) {
const size_t steps = v / Encoder::skipQuantum; const size_t steps = v / Encoder::skipQuantum;
const size_t dest = loadUnaligned<SkipValueType>( const size_t dest = loadUnaligned<SkipValueType>(
this->skipPointers_ + (steps - 1) * sizeof(SkipValueType)); this->skipPointers_ + (steps - 1) * sizeof(SkipValueType));
...@@ -457,6 +459,7 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -457,6 +459,7 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
// prefetched here (via __builtin_prefetch), but experiments // prefetched here (via __builtin_prefetch), but experiments
// didn't show any significant improvements. // didn't show any significant improvements.
} }
}
// Skip by blocks. // Skip by blocks.
size_t cnt; size_t cnt;
...@@ -492,7 +495,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -492,7 +495,8 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
FOLLY_ALWAYS_INLINE SizeType prepareSkipTo(ValueType v) const { FOLLY_ALWAYS_INLINE SizeType prepareSkipTo(ValueType v) const {
auto position = position_; auto position = position_;
if (Encoder::skipQuantum > 0 && v >= value_ + Encoder::skipQuantum) { if constexpr (Encoder::skipQuantum > 0) {
if (v >= value_ + Encoder::skipQuantum) {
auto outer = outer_; auto outer = outer_;
const size_t steps = v / Encoder::skipQuantum; const size_t steps = v / Encoder::skipQuantum;
const size_t dest = loadUnaligned<SkipValueType>( const size_t dest = loadUnaligned<SkipValueType>(
...@@ -504,13 +508,15 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -504,13 +508,15 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
// Prefetch up to the beginning of where we linear search. After that, // Prefetch up to the beginning of where we linear search. After that,
// hardware prefetching will outperform our own. In addition, this // hardware prefetching will outperform our own. In addition, this
// simplifies calculating what to prefetch as we don't have to calculate // simplifies calculating what to prefetch as we don't have to calculate
// the entire destination address. Two cache lines are prefetched because // the entire destination address. Two cache lines are prefetched
// this results in fewer cycles used (based on practical results) than // because this results in fewer cycles used (based on practical
// one. However, three cache lines does not have any additional effect. // results) than one. However, three cache lines does not have any
// additional effect.
const auto addr = start_ + outer; const auto addr = start_ + outer;
__builtin_prefetch(addr); __builtin_prefetch(addr);
__builtin_prefetch(addr + kCacheLineSize); __builtin_prefetch(addr + kCacheLineSize);
} }
}
return position; return position;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment