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