1226584Sdim//===-------- BlockFrequency.h - Block Frequency Wrapper --------*- C++ -*-===//
2226584Sdim//
3226584Sdim//                     The LLVM Compiler Infrastructure
4226584Sdim//
5226584Sdim// This file is distributed under the University of Illinois Open Source
6226584Sdim// License. See LICENSE.TXT for details.
7226584Sdim//
8226584Sdim//===----------------------------------------------------------------------===//
9226584Sdim//
10226584Sdim// This file implements Block Frequency class.
11226584Sdim//
12226584Sdim//===----------------------------------------------------------------------===//
13226584Sdim
14226584Sdim#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H
15226584Sdim#define LLVM_SUPPORT_BLOCKFREQUENCY_H
16226584Sdim
17235633Sdim#include "llvm/Support/DataTypes.h"
18235633Sdim
19226584Sdimnamespace llvm {
20226584Sdim
21226584Sdimclass raw_ostream;
22226584Sdimclass BranchProbability;
23226584Sdim
24226584Sdim// This class represents Block Frequency as a 64-bit value.
25226584Sdimclass BlockFrequency {
26226584Sdim
27226584Sdim  uint64_t Frequency;
28263509Sdim  static const int64_t ENTRY_FREQ = 1 << 14;
29226584Sdim
30263509Sdim  /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
31263509Sdim  /// the division by D. Upon overflow, the routine will saturate and
32263509Sdim  /// additionally will return the remainder set to D.
33263509Sdim  uint32_t scale(uint32_t N, uint32_t D);
34263509Sdim
35226584Sdimpublic:
36226584Sdim  BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
37226584Sdim
38263509Sdim  /// \brief Returns the frequency of the entry block of the function.
39226584Sdim  static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
40263509Sdim
41263509Sdim  /// \brief Returns the maximum possible frequency, the saturation value.
42263509Sdim  static uint64_t getMaxFrequency() { return -1ULL; }
43263509Sdim
44263509Sdim  /// \brief Returns the frequency as a fixpoint number scaled by the entry
45263509Sdim  /// frequency.
46226584Sdim  uint64_t getFrequency() const { return Frequency; }
47226584Sdim
48263509Sdim  /// \brief Multiplies with a branch probability. The computation will never
49263509Sdim  /// overflow.
50226584Sdim  BlockFrequency &operator*=(const BranchProbability &Prob);
51226584Sdim  const BlockFrequency operator*(const BranchProbability &Prob) const;
52226584Sdim
53263509Sdim  /// \brief Divide by a non-zero branch probability using saturating
54263509Sdim  /// arithmetic.
55263509Sdim  BlockFrequency &operator/=(const BranchProbability &Prob);
56263509Sdim  BlockFrequency operator/(const BranchProbability &Prob) const;
57263509Sdim
58263509Sdim  /// \brief Adds another block frequency using saturating arithmetic.
59226584Sdim  BlockFrequency &operator+=(const BlockFrequency &Freq);
60226584Sdim  const BlockFrequency operator+(const BlockFrequency &Freq) const;
61226584Sdim
62263509Sdim  /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
63263509Sdim  /// the division by D. Upon overflow, the routine will saturate.
64263509Sdim  uint32_t scale(const BranchProbability &Prob);
65263509Sdim
66226584Sdim  bool operator<(const BlockFrequency &RHS) const {
67226584Sdim    return Frequency < RHS.Frequency;
68226584Sdim  }
69226584Sdim
70226584Sdim  bool operator<=(const BlockFrequency &RHS) const {
71226584Sdim    return Frequency <= RHS.Frequency;
72226584Sdim  }
73226584Sdim
74226584Sdim  bool operator>(const BlockFrequency &RHS) const {
75226584Sdim    return Frequency > RHS.Frequency;
76226584Sdim  }
77226584Sdim
78226584Sdim  bool operator>=(const BlockFrequency &RHS) const {
79226584Sdim    return Frequency >= RHS.Frequency;
80226584Sdim  }
81226584Sdim
82226584Sdim  void print(raw_ostream &OS) const;
83226584Sdim};
84226584Sdim
85226584Sdimraw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq);
86226584Sdim
87226584Sdim}
88226584Sdim
89226584Sdim#endif
90