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(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 using namespace sampleprof; 69 70 // The number of bits reserved for the base discrimininator. The base 71 // discriminaitor starts from bit 0. 72 static const unsigned BaseDiscriminatorBitWidth = 8; 73 74 // The number of bits reserved for each FS discriminator pass. 75 static const unsigned FSDiscriminatorBitWidth = 6; 76 77 // Return the number of FS passes, excluding the pass adding the base 78 // discriminators. 79 // The number of passes for FS discriminators. Note that the total 80 // number of discriminaitor bits, i.e. 81 // BaseDiscriminatorBitWidth 82 // + FSDiscriminatorBitWidth * getNumFSPasses() 83 // needs to fit in an unsigned int type. 84 static inline unsigned getNumFSPasses() { 85 return static_cast<unsigned>(FSDiscriminatorPass::PassLast); 86 } 87 88 // Return the ending bit for FSPass P. 89 static inline unsigned getFSPassBitEnd(FSDiscriminatorPass P) { 90 unsigned I = static_cast<unsigned>(P); 91 assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number."); 92 return BaseDiscriminatorBitWidth + I * FSDiscriminatorBitWidth - 1; 93 } 94 95 // Return the begining bit for FSPass P. 96 static inline unsigned getFSPassBitBegin(FSDiscriminatorPass P) { 97 if (P == FSDiscriminatorPass::Base) 98 return 0; 99 unsigned I = static_cast<unsigned>(P); 100 assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number."); 101 return getFSPassBitEnd(static_cast<FSDiscriminatorPass>(I - 1)) + 1; 102 } 103 104 // Return the beginning bit for the last FSPass. 105 static inline int getLastFSPassBitBegin() { 106 return getFSPassBitBegin(static_cast<FSDiscriminatorPass>(getNumFSPasses())); 107 } 108 109 // Return the ending bit for the last FSPass. 110 static inline unsigned getLastFSPassBitEnd() { 111 return getFSPassBitEnd(static_cast<FSDiscriminatorPass>(getNumFSPasses())); 112 } 113 114 // Return the beginning bit for the base (first) FSPass. 115 static inline unsigned getBaseFSBitBegin() { return 0; } 116 117 // Return the ending bit for the base (first) FSPass. 118 static inline unsigned getBaseFSBitEnd() { 119 return BaseDiscriminatorBitWidth - 1; 120 } 121 122 // Set bits in range of [0 .. n] to 1. Used in FS Discriminators. 123 static inline unsigned getN1Bits(int N) { 124 // Work around the g++ bug that folding "(1U << (N + 1)) - 1" to 0. 125 if (N == 31) 126 return 0xFFFFFFFF; 127 assert((N < 32) && "N is invalid"); 128 return (1U << (N + 1)) - 1; 129 } 130 131 } // namespace llvm 132 133 #endif /* LLVM_SUPPORT_DISCRIMINATOR_H */ 134