2021-05-19 01:08:38 +02:00
|
|
|
//===---- 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
|
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
#include "llvm/Support/Error.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
2021-05-19 01:08:38 +02:00
|
|
|
// 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.
|
2021-05-27 20:34:22 +02:00
|
|
|
//
|
|
|
|
namespace llvm {
|
|
|
|
namespace sampleprof {
|
2021-06-04 20:02:11 +02:00
|
|
|
enum FSDiscriminatorPass {
|
2021-05-27 20:34:22 +02:00
|
|
|
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;
|
|
|
|
}
|
2021-05-19 01:08:38 +02:00
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
// Return the beginning bit for the last FSPass.
|
|
|
|
static inline int getLastFSPassBitBegin() {
|
|
|
|
return getFSPassBitBegin(static_cast<FSDiscriminatorPass>(getNumFSPasses()));
|
|
|
|
}
|
2021-05-19 01:08:38 +02:00
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
// Return the ending bit for the last FSPass.
|
|
|
|
static inline unsigned getLastFSPassBitEnd() {
|
|
|
|
return getFSPassBitEnd(static_cast<FSDiscriminatorPass>(getNumFSPasses()));
|
|
|
|
}
|
2021-05-19 01:08:38 +02:00
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
// Return the beginning bit for the base (first) FSPass.
|
|
|
|
static inline unsigned getBaseFSBitBegin() { return 0; }
|
2021-05-19 01:08:38 +02:00
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
// Return the ending bit for the base (first) FSPass.
|
|
|
|
static inline unsigned getBaseFSBitEnd() {
|
|
|
|
return BaseDiscriminatorBitWidth - 1;
|
|
|
|
}
|
2021-05-19 01:08:38 +02:00
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
// Set bits in range of [0 .. n] to 1. Used in FS Discriminators.
|
2021-05-19 01:08:38 +02:00
|
|
|
static inline unsigned getN1Bits(int N) {
|
2021-05-27 20:34:22 +02:00
|
|
|
// Work around the g++ bug that folding "(1U << (N + 1)) - 1" to 0.
|
|
|
|
if (N == 31)
|
2021-05-19 01:08:38 +02:00
|
|
|
return 0xFFFFFFFF;
|
2021-05-27 20:34:22 +02:00
|
|
|
assert((N < 32) && "N is invalid");
|
|
|
|
return (1U << (N + 1)) - 1;
|
2021-05-19 01:08:38 +02:00
|
|
|
}
|
|
|
|
|
2021-05-27 20:34:22 +02:00
|
|
|
} // namespace llvm
|
|
|
|
|
2021-05-19 01:08:38 +02:00
|
|
|
#endif /* LLVM_SUPPORT_DISCRIMINATOR_H */
|