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