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