
## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/ProfileData` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS on Linux: - Manually annotate the file `llvm/include/llvm/ProfileData/InstrProfData.inc` because it is skipped by IDS - Add `LLVM_TEMPLATE_ABI` and `LLVM_EXPORT_TEMPLATE` to exported instantiated templates. - Add `LLVM_ABI_FRIEND` to friend member functions declared with `LLVM_ABI` - Add `LLVM_ABI` to a small number of symbols that require export but are not declared in headers ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang
83 lines
3.5 KiB
C++
83 lines
3.5 KiB
C++
//=-- MemProfCommon.cpp - MemProf common utilities ---------------=//
|
|
//
|
|
// 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 contains MemProf common utilities.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ProfileData/MemProfCommon.h"
|
|
#include "llvm/ProfileData/MemProf.h"
|
|
#include "llvm/Support/BLAKE3.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/HashBuilder.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::memprof;
|
|
|
|
// Upper bound on lifetime access density (accesses per byte per lifetime sec)
|
|
// for marking an allocation cold.
|
|
LLVM_ABI cl::opt<float> MemProfLifetimeAccessDensityColdThreshold(
|
|
"memprof-lifetime-access-density-cold-threshold", cl::init(0.05),
|
|
cl::Hidden,
|
|
cl::desc("The threshold the lifetime access density (accesses per byte per "
|
|
"lifetime sec) must be under to consider an allocation cold"));
|
|
|
|
// Lower bound on lifetime to mark an allocation cold (in addition to accesses
|
|
// per byte per sec above). This is to avoid pessimizing short lived objects.
|
|
LLVM_ABI cl::opt<unsigned> MemProfAveLifetimeColdThreshold(
|
|
"memprof-ave-lifetime-cold-threshold", cl::init(200), cl::Hidden,
|
|
cl::desc("The average lifetime (s) for an allocation to be considered "
|
|
"cold"));
|
|
|
|
// Lower bound on average lifetime accesses density (total life time access
|
|
// density / alloc count) for marking an allocation hot.
|
|
LLVM_ABI cl::opt<unsigned> MemProfMinAveLifetimeAccessDensityHotThreshold(
|
|
"memprof-min-ave-lifetime-access-density-hot-threshold", cl::init(1000),
|
|
cl::Hidden,
|
|
cl::desc("The minimum TotalLifetimeAccessDensity / AllocCount for an "
|
|
"allocation to be considered hot"));
|
|
|
|
LLVM_ABI cl::opt<bool>
|
|
MemProfUseHotHints("memprof-use-hot-hints", cl::init(false), cl::Hidden,
|
|
cl::desc("Enable use of hot hints (only supported for "
|
|
"unambigously hot allocations)"));
|
|
|
|
AllocationType llvm::memprof::getAllocType(uint64_t TotalLifetimeAccessDensity,
|
|
uint64_t AllocCount,
|
|
uint64_t TotalLifetime) {
|
|
// The access densities are multiplied by 100 to hold 2 decimal places of
|
|
// precision, so need to divide by 100.
|
|
if (((float)TotalLifetimeAccessDensity) / AllocCount / 100 <
|
|
MemProfLifetimeAccessDensityColdThreshold
|
|
// Lifetime is expected to be in ms, so convert the threshold to ms.
|
|
&& ((float)TotalLifetime) / AllocCount >=
|
|
MemProfAveLifetimeColdThreshold * 1000)
|
|
return AllocationType::Cold;
|
|
|
|
// The access densities are multiplied by 100 to hold 2 decimal places of
|
|
// precision, so need to divide by 100.
|
|
if (MemProfUseHotHints &&
|
|
((float)TotalLifetimeAccessDensity) / AllocCount / 100 >
|
|
MemProfMinAveLifetimeAccessDensityHotThreshold)
|
|
return AllocationType::Hot;
|
|
|
|
return AllocationType::NotCold;
|
|
}
|
|
|
|
uint64_t llvm::memprof::computeFullStackId(ArrayRef<Frame> CallStack) {
|
|
llvm::HashBuilder<llvm::TruncatedBLAKE3<8>, llvm::endianness::little>
|
|
HashBuilder;
|
|
for (auto &F : CallStack)
|
|
HashBuilder.add(F.Function, F.LineOffset, F.Column);
|
|
llvm::BLAKE3Result<8> Hash = HashBuilder.final();
|
|
uint64_t Id;
|
|
std::memcpy(&Id, Hash.data(), sizeof(Hash));
|
|
return Id;
|
|
}
|