1 //=-- MemProfCommon.cpp - MemProf common utilities ---------------=// 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 contains MemProf common utilities. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ProfileData/MemProfCommon.h" 14 #include "llvm/ProfileData/MemProf.h" 15 #include "llvm/Support/BLAKE3.h" 16 #include "llvm/Support/CommandLine.h" 17 #include "llvm/Support/Compiler.h" 18 #include "llvm/Support/HashBuilder.h" 19 20 using namespace llvm; 21 using namespace llvm::memprof; 22 23 // Upper bound on lifetime access density (accesses per byte per lifetime sec) 24 // for marking an allocation cold. 25 LLVM_ABI cl::opt<float> MemProfLifetimeAccessDensityColdThreshold( 26 "memprof-lifetime-access-density-cold-threshold", cl::init(0.05), 27 cl::Hidden, 28 cl::desc("The threshold the lifetime access density (accesses per byte per " 29 "lifetime sec) must be under to consider an allocation cold")); 30 31 // Lower bound on lifetime to mark an allocation cold (in addition to accesses 32 // per byte per sec above). This is to avoid pessimizing short lived objects. 33 LLVM_ABI cl::opt<unsigned> MemProfAveLifetimeColdThreshold( 34 "memprof-ave-lifetime-cold-threshold", cl::init(200), cl::Hidden, 35 cl::desc("The average lifetime (s) for an allocation to be considered " 36 "cold")); 37 38 // Lower bound on average lifetime accesses density (total life time access 39 // density / alloc count) for marking an allocation hot. 40 LLVM_ABI cl::opt<unsigned> MemProfMinAveLifetimeAccessDensityHotThreshold( 41 "memprof-min-ave-lifetime-access-density-hot-threshold", cl::init(1000), 42 cl::Hidden, 43 cl::desc("The minimum TotalLifetimeAccessDensity / AllocCount for an " 44 "allocation to be considered hot")); 45 46 LLVM_ABI cl::opt<bool> 47 MemProfUseHotHints("memprof-use-hot-hints", cl::init(false), cl::Hidden, 48 cl::desc("Enable use of hot hints (only supported for " 49 "unambigously hot allocations)")); 50 51 AllocationType llvm::memprof::getAllocType(uint64_t TotalLifetimeAccessDensity, 52 uint64_t AllocCount, 53 uint64_t TotalLifetime) { 54 // The access densities are multiplied by 100 to hold 2 decimal places of 55 // precision, so need to divide by 100. 56 if (((float)TotalLifetimeAccessDensity) / AllocCount / 100 < 57 MemProfLifetimeAccessDensityColdThreshold 58 // Lifetime is expected to be in ms, so convert the threshold to ms. 59 && ((float)TotalLifetime) / AllocCount >= 60 MemProfAveLifetimeColdThreshold * 1000) 61 return AllocationType::Cold; 62 63 // The access densities are multiplied by 100 to hold 2 decimal places of 64 // precision, so need to divide by 100. 65 if (MemProfUseHotHints && 66 ((float)TotalLifetimeAccessDensity) / AllocCount / 100 > 67 MemProfMinAveLifetimeAccessDensityHotThreshold) 68 return AllocationType::Hot; 69 70 return AllocationType::NotCold; 71 } 72 73 uint64_t llvm::memprof::computeFullStackId(ArrayRef<Frame> CallStack) { 74 llvm::HashBuilder<llvm::TruncatedBLAKE3<8>, llvm::endianness::little> 75 HashBuilder; 76 for (auto &F : CallStack) 77 HashBuilder.add(F.Function, F.LineOffset, F.Column); 78 llvm::BLAKE3Result<8> Hash = HashBuilder.final(); 79 uint64_t Id; 80 std::memcpy(&Id, Hash.data(), sizeof(Hash)); 81 return Id; 82 } 83