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 19 namespace llvm { 20 21 class BranchProbability; 22 23 // This class represents Block Frequency as a 64-bit value. 24 class BlockFrequency { 25 uint64_t Frequency; 26 27 public: 28 BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { } 29 30 /// Returns the maximum possible frequency, the saturation value. 31 static uint64_t getMaxFrequency() { return UINT64_MAX; } 32 33 /// Returns the frequency as a fixpoint number scaled by the entry 34 /// frequency. 35 uint64_t getFrequency() const { return Frequency; } 36 37 /// Multiplies with a branch probability. The computation will never 38 /// overflow. 39 BlockFrequency &operator*=(BranchProbability Prob); 40 BlockFrequency operator*(BranchProbability Prob) const; 41 42 /// Divide by a non-zero branch probability using saturating 43 /// arithmetic. 44 BlockFrequency &operator/=(BranchProbability Prob); 45 BlockFrequency operator/(BranchProbability Prob) const; 46 47 /// Adds another block frequency using saturating arithmetic. 48 BlockFrequency &operator+=(BlockFrequency Freq) { 49 uint64_t Before = Freq.Frequency; 50 Frequency += Freq.Frequency; 51 52 // If overflow, set frequency to the maximum value. 53 if (Frequency < Before) 54 Frequency = UINT64_MAX; 55 56 return *this; 57 } 58 BlockFrequency operator+(BlockFrequency Freq) const { 59 BlockFrequency NewFreq(Frequency); 60 NewFreq += Freq; 61 return NewFreq; 62 } 63 64 /// Subtracts another block frequency using saturating arithmetic. 65 BlockFrequency &operator-=(BlockFrequency Freq) { 66 // If underflow, set frequency to 0. 67 if (Frequency <= Freq.Frequency) 68 Frequency = 0; 69 else 70 Frequency -= Freq.Frequency; 71 return *this; 72 } 73 BlockFrequency operator-(BlockFrequency Freq) const { 74 BlockFrequency NewFreq(Frequency); 75 NewFreq -= Freq; 76 return NewFreq; 77 } 78 79 /// Shift block frequency to the right by count digits saturating to 1. 80 BlockFrequency &operator>>=(const unsigned count) { 81 // Frequency can never be 0 by design. 82 assert(Frequency != 0); 83 84 // Shift right by count. 85 Frequency >>= count; 86 87 // Saturate to 1 if we are 0. 88 Frequency |= Frequency == 0; 89 return *this; 90 } 91 92 bool operator<(BlockFrequency RHS) const { 93 return Frequency < RHS.Frequency; 94 } 95 96 bool operator<=(BlockFrequency RHS) const { 97 return Frequency <= RHS.Frequency; 98 } 99 100 bool operator>(BlockFrequency RHS) const { 101 return Frequency > RHS.Frequency; 102 } 103 104 bool operator>=(BlockFrequency RHS) const { 105 return Frequency >= RHS.Frequency; 106 } 107 108 bool operator==(BlockFrequency RHS) const { 109 return Frequency == RHS.Frequency; 110 } 111 }; 112 113 } // namespace llvm 114 115 #endif 116