aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/include/llvm/Support/Discriminator.h
blob: 8f957f7ea8f65d5af38db355d7924b44f94a7be1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===---- llvm/Support/Discriminator.h -- Discriminator Utils ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the constants and utility functions for discriminators.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_DISCRIMINATOR_H
#define LLVM_SUPPORT_DISCRIMINATOR_H

#include "llvm/Support/Error.h"
#include <assert.h>

// Utility functions for encoding / decoding discriminators.
/// With a given unsigned int \p U, use up to 13 bits to represent it.
/// old_bit 1~5  --> new_bit 1~5
/// old_bit 6~12 --> new_bit 7~13
/// new_bit_6 is 0 if higher bits (7~13) are all 0
static inline unsigned getPrefixEncodingFromUnsigned(unsigned U) {
  U &= 0xfff;
  return U > 0x1f ? (((U & 0xfe0) << 1) | (U & 0x1f) | 0x20) : U;
}

/// Reverse transformation as getPrefixEncodingFromUnsigned.
static inline unsigned getUnsignedFromPrefixEncoding(unsigned U) {
  if (U & 1)
    return 0;
  U >>= 1;
  return (U & 0x20) ? (((U >> 1) & 0xfe0) | (U & 0x1f)) : (U & 0x1f);
}

/// Returns the next component stored in discriminator.
static inline unsigned getNextComponentInDiscriminator(unsigned D) {
  if ((D & 1) == 0)
    return D >> ((D & 0x40) ? 14 : 7);
  else
    return D >> 1;
}

static inline unsigned encodeComponent(unsigned C) {
  return (C == 0) ? 1U : (getPrefixEncodingFromUnsigned(C) << 1);
}

static inline unsigned encodingBits(unsigned C) {
  return (C == 0) ? 1 : (C > 0x1f ? 14 : 7);
}

// Some constants used in FS Discriminators.
//
namespace llvm {
namespace sampleprof {
enum FSDiscriminatorPass {
  Base = 0,
  Pass0 = 0,
  Pass1 = 1,
  Pass2 = 2,
  Pass3 = 3,
  Pass4 = 4,
  PassLast = 4,
};
} // namespace sampleprof

using namespace sampleprof;

// The number of bits reserved for the base discrimininator. The base
// discriminaitor starts from bit 0.
static const unsigned BaseDiscriminatorBitWidth = 8;

// The number of bits reserved for each FS discriminator pass.
static const unsigned FSDiscriminatorBitWidth = 6;

// Return the number of FS passes, excluding the pass adding the base
// discriminators.
// The number of passes for FS discriminators. Note that the total
// number of discriminaitor bits, i.e.
// BaseDiscriminatorBitWidth
//  + FSDiscriminatorBitWidth * getNumFSPasses()
// needs to fit in an unsigned int type.
static inline unsigned getNumFSPasses() {
  return static_cast<unsigned>(FSDiscriminatorPass::PassLast);
}

// Return the ending bit for FSPass P.
static inline unsigned getFSPassBitEnd(FSDiscriminatorPass P) {
  unsigned I = static_cast<unsigned>(P);
  assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number.");
  return BaseDiscriminatorBitWidth + I * FSDiscriminatorBitWidth - 1;
}

// Return the begining bit for FSPass P.
static inline unsigned getFSPassBitBegin(FSDiscriminatorPass P) {
  if (P == FSDiscriminatorPass::Base)
    return 0;
  unsigned I = static_cast<unsigned>(P);
  assert(I <= getNumFSPasses() && "Invalid FS discriminator pass number.");
  return getFSPassBitEnd(static_cast<FSDiscriminatorPass>(I - 1)) + 1;
}

// Return the beginning bit for the last FSPass.
static inline int getLastFSPassBitBegin() {
  return getFSPassBitBegin(static_cast<FSDiscriminatorPass>(getNumFSPasses()));
}

// Return the ending bit for the last FSPass.
static inline unsigned getLastFSPassBitEnd() {
  return getFSPassBitEnd(static_cast<FSDiscriminatorPass>(getNumFSPasses()));
}

// Return the beginning bit for the base (first) FSPass.
static inline unsigned getBaseFSBitBegin() { return 0; }

// Return the ending bit for the base (first) FSPass.
static inline unsigned getBaseFSBitEnd() {
  return BaseDiscriminatorBitWidth - 1;
}

// Set bits in range of [0 .. n] to 1. Used in FS Discriminators.
static inline unsigned getN1Bits(int N) {
  // Work around the g++ bug that folding "(1U << (N + 1)) - 1" to 0.
  if (N == 31)
    return 0xFFFFFFFF;
  assert((N < 32) && "N is invalid");
  return (1U << (N + 1)) - 1;
}

} // namespace llvm

#endif /* LLVM_SUPPORT_DISCRIMINATOR_H */

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif