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