xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/BlockFrequency.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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