aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2023-10-24 20:27:39 -0700
committerGitHub <noreply@github.com>2023-10-24 20:27:39 -0700
commite3cf80c5c1fe55efd8216575ccadea0ab087e79c (patch)
tree879bf301a8bd840d2ed60eb8216fb82f6a6d9eb4 /llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
parent69ade08b4a1ade66e61b3f9f095553a71e452873 (diff)
downloadllvm-e3cf80c5c1fe55efd8216575ccadea0ab087e79c.zip
llvm-e3cf80c5c1fe55efd8216575ccadea0ab087e79c.tar.gz
llvm-e3cf80c5c1fe55efd8216575ccadea0ab087e79c.tar.bz2
BlockFrequencyInfoImpl: Avoid big numbers, increase precision for small spreads
BlockFrequencyInfo calculates block frequencies as Scaled64 numbers but as a last step converts them to unsigned 64bit integers (`BlockFrequency`). This improves the factors picked for this conversion so that: * Avoid big numbers close to UINT64_MAX to avoid users overflowing/saturating when adding multiply frequencies together or when multiplying with integers. This leaves the topmost 10 bits unused to allow for some room. * Spread the difference between hottest/coldest block as much as possible to increase precision. * If the hot/cold spread cannot be represented loose precision at the lower end, but keep the frequencies at the upper end for hot blocks differentiable.
Diffstat (limited to 'llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp')
-rw-r--r--llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp34
1 files changed, 14 insertions, 20 deletions
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
index 6f94499..ae08d56 100644
--- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
+++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
@@ -481,30 +481,24 @@ void BlockFrequencyInfoImplBase::distributeMass(const BlockNode &Source,
static void convertFloatingToInteger(BlockFrequencyInfoImplBase &BFI,
const Scaled64 &Min, const Scaled64 &Max) {
- // Scale the Factor to a size that creates integers. Ideally, integers would
- // be scaled so that Max == UINT64_MAX so that they can be best
- // differentiated. However, in the presence of large frequency values, small
- // frequencies are scaled down to 1, making it impossible to differentiate
- // small, unequal numbers. When the spread between Min and Max frequencies
- // fits well within MaxBits, we make the scale be at least 8.
- const unsigned MaxBits = 64;
- const unsigned SpreadBits = (Max / Min).lg();
- Scaled64 ScalingFactor;
- if (SpreadBits <= MaxBits - 3) {
- // If the values are small enough, make the scaling factor at least 8 to
- // allow distinguishing small values.
- ScalingFactor = Min.inverse();
- ScalingFactor <<= 3;
- } else {
- // If the values need more than MaxBits to be represented, saturate small
- // frequency values down to 1 by using a scaling factor that benefits large
- // frequency values.
- ScalingFactor = Scaled64(1, MaxBits) / Max;
- }
+ // Scale the Factor to a size that creates integers. If possible scale
+ // integers so that Max == UINT64_MAX so that they can be best differentiated.
+ // Is is possible that the range between min and max cannot be accurately
+ // represented in a 64bit integer without either loosing precision for small
+ // values (so small unequal numbers all map to 1) or saturaturing big numbers
+ // loosing precision for big numbers (so unequal big numbers may map to
+ // UINT64_MAX). We choose to loose precision for small numbers.
+ const unsigned MaxBits = sizeof(Scaled64::DigitsType) * CHAR_BIT;
+ // Users often add up multiple BlockFrequency values or multiply them with
+ // things like instruction costs. Leave some room to avoid saturating
+ // operations reaching UIN64_MAX too early.
+ const unsigned Slack = 10;
+ Scaled64 ScalingFactor = Scaled64(1, MaxBits - Slack) / Max;
// Translate the floats to integers.
LLVM_DEBUG(dbgs() << "float-to-int: min = " << Min << ", max = " << Max
<< ", factor = " << ScalingFactor << "\n");
+ (void)Min;
for (size_t Index = 0; Index < BFI.Freqs.size(); ++Index) {
Scaled64 Scaled = BFI.Freqs[Index].Scaled * ScalingFactor;
BFI.Freqs[Index].Integer = std::max(UINT64_C(1), Scaled.toInt<uint64_t>());