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: |
29 | BlockFrequency() : Frequency(0) {} |
30 | explicit BlockFrequency(uint64_t Freq) : Frequency(Freq) {} |
31 | |
32 | /// Returns the maximum possible frequency, the saturation value. |
33 | static BlockFrequency max() { return BlockFrequency(UINT64_MAX); } |
34 | |
35 | /// Returns the frequency as a fixpoint number scaled by the entry |
36 | /// frequency. |
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 |