1/*===-- InstrProfData.inc - instr profiling runtime structures -*- C++ -*-=== *\ 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 is the main file that defines all the data structure, signature, 10 * constant literals that are shared across profiling runtime library, 11 * compiler (instrumentation), and host tools (reader/writer). The entities 12 * defined in this file affect the profile runtime ABI, the raw profile format, 13 * or both. 14 * 15 * The file has two identical copies. The primary copy lives in LLVM and 16 * the other one sits in compiler-rt/lib/profile directory. To make changes 17 * in this file, first modify the primary copy and copy it over to compiler-rt. 18 * Testing of any change in this file can start only after the two copies are 19 * synced up. 20 * 21 * The first part of the file includes macros that defines types, names, and 22 * initializers for the member fields of the core data structures. The field 23 * declarations for one structure is enabled by defining the field activation 24 * macro associated with that structure. Only one field activation record 25 * can be defined at one time and the rest definitions will be filtered out by 26 * the preprocessor. 27 * 28 * Examples of how the template is used to instantiate structure definition: 29 * 1. To declare a structure: 30 * 31 * struct ProfData { 32 * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 33 * Type Name; 34 * #include "llvm/ProfileData/InstrProfData.inc" 35 * }; 36 * 37 * 2. To construct LLVM type arrays for the struct type: 38 * 39 * Type *DataTypes[] = { 40 * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 41 * LLVMType, 42 * #include "llvm/ProfileData/InstrProfData.inc" 43 * }; 44 * 45 * 4. To construct constant array for the initializers: 46 * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 47 * Initializer, 48 * Constant *ConstantVals[] = { 49 * #include "llvm/ProfileData/InstrProfData.inc" 50 * }; 51 * 52 * 53 * The second part of the file includes definitions all other entities that 54 * are related to runtime ABI and format. When no field activation macro is 55 * defined, this file can be included to introduce the definitions. 56 * 57\*===----------------------------------------------------------------------===*/ 58 59/* Functions marked with INSTR_PROF_VISIBILITY must have hidden visibility in 60 * the compiler runtime. */ 61#ifndef INSTR_PROF_VISIBILITY 62#define INSTR_PROF_VISIBILITY 63#endif 64 65// clang-format off:consider re-enabling clang-format if auto-formatted C macros 66// are readable (e.g., after `issue #82426` is fixed) 67/* INSTR_PROF_DATA start. */ 68/* Definition of member fields of the per-function control structure. */ 69#ifndef INSTR_PROF_DATA 70#define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) 71#else 72#define INSTR_PROF_DATA_DEFINED 73#endif 74INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), NameRef, \ 75 ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ 76 IndexedInstrProf::ComputeHash(getPGOFuncNameVarInitializer(Inc->getName())))) 77INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ 78 ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ 79 Inc->getHash()->getZExtValue())) 80INSTR_PROF_DATA(const IntPtrT, IntPtrTy, CounterPtr, RelativeCounterPtr) 81INSTR_PROF_DATA(const IntPtrT, IntPtrTy, BitmapPtr, RelativeBitmapPtr) 82/* This is used to map function pointers for the indirect call targets to 83 * function name hashes during the conversion from raw to merged profile 84 * data. 85 */ 86INSTR_PROF_DATA(const IntPtrT, llvm::PointerType::getUnqual(Ctx), FunctionPointer, \ 87 FunctionAddr) 88INSTR_PROF_DATA(IntPtrT, llvm::PointerType::getUnqual(Ctx), Values, \ 89 ValuesPtrExpr) 90INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \ 91 ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters)) 92INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \ 93 ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) \ 94INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumBitmapBytes, \ 95 ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumBitmapBytes)) 96#undef INSTR_PROF_DATA 97/* INSTR_PROF_DATA end. */ 98 99/* For a virtual table object, record the name hash to associate profiled 100 * addresses with global variables, and record {starting address, size in bytes} 101 * to map the profiled virtual table (which usually have an offset from the 102 * starting address) back to a virtual table object. */ 103#ifndef INSTR_PROF_VTABLE_DATA 104#define INSTR_PROF_VTABLE_DATA(Type, LLVMType, Name, Initializer) 105#else 106#define INSTR_PROF_VTABLE_DATA_DEFINED 107#endif 108INSTR_PROF_VTABLE_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), \ 109 VTableNameHash, ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ 110 IndexedInstrProf::ComputeHash(PGOVTableName))) 111INSTR_PROF_VTABLE_DATA(const IntPtrT, llvm::PointerType::getUnqual(Ctx), \ 112 VTablePointer, VTableAddr) 113INSTR_PROF_VTABLE_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), VTableSize, \ 114 ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \ 115 VTableSizeVal)) 116#undef INSTR_PROF_VTABLE_DATA 117/* INSTR_PROF_VTABLE_DATA end. */ 118 119/* This is an internal data structure used by value profiler. It 120 * is defined here to allow serialization code sharing by LLVM 121 * to be used in unit test. 122 * 123 * typedef struct ValueProfNode { 124 * // InstrProfValueData VData; 125 * uint64_t Value; 126 * uint64_t Count; 127 * struct ValueProfNode *Next; 128 * } ValueProfNode; 129 */ 130/* INSTR_PROF_VALUE_NODE start. */ 131#ifndef INSTR_PROF_VALUE_NODE 132#define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Initializer) 133#else 134#define INSTR_PROF_DATA_DEFINED 135#endif 136INSTR_PROF_VALUE_NODE(uint64_t, llvm::Type::getInt64Ty(Ctx), Value, \ 137 ConstantInt::get(llvm::Type::GetInt64Ty(Ctx), 0)) 138INSTR_PROF_VALUE_NODE(uint64_t, llvm::Type::getInt64Ty(Ctx), Count, \ 139 ConstantInt::get(llvm::Type::GetInt64Ty(Ctx), 0)) 140INSTR_PROF_VALUE_NODE(PtrToNodeT, llvm::PointerType::getUnqual(Ctx), Next, \ 141 ConstantInt::get(llvm::PointerType::getUnqual(Ctx), 0)) 142#undef INSTR_PROF_VALUE_NODE 143/* INSTR_PROF_VALUE_NODE end. */ 144 145/* INSTR_PROF_RAW_HEADER start */ 146/* Definition of member fields of the raw profile header data structure. */ 147/* Please update llvm/docs/InstrProfileFormat.rst as appropriate when updating 148 raw profile format. */ 149#ifndef INSTR_PROF_RAW_HEADER 150#define INSTR_PROF_RAW_HEADER(Type, Name, Initializer) 151#else 152#define INSTR_PROF_DATA_DEFINED 153#endif 154INSTR_PROF_RAW_HEADER(uint64_t, Magic, __llvm_profile_get_magic()) 155INSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version()) 156INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) 157INSTR_PROF_RAW_HEADER(uint64_t, NumData, NumData) 158INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesBeforeCounters, PaddingBytesBeforeCounters) 159INSTR_PROF_RAW_HEADER(uint64_t, NumCounters, NumCounters) 160INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterCounters, PaddingBytesAfterCounters) 161INSTR_PROF_RAW_HEADER(uint64_t, NumBitmapBytes, NumBitmapBytes) 162INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterBitmapBytes, PaddingBytesAfterBitmapBytes) 163INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) 164INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, 165 (uintptr_t)CountersBegin - (uintptr_t)DataBegin) 166INSTR_PROF_RAW_HEADER(uint64_t, BitmapDelta, 167 (uintptr_t)BitmapBegin - (uintptr_t)DataBegin) 168INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin) 169INSTR_PROF_RAW_HEADER(uint64_t, NumVTables, NumVTables) 170INSTR_PROF_RAW_HEADER(uint64_t, VNamesSize, VNamesSize) 171INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last) 172#undef INSTR_PROF_RAW_HEADER 173/* INSTR_PROF_RAW_HEADER end */ 174 175/* VALUE_PROF_FUNC_PARAM start */ 176/* Definition of parameter types of the runtime API used to do value profiling 177 * for a given value site. 178 */ 179#ifndef VALUE_PROF_FUNC_PARAM 180#define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType) 181#define INSTR_PROF_COMMA 182#else 183#define INSTR_PROF_DATA_DEFINED 184#define INSTR_PROF_COMMA , 185#endif 186VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \ 187 INSTR_PROF_COMMA 188VALUE_PROF_FUNC_PARAM(void *, Data, PointerType::getUnqual(Ctx)) INSTR_PROF_COMMA 189VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) 190#undef VALUE_PROF_FUNC_PARAM 191#undef INSTR_PROF_COMMA 192/* VALUE_PROF_FUNC_PARAM end */ 193 194/* VALUE_PROF_KIND start */ 195#ifndef VALUE_PROF_KIND 196#define VALUE_PROF_KIND(Enumerator, Value, Descr) 197#else 198#define INSTR_PROF_DATA_DEFINED 199#endif 200/* For indirect function call value profiling, the addresses of the target 201 * functions are profiled by the instrumented code. The target addresses are 202 * written in the raw profile data and converted to target function name's MD5 203 * hash by the profile reader during deserialization. Typically, this happens 204 * when the raw profile data is read during profile merging. 205 * 206 * For this remapping the ProfData is used. ProfData contains both the function 207 * name hash and the function address. 208 */ 209VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0, "indirect call target") 210/* For memory intrinsic functions size profiling. */ 211VALUE_PROF_KIND(IPVK_MemOPSize, 1, "memory intrinsic functions size") 212/* For virtual table address profiling, the address point of the virtual table 213 * (i.e., the address contained in objects pointing to a virtual table) are 214 * profiled. Note this may not be the address of the per C++ class virtual table 215 * object (e.g., there might be an offset). 216 * 217 * The profiled addresses are stored in raw profile, together with the following 218 * two types of information. 219 * 1. The (starting and ending) addresses of per C++ class virtual table objects. 220 * 2. The (compressed) virtual table object names. 221 * RawInstrProfReader converts profiled virtual table addresses to virtual table 222 * objects' MD5 hash. 223 */ 224VALUE_PROF_KIND(IPVK_VTableTarget, 2, "The profiled address point of the vtable") 225/* These two kinds must be the last to be 226 * declared. This is to make sure the string 227 * array created with the template can be 228 * indexed with the kind value. 229 */ 230VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget, "first") 231VALUE_PROF_KIND(IPVK_Last, IPVK_VTableTarget, "last") 232 233#undef VALUE_PROF_KIND 234/* VALUE_PROF_KIND end */ 235 236#undef COVMAP_V2_OR_V3 237#ifdef COVMAP_V2 238#define COVMAP_V2_OR_V3 239#endif 240#ifdef COVMAP_V3 241#define COVMAP_V2_OR_V3 242#endif 243 244/* COVMAP_FUNC_RECORD start */ 245/* Definition of member fields of the function record structure in coverage 246 * map. 247 */ 248#ifndef COVMAP_FUNC_RECORD 249#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) 250#else 251#define INSTR_PROF_DATA_DEFINED 252#endif 253#ifdef COVMAP_V1 254COVMAP_FUNC_RECORD(const IntPtrT, llvm::PointerType::getUnqual(Ctx), \ 255 NamePtr, llvm::ConstantExpr::getBitCast(NamePtr, \ 256 llvm::PointerType::getUnqual(Ctx))) 257COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ 258 llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \ 259 NameValue.size())) 260#endif 261#ifdef COVMAP_V2_OR_V3 262COVMAP_FUNC_RECORD(const int64_t, llvm::Type::getInt64Ty(Ctx), NameRef, \ 263 llvm::ConstantInt::get( \ 264 llvm::Type::getInt64Ty(Ctx), NameHash)) 265#endif 266COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), DataSize, \ 267 llvm::ConstantInt::get( \ 268 llvm::Type::getInt32Ty(Ctx), CoverageMapping.size())) 269COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ 270 llvm::ConstantInt::get( \ 271 llvm::Type::getInt64Ty(Ctx), FuncHash)) 272#ifdef COVMAP_V3 273COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FilenamesRef, \ 274 llvm::ConstantInt::get( \ 275 llvm::Type::getInt64Ty(Ctx), FilenamesRef)) 276COVMAP_FUNC_RECORD(const char, \ 277 llvm::ArrayType::get(llvm::Type::getInt8Ty(Ctx), \ 278 CoverageMapping.size()), \ 279 CoverageMapping, 280 llvm::ConstantDataArray::getRaw( \ 281 CoverageMapping, CoverageMapping.size(), \ 282 llvm::Type::getInt8Ty(Ctx))) 283#endif 284#undef COVMAP_FUNC_RECORD 285/* COVMAP_FUNC_RECORD end. */ 286 287/* COVMAP_HEADER start */ 288/* Definition of member fields of coverage map header. 289 */ 290#ifndef COVMAP_HEADER 291#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) 292#else 293#define INSTR_PROF_DATA_DEFINED 294#endif 295COVMAP_HEADER(uint32_t, Int32Ty, NRecords, \ 296 llvm::ConstantInt::get(Int32Ty, NRecords)) 297COVMAP_HEADER(uint32_t, Int32Ty, FilenamesSize, \ 298 llvm::ConstantInt::get(Int32Ty, FilenamesSize)) 299COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ 300 llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) 301COVMAP_HEADER(uint32_t, Int32Ty, Version, \ 302 llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion)) 303#undef COVMAP_HEADER 304/* COVMAP_HEADER end. */ 305 306 307#ifdef INSTR_PROF_SECT_ENTRY 308#define INSTR_PROF_DATA_DEFINED 309INSTR_PROF_SECT_ENTRY(IPSK_data, \ 310 INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON), \ 311 INSTR_PROF_DATA_COFF, "__DATA,") 312INSTR_PROF_SECT_ENTRY(IPSK_cnts, \ 313 INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \ 314 INSTR_PROF_CNTS_COFF, "__DATA,") 315INSTR_PROF_SECT_ENTRY(IPSK_bitmap, \ 316 INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON), \ 317 INSTR_PROF_BITS_COFF, "__DATA,") 318INSTR_PROF_SECT_ENTRY(IPSK_name, \ 319 INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \ 320 INSTR_PROF_NAME_COFF, "__DATA,") 321INSTR_PROF_SECT_ENTRY(IPSK_vname, \ 322 INSTR_PROF_QUOTE(INSTR_PROF_VNAME_COMMON), \ 323 INSTR_PROF_VNAME_COFF, "__DATA,") 324INSTR_PROF_SECT_ENTRY(IPSK_vals, \ 325 INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON), \ 326 INSTR_PROF_VALS_COFF, "__DATA,") 327INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \ 328 INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON), \ 329 INSTR_PROF_VNODES_COFF, "__DATA,") 330INSTR_PROF_SECT_ENTRY(IPSK_vtab, \ 331 INSTR_PROF_QUOTE(INSTR_PROF_VTAB_COMMON), \ 332 INSTR_PROF_VTAB_COFF, "__DATA,") 333INSTR_PROF_SECT_ENTRY(IPSK_covmap, \ 334 INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \ 335 INSTR_PROF_COVMAP_COFF, "__LLVM_COV,") 336INSTR_PROF_SECT_ENTRY(IPSK_covfun, \ 337 INSTR_PROF_QUOTE(INSTR_PROF_COVFUN_COMMON), \ 338 INSTR_PROF_COVFUN_COFF, "__LLVM_COV,") 339INSTR_PROF_SECT_ENTRY(IPSK_orderfile, \ 340 INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON), \ 341 INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COFF), "__DATA,") 342INSTR_PROF_SECT_ENTRY(IPSK_covdata, \ 343 INSTR_PROF_QUOTE(INSTR_PROF_COVDATA_COMMON), \ 344 INSTR_PROF_COVDATA_COFF, "__LLVM_COV,") 345INSTR_PROF_SECT_ENTRY(IPSK_covname, \ 346 INSTR_PROF_QUOTE(INSTR_PROF_COVNAME_COMMON), \ 347 INSTR_PROF_COVNAME_COFF, "__LLVM_COV,") 348 349#undef INSTR_PROF_SECT_ENTRY 350#endif 351 352 353#ifdef INSTR_PROF_VALUE_PROF_DATA 354#define INSTR_PROF_DATA_DEFINED 355 356#define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255 357/*! 358 * This is the header of the data structure that defines the on-disk 359 * layout of the value profile data of a particular kind for one function. 360 */ 361typedef struct ValueProfRecord { 362 /* The kind of the value profile record. */ 363 uint32_t Kind; 364 /* 365 * The number of value profile sites. It is guaranteed to be non-zero; 366 * otherwise the record for this kind won't be emitted. 367 */ 368 uint32_t NumValueSites; 369 /* 370 * The first element of the array that stores the number of profiled 371 * values for each value site. The size of the array is NumValueSites. 372 * Since NumValueSites is greater than zero, there is at least one 373 * element in the array. 374 */ 375 uint8_t SiteCountArray[1]; 376 377 /* 378 * The fake declaration is for documentation purpose only. 379 * Align the start of next field to be on 8 byte boundaries. 380 uint8_t Padding[X]; 381 */ 382 383 /* The array of value profile data. The size of the array is the sum 384 * of all elements in SiteCountArray[]. 385 InstrProfValueData ValueData[]; 386 */ 387 388#ifdef __cplusplus 389 /*! 390 * Return the number of value sites. 391 */ 392 uint32_t getNumValueSites() const { return NumValueSites; } 393 /*! 394 * Read data from this record and save it to Record. 395 */ 396 void deserializeTo(InstrProfRecord &Record, 397 InstrProfSymtab *SymTab); 398 /* 399 * In-place byte swap: 400 * Do byte swap for this instance. \c Old is the original order before 401 * the swap, and \c New is the New byte order. 402 */ 403 void swapBytes(llvm::endianness Old, llvm::endianness New); 404#endif 405} ValueProfRecord; 406 407/*! 408 * Per-function header/control data structure for value profiling 409 * data in indexed format. 410 */ 411typedef struct ValueProfData { 412 /* 413 * Total size in bytes including this field. It must be a multiple 414 * of sizeof(uint64_t). 415 */ 416 uint32_t TotalSize; 417 /* 418 *The number of value profile kinds that has value profile data. 419 * In this implementation, a value profile kind is considered to 420 * have profile data if the number of value profile sites for the 421 * kind is not zero. More aggressively, the implementation can 422 * choose to check the actual data value: if none of the value sites 423 * has any profiled values, the kind can be skipped. 424 */ 425 uint32_t NumValueKinds; 426 427 /* 428 * Following are a sequence of variable length records. The prefix/header 429 * of each record is defined by ValueProfRecord type. The number of 430 * records is NumValueKinds. 431 * ValueProfRecord Record_1; 432 * ValueProfRecord Record_N; 433 */ 434 435#if __cplusplus 436 /*! 437 * Return the total size in bytes of the on-disk value profile data 438 * given the data stored in Record. 439 */ 440 static uint32_t getSize(const InstrProfRecord &Record); 441 /*! 442 * Return a pointer to \c ValueProfData instance ready to be streamed. 443 */ 444 static std::unique_ptr<ValueProfData> 445 serializeFrom(const InstrProfRecord &Record); 446 /*! 447 * Check the integrity of the record. 448 */ 449 Error checkIntegrity(); 450 /*! 451 * Return a pointer to \c ValueProfileData instance ready to be read. 452 * All data in the instance are properly byte swapped. The input 453 * data is assumed to be in little endian order. 454 */ 455 static Expected<std::unique_ptr<ValueProfData>> 456 getValueProfData(const unsigned char *SrcBuffer, 457 const unsigned char *const SrcBufferEnd, 458 llvm::endianness SrcDataEndianness); 459 /*! 460 * Swap byte order from \c Endianness order to host byte order. 461 */ 462 void swapBytesToHost(llvm::endianness Endianness); 463 /*! 464 * Swap byte order from host byte order to \c Endianness order. 465 */ 466 void swapBytesFromHost(llvm::endianness Endianness); 467 /*! 468 * Return the total size of \c ValueProfileData. 469 */ 470 uint32_t getSize() const { return TotalSize; } 471 /*! 472 * Read data from this data and save it to \c Record. 473 */ 474 void deserializeTo(InstrProfRecord &Record, 475 InstrProfSymtab *SymTab); 476 void operator delete(void *ptr) { ::operator delete(ptr); } 477#endif 478} ValueProfData; 479 480/* 481 * The closure is designed to abstact away two types of value profile data: 482 * - InstrProfRecord which is the primary data structure used to 483 * represent profile data in host tools (reader, writer, and profile-use) 484 * - value profile runtime data structure suitable to be used by C 485 * runtime library. 486 * 487 * Both sources of data need to serialize to disk/memory-buffer in common 488 * format: ValueProfData. The abstraction allows compiler-rt's raw profiler 489 * writer to share the same format and code with indexed profile writer. 490 * 491 * For documentation of the member methods below, refer to corresponding methods 492 * in class InstrProfRecord. 493 */ 494typedef struct ValueProfRecordClosure { 495 const void *Record; 496 uint32_t (*GetNumValueKinds)(const void *Record); 497 uint32_t (*GetNumValueSites)(const void *Record, uint32_t VKind); 498 uint32_t (*GetNumValueData)(const void *Record, uint32_t VKind); 499 uint32_t (*GetNumValueDataForSite)(const void *R, uint32_t VK, uint32_t S); 500 501 /* 502 * After extracting the value profile data from the value profile record, 503 * this method is used to map the in-memory value to on-disk value. If 504 * the method is null, value will be written out untranslated. 505 */ 506 uint64_t (*RemapValueData)(uint32_t, uint64_t Value); 507 void (*GetValueForSite)(const void *R, InstrProfValueData *Dst, uint32_t K, 508 uint32_t S); 509 ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes); 510} ValueProfRecordClosure; 511 512INSTR_PROF_VISIBILITY ValueProfRecord * 513getFirstValueProfRecord(ValueProfData *VPD); 514INSTR_PROF_VISIBILITY ValueProfRecord * 515getValueProfRecordNext(ValueProfRecord *VPR); 516INSTR_PROF_VISIBILITY InstrProfValueData * 517getValueProfRecordValueData(ValueProfRecord *VPR); 518INSTR_PROF_VISIBILITY uint32_t 519getValueProfRecordHeaderSize(uint32_t NumValueSites); 520 521#undef INSTR_PROF_VALUE_PROF_DATA 522#endif /* INSTR_PROF_VALUE_PROF_DATA */ 523 524 525#ifdef INSTR_PROF_COMMON_API_IMPL 526#define INSTR_PROF_DATA_DEFINED 527#ifdef __cplusplus 528#define INSTR_PROF_INLINE inline 529#define INSTR_PROF_NULLPTR nullptr 530#else 531#define INSTR_PROF_INLINE 532#define INSTR_PROF_NULLPTR NULL 533#endif 534 535#ifndef offsetof 536#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 537#endif 538 539// clang-format on 540 541/*! 542 * Return the \c ValueProfRecord header size including the 543 * padding bytes. 544 */ 545INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint32_t 546getValueProfRecordHeaderSize(uint32_t NumValueSites) { 547 uint32_t Size = offsetof(ValueProfRecord, SiteCountArray) + 548 sizeof(uint8_t) * NumValueSites; 549 /* Round the size to multiple of 8 bytes. */ 550 Size = (Size + 7) & ~7; 551 return Size; 552} 553 554/*! 555 * Return the total size of the value profile record including the 556 * header and the value data. 557 */ 558INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint32_t 559getValueProfRecordSize(uint32_t NumValueSites, uint32_t NumValueData) { 560 return getValueProfRecordHeaderSize(NumValueSites) + 561 sizeof(InstrProfValueData) * NumValueData; 562} 563 564/*! 565 * Return the pointer to the start of value data array. 566 */ 567INSTR_PROF_VISIBILITY INSTR_PROF_INLINE InstrProfValueData * 568getValueProfRecordValueData(ValueProfRecord *This) { 569 return (InstrProfValueData *)((char *)This + getValueProfRecordHeaderSize( 570 This->NumValueSites)); 571} 572 573/*! 574 * Return the total number of value data for \c This record. 575 */ 576INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint32_t 577getValueProfRecordNumValueData(ValueProfRecord *This) { 578 uint32_t NumValueData = 0; 579 uint32_t I; 580 for (I = 0; I < This->NumValueSites; I++) 581 NumValueData += This->SiteCountArray[I]; 582 return NumValueData; 583} 584 585/*! 586 * Use this method to advance to the next \c This \c ValueProfRecord. 587 */ 588INSTR_PROF_VISIBILITY INSTR_PROF_INLINE ValueProfRecord * 589getValueProfRecordNext(ValueProfRecord *This) { 590 uint32_t NumValueData = getValueProfRecordNumValueData(This); 591 return (ValueProfRecord *)((char *)This + 592 getValueProfRecordSize(This->NumValueSites, 593 NumValueData)); 594} 595 596/*! 597 * Return the first \c ValueProfRecord instance. 598 */ 599INSTR_PROF_VISIBILITY INSTR_PROF_INLINE ValueProfRecord * 600getFirstValueProfRecord(ValueProfData *This) { 601 return (ValueProfRecord *)((char *)This + sizeof(ValueProfData)); 602} 603 604/* Closure based interfaces. */ 605 606/*! 607 * Return the total size in bytes of the on-disk value profile data 608 * given the data stored in Record. 609 */ 610INSTR_PROF_VISIBILITY uint32_t 611getValueProfDataSize(ValueProfRecordClosure *Closure) { 612 uint32_t Kind; 613 uint32_t TotalSize = sizeof(ValueProfData); 614 const void *Record = Closure->Record; 615 616 for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 617 uint32_t NumValueSites = Closure->GetNumValueSites(Record, Kind); 618 if (!NumValueSites) 619 continue; 620 TotalSize += getValueProfRecordSize(NumValueSites, 621 Closure->GetNumValueData(Record, Kind)); 622 } 623 return TotalSize; 624} 625 626/*! 627 * Extract value profile data of a function for the profile kind \c ValueKind 628 * from the \c Closure and serialize the data into \c This record instance. 629 */ 630INSTR_PROF_VISIBILITY void 631serializeValueProfRecordFrom(ValueProfRecord *This, 632 ValueProfRecordClosure *Closure, 633 uint32_t ValueKind, uint32_t NumValueSites) { 634 uint32_t S; 635 const void *Record = Closure->Record; 636 This->Kind = ValueKind; 637 This->NumValueSites = NumValueSites; 638 InstrProfValueData *DstVD = getValueProfRecordValueData(This); 639 640 for (S = 0; S < NumValueSites; S++) { 641 uint32_t ND = Closure->GetNumValueDataForSite(Record, ValueKind, S); 642 This->SiteCountArray[S] = ND; 643 Closure->GetValueForSite(Record, DstVD, ValueKind, S); 644 DstVD += ND; 645 } 646} 647 648/*! 649 * Extract value profile data of a function from the \c Closure 650 * and serialize the data into \c DstData if it is not NULL or heap 651 * memory allocated by the \c Closure's allocator method. If \c 652 * DstData is not null, the caller is expected to set the TotalSize 653 * in DstData. 654 */ 655INSTR_PROF_VISIBILITY ValueProfData * 656serializeValueProfDataFrom(ValueProfRecordClosure *Closure, 657 ValueProfData *DstData) { 658 uint32_t Kind; 659 uint32_t TotalSize = 660 DstData ? DstData->TotalSize : getValueProfDataSize(Closure); 661 662 ValueProfData *VPD = 663 DstData ? DstData : Closure->AllocValueProfData(TotalSize); 664 665 VPD->TotalSize = TotalSize; 666 VPD->NumValueKinds = Closure->GetNumValueKinds(Closure->Record); 667 ValueProfRecord *VR = getFirstValueProfRecord(VPD); 668 for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 669 uint32_t NumValueSites = Closure->GetNumValueSites(Closure->Record, Kind); 670 if (!NumValueSites) 671 continue; 672 serializeValueProfRecordFrom(VR, Closure, Kind, NumValueSites); 673 VR = getValueProfRecordNext(VR); 674 } 675 return VPD; 676} 677 678#undef INSTR_PROF_COMMON_API_IMPL 679#endif /* INSTR_PROF_COMMON_API_IMPL */ 680 681/*============================================================================*/ 682 683// clang-format off:consider re-enabling clang-format if auto-formatted C macros 684// are readable (e.g., after `issue #82426` is fixed) 685#ifndef INSTR_PROF_DATA_DEFINED 686 687#ifndef INSTR_PROF_DATA_INC 688#define INSTR_PROF_DATA_INC 689 690/* Helper macros. */ 691#define INSTR_PROF_SIMPLE_QUOTE(x) #x 692#define INSTR_PROF_QUOTE(x) INSTR_PROF_SIMPLE_QUOTE(x) 693#define INSTR_PROF_SIMPLE_CONCAT(x,y) x ## y 694#define INSTR_PROF_CONCAT(x,y) INSTR_PROF_SIMPLE_CONCAT(x,y) 695 696/* Magic number to detect file format and endianness. 697 * Use 255 at one end, since no UTF-8 file can use that character. Avoid 0, 698 * so that utilities, like strings, don't grab it as a string. 129 is also 699 * invalid UTF-8, and high enough to be interesting. 700 * Use "lprofr" in the centre to stand for "LLVM Profile Raw", or "lprofR" 701 * for 32-bit platforms. 702 */ 703#define INSTR_PROF_RAW_MAGIC_64 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \ 704 (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ 705 (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129 706#define INSTR_PROF_RAW_MAGIC_32 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \ 707 (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ 708 (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 709 710/* Raw profile format version (start from 1). */ 711#define INSTR_PROF_RAW_VERSION 10 712/* Indexed profile format version (start from 1). */ 713#define INSTR_PROF_INDEX_VERSION 12 714/* Coverage mapping format version (start from 0). */ 715#define INSTR_PROF_COVMAP_VERSION 6 716 717/* Profile version is always of type uint64_t. Reserve the upper 32 bits in the 718 * version for other variants of profile. We set the 8th most significant bit 719 * (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentation 720 * generated profile, and 0 if this is a Clang FE generated profile. 721 * 1 in bit 57 indicates there are context-sensitive records in the profile. 722 * The 59th bit indicates whether to use debug info to correlate profiles. 723 * The 60th bit indicates single byte coverage instrumentation. 724 * The 61st bit indicates function entry instrumentation only. 725 * The 62nd bit indicates whether memory profile information is present. 726 * The 63rd bit indicates if this is a temporal profile. 727 */ 728#define VARIANT_MASKS_ALL 0xffffffff00000000ULL 729#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL) 730#define VARIANT_MASK_IR_PROF (0x1ULL << 56) 731#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57) 732#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58) 733#define VARIANT_MASK_DBG_CORRELATE (0x1ULL << 59) 734#define VARIANT_MASK_BYTE_COVERAGE (0x1ULL << 60) 735#define VARIANT_MASK_FUNCTION_ENTRY_ONLY (0x1ULL << 61) 736#define VARIANT_MASK_MEMPROF (0x1ULL << 62) 737#define VARIANT_MASK_TEMPORAL_PROF (0x1ULL << 63) 738#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version 739#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime 740#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias 741#define INSTR_PROF_PROFILE_SET_TIMESTAMP __llvm_profile_set_timestamp 742#define INSTR_PROF_PROFILE_SAMPLING_VAR __llvm_profile_sampling 743 744/* The variable that holds the name of the profile data 745 * specified via command line. */ 746#define INSTR_PROF_PROFILE_NAME_VAR __llvm_profile_filename 747 748/* section name strings common to all targets other 749 than WIN32 */ 750#define INSTR_PROF_DATA_COMMON __llvm_prf_data 751#define INSTR_PROF_NAME_COMMON __llvm_prf_names 752#define INSTR_PROF_VNAME_COMMON __llvm_prf_vns 753#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts 754#define INSTR_PROF_BITS_COMMON __llvm_prf_bits 755#define INSTR_PROF_VALS_COMMON __llvm_prf_vals 756#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds 757#define INSTR_PROF_VTAB_COMMON __llvm_prf_vtab 758#define INSTR_PROF_COVMAP_COMMON __llvm_covmap 759#define INSTR_PROF_COVFUN_COMMON __llvm_covfun 760#define INSTR_PROF_COVDATA_COMMON __llvm_covdata 761#define INSTR_PROF_COVNAME_COMMON __llvm_covnames 762#define INSTR_PROF_ORDERFILE_COMMON __llvm_orderfile 763/* Windows section names. Because these section names contain dollar characters, 764 * they must be quoted. 765 */ 766#define INSTR_PROF_DATA_COFF ".lprfd$M" 767#define INSTR_PROF_NAME_COFF ".lprfn$M" 768#define INSTR_PROF_VNAME_COFF ".lprfvn$M" 769#define INSTR_PROF_CNTS_COFF ".lprfc$M" 770#define INSTR_PROF_BITS_COFF ".lprfb$M" 771#define INSTR_PROF_VALS_COFF ".lprfv$M" 772#define INSTR_PROF_VNODES_COFF ".lprfnd$M" 773#define INSTR_PROF_VTAB_COFF ".lprfvt$M" 774#define INSTR_PROF_COVMAP_COFF ".lcovmap$M" 775#define INSTR_PROF_COVFUN_COFF ".lcovfun$M" 776/* Since cov data and cov names sections are not allocated, we don't need to 777 * access them at runtime. 778 */ 779#define INSTR_PROF_COVDATA_COFF ".lcovd" 780#define INSTR_PROF_COVNAME_COFF ".lcovn" 781#define INSTR_PROF_ORDERFILE_COFF ".lorderfile$M" 782 783#ifdef _WIN32 784/* Runtime section names and name strings. */ 785#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF 786#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF 787#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF 788#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_BITS_COFF 789#define INSTR_PROF_VTAB_SECT_NAME INSTR_PROF_VTAB_COFF 790#define INSTR_PROF_VNAME_SECT_NAME INSTR_PROF_VNAME_COFF 791/* Array of pointers. Each pointer points to a list 792 * of value nodes associated with one value site. 793 */ 794#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COFF 795/* Value profile nodes section. */ 796#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF 797#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF 798#define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_COVFUN_COFF 799#define INSTR_PROF_COVDATA_SECT_NAME INSTR_PROF_COVDATA_COFF 800#define INSTR_PROF_COVNAME_SECT_NAME INSTR_PROF_COVNAME_COFF 801#define INSTR_PROF_ORDERFILE_SECT_NAME INSTR_PROF_ORDERFILE_COFF 802#else 803/* Runtime section names and name strings. */ 804#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON) 805#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON) 806#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON) 807#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON) 808#define INSTR_PROF_VTAB_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VTAB_COMMON) 809#define INSTR_PROF_VNAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VNAME_COMMON) 810/* Array of pointers. Each pointer points to a list 811 * of value nodes associated with one value site. 812 */ 813#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON) 814/* Value profile nodes section. */ 815#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON) 816#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON) 817#define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVFUN_COMMON) 818#define INSTR_PROF_COVDATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVDATA_COMMON) 819#define INSTR_PROF_COVNAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVNAME_COMMON) 820/* Order file instrumentation. */ 821#define INSTR_PROF_ORDERFILE_SECT_NAME \ 822 INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON) 823#endif 824 825#define INSTR_PROF_ORDERFILE_BUFFER_NAME _llvm_order_file_buffer 826#define INSTR_PROF_ORDERFILE_BUFFER_NAME_STR \ 827 INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_BUFFER_NAME) 828#define INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME _llvm_order_file_buffer_idx 829#define INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME_STR \ 830 INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME) 831 832/* Macros to define start/stop section symbol for a given 833 * section on Linux. For instance 834 * INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME) will 835 * expand to __start___llvm_prof_data 836 */ 837#define INSTR_PROF_SECT_START(Sect) \ 838 INSTR_PROF_CONCAT(__start_,Sect) 839#define INSTR_PROF_SECT_STOP(Sect) \ 840 INSTR_PROF_CONCAT(__stop_,Sect) 841 842/* Value Profiling API linkage name. */ 843#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target 844#define INSTR_PROF_VALUE_PROF_FUNC_STR \ 845 INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC) 846#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC __llvm_profile_instrument_memop 847#define INSTR_PROF_VALUE_PROF_MEMOP_FUNC_STR \ 848 INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_MEMOP_FUNC) 849 850/* InstrProfile per-function control data alignment. */ 851#define INSTR_PROF_DATA_ALIGNMENT 8 852 853/* The data structure that represents a tracked value by the 854 * value profiler. 855 */ 856typedef struct InstrProfValueData { 857 /* Profiled value. */ 858 uint64_t Value; 859 /* Number of times the value appears in the training run. */ 860 uint64_t Count; 861} InstrProfValueData; 862 863#endif /* INSTR_PROF_DATA_INC */ 864 865#ifndef INSTR_ORDER_FILE_INC 866/* The maximal # of functions: 128*1024 (the buffer size will be 128*4 KB). */ 867#define INSTR_ORDER_FILE_BUFFER_SIZE 131072 868#define INSTR_ORDER_FILE_BUFFER_BITS 17 869#define INSTR_ORDER_FILE_BUFFER_MASK 0x1ffff 870#endif /* INSTR_ORDER_FILE_INC */ 871#else 872#undef INSTR_PROF_DATA_DEFINED 873#endif 874 875#undef COVMAP_V2_OR_V3 876 877#ifdef INSTR_PROF_VALUE_PROF_MEMOP_API 878 879#ifdef __cplusplus 880#define INSTR_PROF_INLINE inline 881#else 882#define INSTR_PROF_INLINE 883#endif 884 885/* The value range buckets (22 buckets) for the memop size value profiling looks 886 * like: 887 * 888 * [0, 0] 889 * [1, 1] 890 * [2, 2] 891 * [3, 3] 892 * [4, 4] 893 * [5, 5] 894 * [6, 6] 895 * [7, 7] 896 * [8, 8] 897 * [9, 15] 898 * [16, 16] 899 * [17, 31] 900 * [32, 32] 901 * [33, 63] 902 * [64, 64] 903 * [65, 127] 904 * [128, 128] 905 * [129, 255] 906 * [256, 256] 907 * [257, 511] 908 * [512, 512] 909 * [513, UINT64_MAX] 910 * 911 * Each range has a 'representative value' which is the lower end value of the 912 * range and used to store in the runtime profile data records and the VP 913 * metadata. For example, it's 2 for [2, 2] and 64 for [65, 127]. 914 */ 915#define INSTR_PROF_NUM_BUCKETS 22 916 917/* 918 * Clz and Popcount. This code was copied from 919 * compiler-rt/lib/fuzzer/{FuzzerBuiltins.h,FuzzerBuiltinsMsvc.h} and 920 * llvm/include/llvm/Support/MathExtras.h. 921 */ 922#if defined(_MSC_VER) && !defined(__clang__) 923 924#include <intrin.h> 925INSTR_PROF_VISIBILITY INSTR_PROF_INLINE 926int InstProfClzll(unsigned long long X) { 927 unsigned long LeadZeroIdx = 0; 928#if !defined(_M_ARM64) && !defined(_M_X64) 929 // Scan the high 32 bits. 930 if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X >> 32))) 931 return (int)(63 - (LeadZeroIdx + 32)); // Create a bit offset 932 // from the MSB. 933 // Scan the low 32 bits. 934 if (_BitScanReverse(&LeadZeroIdx, (unsigned long)(X))) 935 return (int)(63 - LeadZeroIdx); 936#else 937 if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx; 938#endif 939 return 64; 940} 941INSTR_PROF_VISIBILITY INSTR_PROF_INLINE 942int InstProfPopcountll(unsigned long long X) { 943 // This code originates from https://reviews.llvm.org/rG30626254510f. 944 unsigned long long v = X; 945 v = v - ((v >> 1) & 0x5555555555555555ULL); 946 v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); 947 v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; 948 return (int)((unsigned long long)(v * 0x0101010101010101ULL) >> 56); 949} 950 951#else 952 953INSTR_PROF_VISIBILITY INSTR_PROF_INLINE 954int InstProfClzll(unsigned long long X) { return __builtin_clzll(X); } 955INSTR_PROF_VISIBILITY INSTR_PROF_INLINE 956int InstProfPopcountll(unsigned long long X) { return __builtin_popcountll(X); } 957 958#endif /* defined(_MSC_VER) && !defined(__clang__) */ 959 960// clang-format on 961 962/* Map an (observed) memop size value to the representative value of its range. 963 * For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */ 964INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint64_t 965InstrProfGetRangeRepValue(uint64_t Value) { 966 if (Value <= 8) 967 // The first ranges are individually tracked. Use the value as is. 968 return Value; 969 else if (Value >= 513) 970 // The last range is mapped to its lowest value. 971 return 513; 972 else if (InstProfPopcountll(Value) == 1) 973 // If it's a power of two, use it as is. 974 return Value; 975 else 976 // Otherwise, take to the previous power of two + 1. 977 return (UINT64_C(1) << (64 - InstProfClzll(Value) - 1)) + 1; 978} 979 980/* Return true if the range that an (observed) memop size value belongs to has 981 * only a single value in the range. For example, 0 -> true, 8 -> true, 10 -> 982 * false, 64 -> true, 100 -> false, 513 -> false. */ 983INSTR_PROF_VISIBILITY INSTR_PROF_INLINE unsigned 984InstrProfIsSingleValRange(uint64_t Value) { 985 if (Value <= 8) 986 // The first ranges are individually tracked. 987 return 1; 988 else if (InstProfPopcountll(Value) == 1) 989 // If it's a power of two, there's only one value. 990 return 1; 991 else 992 // Otherwise, there's more than one value in the range. 993 return 0; 994} 995 996#endif /* INSTR_PROF_VALUE_PROF_MEMOP_API */ 997