1 | //===---- llvm/Support/Discriminator.h -- Discriminator Utils ---*- 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 defines the constants and utility functions for discriminators. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_SUPPORT_DISCRIMINATOR_H |
14 | #define LLVM_SUPPORT_DISCRIMINATOR_H |
15 | |
16 | #include "llvm/Support/Error.h" |
17 | #include <assert.h> |
18 | |
19 | // Utility functions for encoding / decoding discriminators. |
20 | /// With a given unsigned int \p U, use up to 13 bits to represent it. |
21 | /// old_bit 1~5 --> new_bit 1~5 |
22 | /// old_bit 6~12 --> new_bit 7~13 |
23 | /// new_bit_6 is 0 if higher bits (7~13) are all 0 |
24 | static inline unsigned getPrefixEncodingFromUnsigned(unsigned U) { |
25 | U &= 0xfff; |
26 | return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U; |
27 | } |
28 | |
29 | /// Reverse transformation as getPrefixEncodingFromUnsigned. |
30 | static inline unsigned getUnsignedFromPrefixEncoding(unsigned U) { |
31 | if (U & 1) |
32 | return 0; |
33 | U >>= 1; |
34 | return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f); |
35 | } |
36 | |
37 | /// Returns the next component stored in discriminator. |
38 | static inline unsigned getNextComponentInDiscriminator(unsigned D) { |
39 | if ((D & 1) == 0) |
40 | return D >> ((D & 0x40) ? 14 : 7); |
41 | else |
42 | return D >> 1; |
43 | } |
44 | |
45 | static inline unsigned encodeComponent(unsigned C) { |
46 | return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(U: C) << 1); |
47 | } |
48 | |
49 | static inline unsigned encodingBits(unsigned C) { |
50 | return (C == 0) ? 1 : (C > 0x1f ? 14 : 7); |
51 | } |
52 | |
53 | // Some constants used in FS Discriminators. |
54 | // |
55 | namespace llvm { |
56 | namespace sampleprof { |
57 | enum FSDiscriminatorPass { |
58 | Base = 0, |
59 | Pass0 = 0, |
60 | Pass1 = 1, |
61 | Pass2 = 2, |
62 | Pass3 = 3, |
63 | Pass4 = 4, |
64 | PassLast = 4, |
65 | }; |
66 | } // namespace sampleprof |
67 | |
68 | // The number of bits reserved for the base discrimininator. The base |
69 | // discriminaitor starts from bit 0. |
70 | static const unsigned BaseDiscriminatorBitWidth = 8; |
71 | |
72 | // The number of bits reserved for each FS discriminator pass. |
73 | static const unsigned FSDiscriminatorBitWidth = 6; |
74 | |
75 | // Return the number of FS passes, excluding the pass adding the base |
76 | // discriminators. |
77 | // The number of passes for FS discriminators. Note that the total |
78 | // number of discriminaitor bits, i.e. |
79 | // BaseDiscriminatorBitWidth |
80 | // + FSDiscriminatorBitWidth * getNumFSPasses() |
81 | // needs to fit in an unsigned int type. |
82 | static inline unsigned getNumFSPasses() { |
83 | return static_cast<unsigned>(sampleprof::FSDiscriminatorPass::PassLast); |
84 | } |
85 | |
86 | // Return the ending bit for FSPass P. |
87 | static inline unsigned getFSPassBitEnd(sampleprof::FSDiscriminatorPass P) { |
88 | unsigned I = static_cast<unsigned>(P); |
89 | assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number." ); |
90 | return BaseDiscriminatorBitWidth + I * FSDiscriminatorBitWidth - 1; |
91 | } |
92 | |
93 | // Return the begining bit for FSPass P. |
94 | static inline unsigned getFSPassBitBegin(sampleprof::FSDiscriminatorPass P) { |
95 | if (P == sampleprof::FSDiscriminatorPass::Base) |
96 | return 0; |
97 | unsigned I = static_cast<unsigned>(P); |
98 | assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number." ); |
99 | return getFSPassBitEnd(P: static_cast<sampleprof::FSDiscriminatorPass>(I - 1)) + |
100 | 1; |
101 | } |
102 | |
103 | // Return the beginning bit for the last FSPass. |
104 | static inline int getLastFSPassBitBegin() { |
105 | return getFSPassBitBegin( |
106 | P: static_cast<sampleprof::FSDiscriminatorPass>(getNumFSPasses())); |
107 | } |
108 | |
109 | // Return the ending bit for the last FSPass. |
110 | static inline unsigned getLastFSPassBitEnd() { |
111 | return getFSPassBitEnd( |
112 | P: static_cast<sampleprof::FSDiscriminatorPass>(getNumFSPasses())); |
113 | } |
114 | |
115 | // Return the beginning bit for the base (first) FSPass. |
116 | static inline unsigned getBaseFSBitBegin() { return 0; } |
117 | |
118 | // Return the ending bit for the base (first) FSPass. |
119 | static inline unsigned getBaseFSBitEnd() { |
120 | return BaseDiscriminatorBitWidth - 1; |
121 | } |
122 | |
123 | // Set bits in range of [0 .. n] to 1. Used in FS Discriminators. |
124 | static inline unsigned getN1Bits(int N) { |
125 | // Work around the g++ bug that folding "(1U << (N + 1)) - 1" to 0. |
126 | if (N == 31) |
127 | return 0xFFFFFFFF; |
128 | assert((N < 32) && "N is invalid" ); |
129 | return (1U << (N + 1)) - 1; |
130 | } |
131 | |
132 | } // namespace llvm |
133 | |
134 | #endif /* LLVM_SUPPORT_DISCRIMINATOR_H */ |
135 | |