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