1 //===-------- BlockFrequency.h - Block Frequency Wrapper --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements Block Frequency class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H 14 #define LLVM_SUPPORT_BLOCKFREQUENCY_H 15 16 #include <cassert> 17 #include <cstdint> 18 #include <optional> 19 20 namespace llvm { 21 22 class BranchProbability; 23 24 // This class represents Block Frequency as a 64-bit value. 25 class BlockFrequency { 26 uint64_t Frequency; 27 28 public: BlockFrequency()29 BlockFrequency() : Frequency(0) {} BlockFrequency(uint64_t Freq)30 explicit BlockFrequency(uint64_t Freq) : Frequency(Freq) {} 31 32 /// Returns the maximum possible frequency, the saturation value. max()33 static BlockFrequency max() { return BlockFrequency(UINT64_MAX); } 34 35 /// Returns the frequency as a fixpoint number scaled by the entry 36 /// frequency. getFrequency()37 uint64_t getFrequency() const { return Frequency; } 38 39 /// Multiplies with a branch probability. The computation will never 40 /// overflow. 41 BlockFrequency &operator*=(BranchProbability Prob); 42 BlockFrequency operator*(BranchProbability Prob) const; 43 44 /// Divide by a non-zero branch probability using saturating 45 /// arithmetic. 46 BlockFrequency &operator/=(BranchProbability Prob); 47 BlockFrequency operator/(BranchProbability Prob) const; 48 49 /// Adds another block frequency using saturating arithmetic. 50 BlockFrequency &operator+=(BlockFrequency Freq) { 51 uint64_t Before = Freq.Frequency; 52 Frequency += Freq.Frequency; 53 54 // If overflow, set frequency to the maximum value. 55 if (Frequency < Before) 56 Frequency = UINT64_MAX; 57 58 return *this; 59 } 60 BlockFrequency operator+(BlockFrequency Freq) const { 61 BlockFrequency NewFreq(Frequency); 62 NewFreq += Freq; 63 return NewFreq; 64 } 65 66 /// Subtracts another block frequency using saturating arithmetic. 67 BlockFrequency &operator-=(BlockFrequency Freq) { 68 // If underflow, set frequency to 0. 69 if (Frequency <= Freq.Frequency) 70 Frequency = 0; 71 else 72 Frequency -= Freq.Frequency; 73 return *this; 74 } 75 BlockFrequency operator-(BlockFrequency Freq) const { 76 BlockFrequency NewFreq(Frequency); 77 NewFreq -= Freq; 78 return NewFreq; 79 } 80 81 /// Multiplies frequency with `Factor`. Returns `nullopt` in case of overflow. 82 std::optional<BlockFrequency> mul(uint64_t Factor) const; 83 84 /// Shift block frequency to the right by count digits saturating to 1. 85 BlockFrequency &operator>>=(const unsigned count) { 86 // Frequency can never be 0 by design. 87 assert(Frequency != 0); 88 89 // Shift right by count. 90 Frequency >>= count; 91 92 // Saturate to 1 if we are 0. 93 Frequency |= Frequency == 0; 94 return *this; 95 } 96 97 bool operator<(BlockFrequency RHS) const { 98 return Frequency < RHS.Frequency; 99 } 100 101 bool operator<=(BlockFrequency RHS) const { 102 return Frequency <= RHS.Frequency; 103 } 104 105 bool operator>(BlockFrequency RHS) const { 106 return Frequency > RHS.Frequency; 107 } 108 109 bool operator>=(BlockFrequency RHS) const { 110 return Frequency >= RHS.Frequency; 111 } 112 113 bool operator==(BlockFrequency RHS) const { 114 return Frequency == RHS.Frequency; 115 } 116 117 bool operator!=(BlockFrequency RHS) const { 118 return Frequency != RHS.Frequency; 119 } 120 }; 121 122 } // namespace llvm 123 124 #endif 125