llvm-project/llvm/lib/ProfileData/MemProfCommon.cpp
Andrew Rogers 6bd606fe49
[llvm] annotate interfaces in llvm/ProfileData for DLL export (#142861)
## 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
2025-06-10 07:58:51 -07:00

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;
}