1*40cf9698Sjoerg/*===-- InstrProfData.inc - instr profiling runtime structures -*- C++ -*-=== *\ 2*40cf9698Sjoerg|* 3*40cf9698Sjoerg|* The LLVM Compiler Infrastructure 4*40cf9698Sjoerg|* 5*40cf9698Sjoerg|* This file is distributed under the University of Illinois Open Source 6*40cf9698Sjoerg|* License. See LICENSE.TXT for details. 7*40cf9698Sjoerg|* 8*40cf9698Sjoerg\*===----------------------------------------------------------------------===*/ 9*40cf9698Sjoerg/* 10*40cf9698Sjoerg * This is the master file that defines all the data structure, signature, 11*40cf9698Sjoerg * constant literals that are shared across profiling runtime library, 12*40cf9698Sjoerg * compiler (instrumentation), and host tools (reader/writer). The entities 13*40cf9698Sjoerg * defined in this file affect the profile runtime ABI, the raw profile format, 14*40cf9698Sjoerg * or both. 15*40cf9698Sjoerg * 16*40cf9698Sjoerg * The file has two identical copies. The master copy lives in LLVM and 17*40cf9698Sjoerg * the other one sits in compiler-rt/lib/profile directory. To make changes 18*40cf9698Sjoerg * in this file, first modify the master copy and copy it over to compiler-rt. 19*40cf9698Sjoerg * Testing of any change in this file can start only after the two copies are 20*40cf9698Sjoerg * synced up. 21*40cf9698Sjoerg * 22*40cf9698Sjoerg * The first part of the file includes macros that defines types, names, and 23*40cf9698Sjoerg * initializers for the member fields of the core data structures. The field 24*40cf9698Sjoerg * declarations for one structure is enabled by defining the field activation 25*40cf9698Sjoerg * macro associated with that structure. Only one field activation record 26*40cf9698Sjoerg * can be defined at one time and the rest definitions will be filtered out by 27*40cf9698Sjoerg * the preprocessor. 28*40cf9698Sjoerg * 29*40cf9698Sjoerg * Examples of how the template is used to instantiate structure definition: 30*40cf9698Sjoerg * 1. To declare a structure: 31*40cf9698Sjoerg * 32*40cf9698Sjoerg * struct ProfData { 33*40cf9698Sjoerg * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 34*40cf9698Sjoerg * Type Name; 35*40cf9698Sjoerg * #include "llvm/ProfileData/InstrProfData.inc" 36*40cf9698Sjoerg * }; 37*40cf9698Sjoerg * 38*40cf9698Sjoerg * 2. To construct LLVM type arrays for the struct type: 39*40cf9698Sjoerg * 40*40cf9698Sjoerg * Type *DataTypes[] = { 41*40cf9698Sjoerg * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 42*40cf9698Sjoerg * LLVMType, 43*40cf9698Sjoerg * #include "llvm/ProfileData/InstrProfData.inc" 44*40cf9698Sjoerg * }; 45*40cf9698Sjoerg * 46*40cf9698Sjoerg * 4. To construct constant array for the initializers: 47*40cf9698Sjoerg * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ 48*40cf9698Sjoerg * Initializer, 49*40cf9698Sjoerg * Constant *ConstantVals[] = { 50*40cf9698Sjoerg * #include "llvm/ProfileData/InstrProfData.inc" 51*40cf9698Sjoerg * }; 52*40cf9698Sjoerg * 53*40cf9698Sjoerg * 54*40cf9698Sjoerg * The second part of the file includes definitions all other entities that 55*40cf9698Sjoerg * are related to runtime ABI and format. When no field activation macro is 56*40cf9698Sjoerg * defined, this file can be included to introduce the definitions. 57*40cf9698Sjoerg * 58*40cf9698Sjoerg\*===----------------------------------------------------------------------===*/ 59*40cf9698Sjoerg 60*40cf9698Sjoerg/* INSTR_PROF_DATA start. */ 61*40cf9698Sjoerg/* Definition of member fields of the per-function control structure. */ 62*40cf9698Sjoerg#ifndef INSTR_PROF_DATA 63*40cf9698Sjoerg#define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) 64*40cf9698Sjoerg#else 65*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 66*40cf9698Sjoerg#endif 67*40cf9698Sjoerg 68*40cf9698SjoergINSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ 69*40cf9698Sjoerg ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \ 70*40cf9698Sjoerg NamePtr->getType()->getPointerElementType()->getArrayNumElements())) 71*40cf9698SjoergINSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \ 72*40cf9698Sjoerg ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters)) 73*40cf9698SjoergINSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ 74*40cf9698Sjoerg ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \ 75*40cf9698Sjoerg Inc->getHash()->getZExtValue())) 76*40cf9698SjoergINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), NamePtr, \ 77*40cf9698Sjoerg ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx))) 78*40cf9698SjoergINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt64PtrTy(Ctx), CounterPtr, \ 79*40cf9698Sjoerg ConstantExpr::getBitCast(CounterPtr, \ 80*40cf9698Sjoerg llvm::Type::getInt64PtrTy(Ctx))) 81*40cf9698SjoergINSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), FunctionPointer, \ 82*40cf9698Sjoerg FunctionAddr) 83*40cf9698SjoergINSTR_PROF_DATA(IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \ 84*40cf9698Sjoerg ConstantPointerNull::get(Int8PtrTy)) 85*40cf9698SjoergINSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \ 86*40cf9698Sjoerg ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) 87*40cf9698Sjoerg#undef INSTR_PROF_DATA 88*40cf9698Sjoerg/* INSTR_PROF_DATA end. */ 89*40cf9698Sjoerg 90*40cf9698Sjoerg/* INSTR_PROF_RAW_HEADER start */ 91*40cf9698Sjoerg/* Definition of member fields of the raw profile header data structure. */ 92*40cf9698Sjoerg#ifndef INSTR_PROF_RAW_HEADER 93*40cf9698Sjoerg#define INSTR_PROF_RAW_HEADER(Type, Name, Initializer) 94*40cf9698Sjoerg#else 95*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 96*40cf9698Sjoerg#endif 97*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, Magic, __llvm_profile_get_magic()) 98*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, Version, __llvm_profile_get_version()) 99*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, DataSize, DataSize) 100*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, CountersSize, CountersSize) 101*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) 102*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, (uintptr_t)CountersBegin) 103*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin) 104*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last) 105*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, ValueDataSize, ValueDataSize) 106*40cf9698SjoergINSTR_PROF_RAW_HEADER(uint64_t, ValueDataDelta, (uintptr_t)ValueDataBegin) 107*40cf9698Sjoerg#undef INSTR_PROF_RAW_HEADER 108*40cf9698Sjoerg/* INSTR_PROF_RAW_HEADER end */ 109*40cf9698Sjoerg 110*40cf9698Sjoerg/* VALUE_PROF_FUNC_PARAM start */ 111*40cf9698Sjoerg/* Definition of parameter types of the runtime API used to do value profiling 112*40cf9698Sjoerg * for a given value site. 113*40cf9698Sjoerg */ 114*40cf9698Sjoerg#ifndef VALUE_PROF_FUNC_PARAM 115*40cf9698Sjoerg#define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType) 116*40cf9698Sjoerg#define INSTR_PROF_COMMA 117*40cf9698Sjoerg#else 118*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 119*40cf9698Sjoerg#define INSTR_PROF_COMMA , 120*40cf9698Sjoerg#endif 121*40cf9698SjoergVALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \ 122*40cf9698Sjoerg INSTR_PROF_COMMA 123*40cf9698SjoergVALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA 124*40cf9698SjoergVALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) 125*40cf9698Sjoerg#undef VALUE_PROF_FUNC_PARAM 126*40cf9698Sjoerg#undef INSTR_PROF_COMMA 127*40cf9698Sjoerg/* VALUE_PROF_FUNC_PARAM end */ 128*40cf9698Sjoerg 129*40cf9698Sjoerg/* VALUE_PROF_KIND start */ 130*40cf9698Sjoerg#ifndef VALUE_PROF_KIND 131*40cf9698Sjoerg#define VALUE_PROF_KIND(Enumerator, Value) 132*40cf9698Sjoerg#else 133*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 134*40cf9698Sjoerg#endif 135*40cf9698SjoergVALUE_PROF_KIND(IPVK_IndirectCallTarget, 0) 136*40cf9698Sjoerg/* These two kinds must be the last to be 137*40cf9698Sjoerg * declared. This is to make sure the string 138*40cf9698Sjoerg * array created with the template can be 139*40cf9698Sjoerg * indexed with the kind value. 140*40cf9698Sjoerg */ 141*40cf9698SjoergVALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget) 142*40cf9698SjoergVALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget) 143*40cf9698Sjoerg 144*40cf9698Sjoerg#undef VALUE_PROF_KIND 145*40cf9698Sjoerg/* VALUE_PROF_KIND end */ 146*40cf9698Sjoerg 147*40cf9698Sjoerg/* COVMAP_FUNC_RECORD start */ 148*40cf9698Sjoerg/* Definition of member fields of the function record structure in coverage 149*40cf9698Sjoerg * map. 150*40cf9698Sjoerg */ 151*40cf9698Sjoerg#ifndef COVMAP_FUNC_RECORD 152*40cf9698Sjoerg#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) 153*40cf9698Sjoerg#else 154*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 155*40cf9698Sjoerg#endif 156*40cf9698SjoergCOVMAP_FUNC_RECORD(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), \ 157*40cf9698Sjoerg NamePtr, llvm::ConstantExpr::getBitCast(NamePtr, \ 158*40cf9698Sjoerg llvm::Type::getInt8PtrTy(Ctx))) 159*40cf9698SjoergCOVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ 160*40cf9698Sjoerg llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\ 161*40cf9698Sjoerg NameValue.size())) 162*40cf9698SjoergCOVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), DataSize, \ 163*40cf9698Sjoerg llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\ 164*40cf9698Sjoerg CoverageMapping.size())) 165*40cf9698SjoergCOVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \ 166*40cf9698Sjoerg llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), FuncHash)) 167*40cf9698Sjoerg#undef COVMAP_FUNC_RECORD 168*40cf9698Sjoerg/* COVMAP_FUNC_RECORD end. */ 169*40cf9698Sjoerg 170*40cf9698Sjoerg/* COVMAP_HEADER start */ 171*40cf9698Sjoerg/* Definition of member fields of coverage map header. 172*40cf9698Sjoerg */ 173*40cf9698Sjoerg#ifndef COVMAP_HEADER 174*40cf9698Sjoerg#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) 175*40cf9698Sjoerg#else 176*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 177*40cf9698Sjoerg#endif 178*40cf9698SjoergCOVMAP_HEADER(uint32_t, Int32Ty, NRecords, \ 179*40cf9698Sjoerg llvm::ConstantInt::get(Int32Ty, FunctionRecords.size())) 180*40cf9698SjoergCOVMAP_HEADER(uint32_t, Int32Ty, FilenamesSize, \ 181*40cf9698Sjoerg llvm::ConstantInt::get(Int32Ty, FilenamesSize)) 182*40cf9698SjoergCOVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ 183*40cf9698Sjoerg llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) 184*40cf9698SjoergCOVMAP_HEADER(uint32_t, Int32Ty, Version, \ 185*40cf9698Sjoerg llvm::ConstantInt::get(Int32Ty, CovMapVersion::CurrentVersion)) 186*40cf9698Sjoerg#undef COVMAP_HEADER 187*40cf9698Sjoerg/* COVMAP_HEADER end. */ 188*40cf9698Sjoerg 189*40cf9698Sjoerg 190*40cf9698Sjoerg#ifdef INSTR_PROF_VALUE_PROF_DATA 191*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 192*40cf9698Sjoerg 193*40cf9698Sjoerg#define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255 194*40cf9698Sjoerg/*! 195*40cf9698Sjoerg * This is the header of the data structure that defines the on-disk 196*40cf9698Sjoerg * layout of the value profile data of a particular kind for one function. 197*40cf9698Sjoerg */ 198*40cf9698Sjoergtypedef struct ValueProfRecord { 199*40cf9698Sjoerg /* The kind of the value profile record. */ 200*40cf9698Sjoerg uint32_t Kind; 201*40cf9698Sjoerg /* 202*40cf9698Sjoerg * The number of value profile sites. It is guaranteed to be non-zero; 203*40cf9698Sjoerg * otherwise the record for this kind won't be emitted. 204*40cf9698Sjoerg */ 205*40cf9698Sjoerg uint32_t NumValueSites; 206*40cf9698Sjoerg /* 207*40cf9698Sjoerg * The first element of the array that stores the number of profiled 208*40cf9698Sjoerg * values for each value site. The size of the array is NumValueSites. 209*40cf9698Sjoerg * Since NumValueSites is greater than zero, there is at least one 210*40cf9698Sjoerg * element in the array. 211*40cf9698Sjoerg */ 212*40cf9698Sjoerg uint8_t SiteCountArray[1]; 213*40cf9698Sjoerg 214*40cf9698Sjoerg /* 215*40cf9698Sjoerg * The fake declaration is for documentation purpose only. 216*40cf9698Sjoerg * Align the start of next field to be on 8 byte boundaries. 217*40cf9698Sjoerg uint8_t Padding[X]; 218*40cf9698Sjoerg */ 219*40cf9698Sjoerg 220*40cf9698Sjoerg /* The array of value profile data. The size of the array is the sum 221*40cf9698Sjoerg * of all elements in SiteCountArray[]. 222*40cf9698Sjoerg InstrProfValueData ValueData[]; 223*40cf9698Sjoerg */ 224*40cf9698Sjoerg 225*40cf9698Sjoerg#ifdef __cplusplus 226*40cf9698Sjoerg /*! 227*40cf9698Sjoerg * \brief Return the number of value sites. 228*40cf9698Sjoerg */ 229*40cf9698Sjoerg uint32_t getNumValueSites() const { return NumValueSites; } 230*40cf9698Sjoerg /*! 231*40cf9698Sjoerg * \brief Read data from this record and save it to Record. 232*40cf9698Sjoerg */ 233*40cf9698Sjoerg void deserializeTo(InstrProfRecord &Record, 234*40cf9698Sjoerg InstrProfRecord::ValueMapType *VMap); 235*40cf9698Sjoerg /* 236*40cf9698Sjoerg * In-place byte swap: 237*40cf9698Sjoerg * Do byte swap for this instance. \c Old is the original order before 238*40cf9698Sjoerg * the swap, and \c New is the New byte order. 239*40cf9698Sjoerg */ 240*40cf9698Sjoerg void swapBytes(support::endianness Old, support::endianness New); 241*40cf9698Sjoerg#endif 242*40cf9698Sjoerg} ValueProfRecord; 243*40cf9698Sjoerg 244*40cf9698Sjoerg/*! 245*40cf9698Sjoerg * Per-function header/control data structure for value profiling 246*40cf9698Sjoerg * data in indexed format. 247*40cf9698Sjoerg */ 248*40cf9698Sjoergtypedef struct ValueProfData { 249*40cf9698Sjoerg /* 250*40cf9698Sjoerg * Total size in bytes including this field. It must be a multiple 251*40cf9698Sjoerg * of sizeof(uint64_t). 252*40cf9698Sjoerg */ 253*40cf9698Sjoerg uint32_t TotalSize; 254*40cf9698Sjoerg /* 255*40cf9698Sjoerg *The number of value profile kinds that has value profile data. 256*40cf9698Sjoerg * In this implementation, a value profile kind is considered to 257*40cf9698Sjoerg * have profile data if the number of value profile sites for the 258*40cf9698Sjoerg * kind is not zero. More aggressively, the implementation can 259*40cf9698Sjoerg * choose to check the actual data value: if none of the value sites 260*40cf9698Sjoerg * has any profiled values, the kind can be skipped. 261*40cf9698Sjoerg */ 262*40cf9698Sjoerg uint32_t NumValueKinds; 263*40cf9698Sjoerg 264*40cf9698Sjoerg /* 265*40cf9698Sjoerg * Following are a sequence of variable length records. The prefix/header 266*40cf9698Sjoerg * of each record is defined by ValueProfRecord type. The number of 267*40cf9698Sjoerg * records is NumValueKinds. 268*40cf9698Sjoerg * ValueProfRecord Record_1; 269*40cf9698Sjoerg * ValueProfRecord Record_N; 270*40cf9698Sjoerg */ 271*40cf9698Sjoerg 272*40cf9698Sjoerg#if __cplusplus 273*40cf9698Sjoerg /*! 274*40cf9698Sjoerg * Return the total size in bytes of the on-disk value profile data 275*40cf9698Sjoerg * given the data stored in Record. 276*40cf9698Sjoerg */ 277*40cf9698Sjoerg static uint32_t getSize(const InstrProfRecord &Record); 278*40cf9698Sjoerg /*! 279*40cf9698Sjoerg * Return a pointer to \c ValueProfData instance ready to be streamed. 280*40cf9698Sjoerg */ 281*40cf9698Sjoerg static std::unique_ptr<ValueProfData> 282*40cf9698Sjoerg serializeFrom(const InstrProfRecord &Record); 283*40cf9698Sjoerg /*! 284*40cf9698Sjoerg * Check the integrity of the record. Return the error code when 285*40cf9698Sjoerg * an error is detected, otherwise return instrprof_error::success. 286*40cf9698Sjoerg */ 287*40cf9698Sjoerg instrprof_error checkIntegrity(); 288*40cf9698Sjoerg /*! 289*40cf9698Sjoerg * Return a pointer to \c ValueProfileData instance ready to be read. 290*40cf9698Sjoerg * All data in the instance are properly byte swapped. The input 291*40cf9698Sjoerg * data is assumed to be in little endian order. 292*40cf9698Sjoerg */ 293*40cf9698Sjoerg static ErrorOr<std::unique_ptr<ValueProfData>> 294*40cf9698Sjoerg getValueProfData(const unsigned char *SrcBuffer, 295*40cf9698Sjoerg const unsigned char *const SrcBufferEnd, 296*40cf9698Sjoerg support::endianness SrcDataEndianness); 297*40cf9698Sjoerg /*! 298*40cf9698Sjoerg * Swap byte order from \c Endianness order to host byte order. 299*40cf9698Sjoerg */ 300*40cf9698Sjoerg void swapBytesToHost(support::endianness Endianness); 301*40cf9698Sjoerg /*! 302*40cf9698Sjoerg * Swap byte order from host byte order to \c Endianness order. 303*40cf9698Sjoerg */ 304*40cf9698Sjoerg void swapBytesFromHost(support::endianness Endianness); 305*40cf9698Sjoerg /*! 306*40cf9698Sjoerg * Return the total size of \c ValueProfileData. 307*40cf9698Sjoerg */ 308*40cf9698Sjoerg uint32_t getSize() const { return TotalSize; } 309*40cf9698Sjoerg /*! 310*40cf9698Sjoerg * Read data from this data and save it to \c Record. 311*40cf9698Sjoerg */ 312*40cf9698Sjoerg void deserializeTo(InstrProfRecord &Record, 313*40cf9698Sjoerg InstrProfRecord::ValueMapType *VMap); 314*40cf9698Sjoerg void operator delete(void *ptr) { ::operator delete(ptr); } 315*40cf9698Sjoerg#endif 316*40cf9698Sjoerg} ValueProfData; 317*40cf9698Sjoerg 318*40cf9698Sjoerg/* 319*40cf9698Sjoerg * The closure is designed to abstact away two types of value profile data: 320*40cf9698Sjoerg * - InstrProfRecord which is the primary data structure used to 321*40cf9698Sjoerg * represent profile data in host tools (reader, writer, and profile-use) 322*40cf9698Sjoerg * - value profile runtime data structure suitable to be used by C 323*40cf9698Sjoerg * runtime library. 324*40cf9698Sjoerg * 325*40cf9698Sjoerg * Both sources of data need to serialize to disk/memory-buffer in common 326*40cf9698Sjoerg * format: ValueProfData. The abstraction allows compiler-rt's raw profiler 327*40cf9698Sjoerg * writer to share the same format and code with indexed profile writer. 328*40cf9698Sjoerg * 329*40cf9698Sjoerg * For documentation of the member methods below, refer to corresponding methods 330*40cf9698Sjoerg * in class InstrProfRecord. 331*40cf9698Sjoerg */ 332*40cf9698Sjoergtypedef struct ValueProfRecordClosure { 333*40cf9698Sjoerg const void *Record; 334*40cf9698Sjoerg uint32_t (*GetNumValueKinds)(const void *Record); 335*40cf9698Sjoerg uint32_t (*GetNumValueSites)(const void *Record, uint32_t VKind); 336*40cf9698Sjoerg uint32_t (*GetNumValueData)(const void *Record, uint32_t VKind); 337*40cf9698Sjoerg uint32_t (*GetNumValueDataForSite)(const void *R, uint32_t VK, uint32_t S); 338*40cf9698Sjoerg 339*40cf9698Sjoerg /* 340*40cf9698Sjoerg * After extracting the value profile data from the value profile record, 341*40cf9698Sjoerg * this method is used to map the in-memory value to on-disk value. If 342*40cf9698Sjoerg * the method is null, value will be written out untranslated. 343*40cf9698Sjoerg */ 344*40cf9698Sjoerg uint64_t (*RemapValueData)(uint32_t, uint64_t Value); 345*40cf9698Sjoerg void (*GetValueForSite)(const void *R, InstrProfValueData *Dst, uint32_t K, 346*40cf9698Sjoerg uint32_t S, uint64_t (*Mapper)(uint32_t, uint64_t)); 347*40cf9698Sjoerg ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes); 348*40cf9698Sjoerg} ValueProfRecordClosure; 349*40cf9698Sjoerg 350*40cf9698Sjoerg/* 351*40cf9698Sjoerg * A wrapper struct that represents value profile runtime data. 352*40cf9698Sjoerg * Like InstrProfRecord class which is used by profiling host tools, 353*40cf9698Sjoerg * ValueProfRuntimeRecord also implements the abstract intefaces defined in 354*40cf9698Sjoerg * ValueProfRecordClosure so that the runtime data can be serialized using 355*40cf9698Sjoerg * shared C implementation. In this structure, NumValueSites and Nodes 356*40cf9698Sjoerg * members are the primary fields while other fields hold the derived 357*40cf9698Sjoerg * information for fast implementation of closure interfaces. 358*40cf9698Sjoerg */ 359*40cf9698Sjoergtypedef struct ValueProfRuntimeRecord { 360*40cf9698Sjoerg /* Number of sites for each value profile kind. */ 361*40cf9698Sjoerg const uint16_t *NumValueSites; 362*40cf9698Sjoerg /* An array of linked-list headers. The size of of the array is the 363*40cf9698Sjoerg * total number of value profile sites : sum(NumValueSites[*])). Each 364*40cf9698Sjoerg * linked-list stores the values profiled for a value profile site. */ 365*40cf9698Sjoerg ValueProfNode **Nodes; 366*40cf9698Sjoerg 367*40cf9698Sjoerg /* Total number of value profile kinds which have at least one 368*40cf9698Sjoerg * value profile sites. */ 369*40cf9698Sjoerg uint32_t NumValueKinds; 370*40cf9698Sjoerg /* An array recording the number of values tracked at each site. 371*40cf9698Sjoerg * The size of the array is TotalNumValueSites. */ 372*40cf9698Sjoerg uint8_t *SiteCountArray[IPVK_Last + 1]; 373*40cf9698Sjoerg ValueProfNode **NodesKind[IPVK_Last + 1]; 374*40cf9698Sjoerg} ValueProfRuntimeRecord; 375*40cf9698Sjoerg 376*40cf9698Sjoerg/* Forward declarations of C interfaces. */ 377*40cf9698Sjoergint initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord, 378*40cf9698Sjoerg const uint16_t *NumValueSites, 379*40cf9698Sjoerg ValueProfNode **Nodes); 380*40cf9698Sjoergvoid finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord); 381*40cf9698Sjoerguint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record); 382*40cf9698SjoergValueProfData * 383*40cf9698SjoergserializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, 384*40cf9698Sjoerg ValueProfData *Dst); 385*40cf9698Sjoerguint32_t getNumValueKindsRT(const void *R); 386*40cf9698Sjoerg 387*40cf9698Sjoerg#undef INSTR_PROF_VALUE_PROF_DATA 388*40cf9698Sjoerg#endif /* INSTR_PROF_VALUE_PROF_DATA */ 389*40cf9698Sjoerg 390*40cf9698Sjoerg 391*40cf9698Sjoerg#ifdef INSTR_PROF_COMMON_API_IMPL 392*40cf9698Sjoerg#define INSTR_PROF_DATA_DEFINED 393*40cf9698Sjoerg#ifdef __cplusplus 394*40cf9698Sjoerg#define INSTR_PROF_INLINE inline 395*40cf9698Sjoerg#define INSTR_PROF_NULLPTR nullptr 396*40cf9698Sjoerg#else 397*40cf9698Sjoerg#define INSTR_PROF_INLINE 398*40cf9698Sjoerg#define INSTR_PROF_NULLPTR NULL 399*40cf9698Sjoerg#endif 400*40cf9698Sjoerg 401*40cf9698Sjoerg#ifndef offsetof 402*40cf9698Sjoerg#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 403*40cf9698Sjoerg#endif 404*40cf9698Sjoerg 405*40cf9698Sjoerg/*! 406*40cf9698Sjoerg * \brief Return the \c ValueProfRecord header size including the 407*40cf9698Sjoerg * padding bytes. 408*40cf9698Sjoerg */ 409*40cf9698SjoergINSTR_PROF_INLINE 410*40cf9698Sjoerguint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites) { 411*40cf9698Sjoerg uint32_t Size = offsetof(ValueProfRecord, SiteCountArray) + 412*40cf9698Sjoerg sizeof(uint8_t) * NumValueSites; 413*40cf9698Sjoerg /* Round the size to multiple of 8 bytes. */ 414*40cf9698Sjoerg Size = (Size + 7) & ~7; 415*40cf9698Sjoerg return Size; 416*40cf9698Sjoerg} 417*40cf9698Sjoerg 418*40cf9698Sjoerg/*! 419*40cf9698Sjoerg * \brief Return the total size of the value profile record including the 420*40cf9698Sjoerg * header and the value data. 421*40cf9698Sjoerg */ 422*40cf9698SjoergINSTR_PROF_INLINE 423*40cf9698Sjoerguint32_t getValueProfRecordSize(uint32_t NumValueSites, 424*40cf9698Sjoerg uint32_t NumValueData) { 425*40cf9698Sjoerg return getValueProfRecordHeaderSize(NumValueSites) + 426*40cf9698Sjoerg sizeof(InstrProfValueData) * NumValueData; 427*40cf9698Sjoerg} 428*40cf9698Sjoerg 429*40cf9698Sjoerg/*! 430*40cf9698Sjoerg * \brief Return the pointer to the start of value data array. 431*40cf9698Sjoerg */ 432*40cf9698SjoergINSTR_PROF_INLINE 433*40cf9698SjoergInstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) { 434*40cf9698Sjoerg return (InstrProfValueData *)((char *)This + getValueProfRecordHeaderSize( 435*40cf9698Sjoerg This->NumValueSites)); 436*40cf9698Sjoerg} 437*40cf9698Sjoerg 438*40cf9698Sjoerg/*! 439*40cf9698Sjoerg * \brief Return the total number of value data for \c This record. 440*40cf9698Sjoerg */ 441*40cf9698SjoergINSTR_PROF_INLINE 442*40cf9698Sjoerguint32_t getValueProfRecordNumValueData(ValueProfRecord *This) { 443*40cf9698Sjoerg uint32_t NumValueData = 0; 444*40cf9698Sjoerg uint32_t I; 445*40cf9698Sjoerg for (I = 0; I < This->NumValueSites; I++) 446*40cf9698Sjoerg NumValueData += This->SiteCountArray[I]; 447*40cf9698Sjoerg return NumValueData; 448*40cf9698Sjoerg} 449*40cf9698Sjoerg 450*40cf9698Sjoerg/*! 451*40cf9698Sjoerg * \brief Use this method to advance to the next \c This \c ValueProfRecord. 452*40cf9698Sjoerg */ 453*40cf9698SjoergINSTR_PROF_INLINE 454*40cf9698SjoergValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) { 455*40cf9698Sjoerg uint32_t NumValueData = getValueProfRecordNumValueData(This); 456*40cf9698Sjoerg return (ValueProfRecord *)((char *)This + 457*40cf9698Sjoerg getValueProfRecordSize(This->NumValueSites, 458*40cf9698Sjoerg NumValueData)); 459*40cf9698Sjoerg} 460*40cf9698Sjoerg 461*40cf9698Sjoerg/*! 462*40cf9698Sjoerg * \brief Return the first \c ValueProfRecord instance. 463*40cf9698Sjoerg */ 464*40cf9698SjoergINSTR_PROF_INLINE 465*40cf9698SjoergValueProfRecord *getFirstValueProfRecord(ValueProfData *This) { 466*40cf9698Sjoerg return (ValueProfRecord *)((char *)This + sizeof(ValueProfData)); 467*40cf9698Sjoerg} 468*40cf9698Sjoerg 469*40cf9698Sjoerg/* Closure based interfaces. */ 470*40cf9698Sjoerg 471*40cf9698Sjoerg/*! 472*40cf9698Sjoerg * Return the total size in bytes of the on-disk value profile data 473*40cf9698Sjoerg * given the data stored in Record. 474*40cf9698Sjoerg */ 475*40cf9698Sjoerguint32_t getValueProfDataSize(ValueProfRecordClosure *Closure) { 476*40cf9698Sjoerg uint32_t Kind; 477*40cf9698Sjoerg uint32_t TotalSize = sizeof(ValueProfData); 478*40cf9698Sjoerg const void *Record = Closure->Record; 479*40cf9698Sjoerg uint32_t NumValueKinds = Closure->GetNumValueKinds(Record); 480*40cf9698Sjoerg if (NumValueKinds == 0) 481*40cf9698Sjoerg return TotalSize; 482*40cf9698Sjoerg 483*40cf9698Sjoerg for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 484*40cf9698Sjoerg uint32_t NumValueSites = Closure->GetNumValueSites(Record, Kind); 485*40cf9698Sjoerg if (!NumValueSites) 486*40cf9698Sjoerg continue; 487*40cf9698Sjoerg TotalSize += getValueProfRecordSize(NumValueSites, 488*40cf9698Sjoerg Closure->GetNumValueData(Record, Kind)); 489*40cf9698Sjoerg } 490*40cf9698Sjoerg return TotalSize; 491*40cf9698Sjoerg} 492*40cf9698Sjoerg 493*40cf9698Sjoerg/*! 494*40cf9698Sjoerg * Extract value profile data of a function for the profile kind \c ValueKind 495*40cf9698Sjoerg * from the \c Closure and serialize the data into \c This record instance. 496*40cf9698Sjoerg */ 497*40cf9698Sjoergvoid serializeValueProfRecordFrom(ValueProfRecord *This, 498*40cf9698Sjoerg ValueProfRecordClosure *Closure, 499*40cf9698Sjoerg uint32_t ValueKind, uint32_t NumValueSites) { 500*40cf9698Sjoerg uint32_t S; 501*40cf9698Sjoerg const void *Record = Closure->Record; 502*40cf9698Sjoerg This->Kind = ValueKind; 503*40cf9698Sjoerg This->NumValueSites = NumValueSites; 504*40cf9698Sjoerg InstrProfValueData *DstVD = getValueProfRecordValueData(This); 505*40cf9698Sjoerg 506*40cf9698Sjoerg for (S = 0; S < NumValueSites; S++) { 507*40cf9698Sjoerg uint32_t ND = Closure->GetNumValueDataForSite(Record, ValueKind, S); 508*40cf9698Sjoerg This->SiteCountArray[S] = ND; 509*40cf9698Sjoerg Closure->GetValueForSite(Record, DstVD, ValueKind, S, 510*40cf9698Sjoerg Closure->RemapValueData); 511*40cf9698Sjoerg DstVD += ND; 512*40cf9698Sjoerg } 513*40cf9698Sjoerg} 514*40cf9698Sjoerg 515*40cf9698Sjoerg/*! 516*40cf9698Sjoerg * Extract value profile data of a function from the \c Closure 517*40cf9698Sjoerg * and serialize the data into \c DstData if it is not NULL or heap 518*40cf9698Sjoerg * memory allocated by the \c Closure's allocator method. 519*40cf9698Sjoerg */ 520*40cf9698SjoergValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure, 521*40cf9698Sjoerg ValueProfData *DstData) { 522*40cf9698Sjoerg uint32_t Kind; 523*40cf9698Sjoerg uint32_t TotalSize = getValueProfDataSize(Closure); 524*40cf9698Sjoerg 525*40cf9698Sjoerg ValueProfData *VPD = 526*40cf9698Sjoerg DstData ? DstData : Closure->AllocValueProfData(TotalSize); 527*40cf9698Sjoerg 528*40cf9698Sjoerg VPD->TotalSize = TotalSize; 529*40cf9698Sjoerg VPD->NumValueKinds = Closure->GetNumValueKinds(Closure->Record); 530*40cf9698Sjoerg ValueProfRecord *VR = getFirstValueProfRecord(VPD); 531*40cf9698Sjoerg for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 532*40cf9698Sjoerg uint32_t NumValueSites = Closure->GetNumValueSites(Closure->Record, Kind); 533*40cf9698Sjoerg if (!NumValueSites) 534*40cf9698Sjoerg continue; 535*40cf9698Sjoerg serializeValueProfRecordFrom(VR, Closure, Kind, NumValueSites); 536*40cf9698Sjoerg VR = getValueProfRecordNext(VR); 537*40cf9698Sjoerg } 538*40cf9698Sjoerg return VPD; 539*40cf9698Sjoerg} 540*40cf9698Sjoerg 541*40cf9698Sjoerg/* 542*40cf9698Sjoerg * The value profiler runtime library stores the value profile data 543*40cf9698Sjoerg * for a given function in \c NumValueSites and \c Nodes structures. 544*40cf9698Sjoerg * \c ValueProfRuntimeRecord class is used to encapsulate the runtime 545*40cf9698Sjoerg * profile data and provides fast interfaces to retrieve the profile 546*40cf9698Sjoerg * information. This interface is used to initialize the runtime record 547*40cf9698Sjoerg * and pre-compute the information needed for efficient implementation 548*40cf9698Sjoerg * of callbacks required by ValueProfRecordClosure class. 549*40cf9698Sjoerg */ 550*40cf9698Sjoergint initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord, 551*40cf9698Sjoerg const uint16_t *NumValueSites, 552*40cf9698Sjoerg ValueProfNode **Nodes) { 553*40cf9698Sjoerg unsigned I, J, S = 0, NumValueKinds = 0; 554*40cf9698Sjoerg RuntimeRecord->NumValueSites = NumValueSites; 555*40cf9698Sjoerg RuntimeRecord->Nodes = Nodes; 556*40cf9698Sjoerg for (I = 0; I <= IPVK_Last; I++) { 557*40cf9698Sjoerg uint16_t N = NumValueSites[I]; 558*40cf9698Sjoerg if (!N) { 559*40cf9698Sjoerg RuntimeRecord->SiteCountArray[I] = INSTR_PROF_NULLPTR; 560*40cf9698Sjoerg continue; 561*40cf9698Sjoerg } 562*40cf9698Sjoerg NumValueKinds++; 563*40cf9698Sjoerg RuntimeRecord->SiteCountArray[I] = (uint8_t *)calloc(N, 1); 564*40cf9698Sjoerg if (!RuntimeRecord->SiteCountArray[I]) 565*40cf9698Sjoerg return 1; 566*40cf9698Sjoerg RuntimeRecord->NodesKind[I] = Nodes ? &Nodes[S] : INSTR_PROF_NULLPTR; 567*40cf9698Sjoerg for (J = 0; J < N; J++) { 568*40cf9698Sjoerg /* Compute value count for each site. */ 569*40cf9698Sjoerg uint32_t C = 0; 570*40cf9698Sjoerg ValueProfNode *Site = 571*40cf9698Sjoerg Nodes ? RuntimeRecord->NodesKind[I][J] : INSTR_PROF_NULLPTR; 572*40cf9698Sjoerg while (Site) { 573*40cf9698Sjoerg C++; 574*40cf9698Sjoerg Site = Site->Next; 575*40cf9698Sjoerg } 576*40cf9698Sjoerg if (C > UCHAR_MAX) 577*40cf9698Sjoerg C = UCHAR_MAX; 578*40cf9698Sjoerg RuntimeRecord->SiteCountArray[I][J] = C; 579*40cf9698Sjoerg } 580*40cf9698Sjoerg S += N; 581*40cf9698Sjoerg } 582*40cf9698Sjoerg RuntimeRecord->NumValueKinds = NumValueKinds; 583*40cf9698Sjoerg return 0; 584*40cf9698Sjoerg} 585*40cf9698Sjoerg 586*40cf9698Sjoergvoid finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord) { 587*40cf9698Sjoerg unsigned I; 588*40cf9698Sjoerg for (I = 0; I <= IPVK_Last; I++) { 589*40cf9698Sjoerg if (RuntimeRecord->SiteCountArray[I]) 590*40cf9698Sjoerg free(RuntimeRecord->SiteCountArray[I]); 591*40cf9698Sjoerg } 592*40cf9698Sjoerg} 593*40cf9698Sjoerg 594*40cf9698Sjoerg/* ValueProfRecordClosure Interface implementation for 595*40cf9698Sjoerg * ValueProfDataRuntimeRecord. */ 596*40cf9698Sjoerguint32_t getNumValueKindsRT(const void *R) { 597*40cf9698Sjoerg return ((const ValueProfRuntimeRecord *)R)->NumValueKinds; 598*40cf9698Sjoerg} 599*40cf9698Sjoerg 600*40cf9698Sjoerguint32_t getNumValueSitesRT(const void *R, uint32_t VK) { 601*40cf9698Sjoerg return ((const ValueProfRuntimeRecord *)R)->NumValueSites[VK]; 602*40cf9698Sjoerg} 603*40cf9698Sjoerg 604*40cf9698Sjoerguint32_t getNumValueDataForSiteRT(const void *R, uint32_t VK, uint32_t S) { 605*40cf9698Sjoerg const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; 606*40cf9698Sjoerg return Record->SiteCountArray[VK][S]; 607*40cf9698Sjoerg} 608*40cf9698Sjoerg 609*40cf9698Sjoerguint32_t getNumValueDataRT(const void *R, uint32_t VK) { 610*40cf9698Sjoerg unsigned I, S = 0; 611*40cf9698Sjoerg const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; 612*40cf9698Sjoerg if (Record->SiteCountArray[VK] == INSTR_PROF_NULLPTR) 613*40cf9698Sjoerg return 0; 614*40cf9698Sjoerg for (I = 0; I < Record->NumValueSites[VK]; I++) 615*40cf9698Sjoerg S += Record->SiteCountArray[VK][I]; 616*40cf9698Sjoerg return S; 617*40cf9698Sjoerg} 618*40cf9698Sjoerg 619*40cf9698Sjoergvoid getValueForSiteRT(const void *R, InstrProfValueData *Dst, uint32_t VK, 620*40cf9698Sjoerg uint32_t S, uint64_t (*Mapper)(uint32_t, uint64_t)) { 621*40cf9698Sjoerg unsigned I, N = 0; 622*40cf9698Sjoerg const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R; 623*40cf9698Sjoerg N = getNumValueDataForSiteRT(R, VK, S); 624*40cf9698Sjoerg if (N == 0) 625*40cf9698Sjoerg return; 626*40cf9698Sjoerg ValueProfNode *VNode = Record->NodesKind[VK][S]; 627*40cf9698Sjoerg for (I = 0; I < N; I++) { 628*40cf9698Sjoerg Dst[I] = VNode->VData; 629*40cf9698Sjoerg VNode = VNode->Next; 630*40cf9698Sjoerg } 631*40cf9698Sjoerg} 632*40cf9698Sjoerg 633*40cf9698SjoergValueProfData *allocValueProfDataRT(size_t TotalSizeInBytes) { 634*40cf9698Sjoerg return (ValueProfData *)calloc(TotalSizeInBytes, 1); 635*40cf9698Sjoerg} 636*40cf9698Sjoerg 637*40cf9698Sjoergstatic ValueProfRecordClosure RTRecordClosure = { 638*40cf9698Sjoerg INSTR_PROF_NULLPTR, getNumValueKindsRT, getNumValueSitesRT, 639*40cf9698Sjoerg getNumValueDataRT, getNumValueDataForSiteRT, INSTR_PROF_NULLPTR, 640*40cf9698Sjoerg getValueForSiteRT, allocValueProfDataRT}; 641*40cf9698Sjoerg 642*40cf9698Sjoerg/* 643*40cf9698Sjoerg * Return the size of ValueProfData structure to store data 644*40cf9698Sjoerg * recorded in the runtime record. 645*40cf9698Sjoerg */ 646*40cf9698Sjoerguint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record) { 647*40cf9698Sjoerg RTRecordClosure.Record = Record; 648*40cf9698Sjoerg return getValueProfDataSize(&RTRecordClosure); 649*40cf9698Sjoerg} 650*40cf9698Sjoerg 651*40cf9698Sjoerg/* 652*40cf9698Sjoerg * Return a ValueProfData instance that stores the data collected 653*40cf9698Sjoerg * from runtime. If \c DstData is provided by the caller, the value 654*40cf9698Sjoerg * profile data will be store in *DstData and DstData is returned, 655*40cf9698Sjoerg * otherwise the method will allocate space for the value data and 656*40cf9698Sjoerg * return pointer to the newly allocated space. 657*40cf9698Sjoerg */ 658*40cf9698SjoergValueProfData * 659*40cf9698SjoergserializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, 660*40cf9698Sjoerg ValueProfData *DstData) { 661*40cf9698Sjoerg RTRecordClosure.Record = Record; 662*40cf9698Sjoerg return serializeValueProfDataFrom(&RTRecordClosure, DstData); 663*40cf9698Sjoerg} 664*40cf9698Sjoerg 665*40cf9698Sjoerg#undef INSTR_PROF_COMMON_API_IMPL 666*40cf9698Sjoerg#endif /* INSTR_PROF_COMMON_API_IMPL */ 667*40cf9698Sjoerg 668*40cf9698Sjoerg/*============================================================================*/ 669*40cf9698Sjoerg 670*40cf9698Sjoerg#ifndef INSTR_PROF_DATA_DEFINED 671*40cf9698Sjoerg 672*40cf9698Sjoerg#ifndef INSTR_PROF_DATA_INC 673*40cf9698Sjoerg#define INSTR_PROF_DATA_INC 674*40cf9698Sjoerg 675*40cf9698Sjoerg/* Helper macros. */ 676*40cf9698Sjoerg#define INSTR_PROF_SIMPLE_QUOTE(x) #x 677*40cf9698Sjoerg#define INSTR_PROF_QUOTE(x) INSTR_PROF_SIMPLE_QUOTE(x) 678*40cf9698Sjoerg#define INSTR_PROF_SIMPLE_CONCAT(x,y) x ## y 679*40cf9698Sjoerg#define INSTR_PROF_CONCAT(x,y) INSTR_PROF_SIMPLE_CONCAT(x,y) 680*40cf9698Sjoerg 681*40cf9698Sjoerg/* Magic number to detect file format and endianness. 682*40cf9698Sjoerg * Use 255 at one end, since no UTF-8 file can use that character. Avoid 0, 683*40cf9698Sjoerg * so that utilities, like strings, don't grab it as a string. 129 is also 684*40cf9698Sjoerg * invalid UTF-8, and high enough to be interesting. 685*40cf9698Sjoerg * Use "lprofr" in the centre to stand for "LLVM Profile Raw", or "lprofR" 686*40cf9698Sjoerg * for 32-bit platforms. 687*40cf9698Sjoerg */ 688*40cf9698Sjoerg#define INSTR_PROF_RAW_MAGIC_64 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \ 689*40cf9698Sjoerg (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ 690*40cf9698Sjoerg (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129 691*40cf9698Sjoerg#define INSTR_PROF_RAW_MAGIC_32 (uint64_t)255 << 56 | (uint64_t)'l' << 48 | \ 692*40cf9698Sjoerg (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | (uint64_t)'o' << 24 | \ 693*40cf9698Sjoerg (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 694*40cf9698Sjoerg 695*40cf9698Sjoerg/* Raw profile format version. */ 696*40cf9698Sjoerg#define INSTR_PROF_RAW_VERSION 2 697*40cf9698Sjoerg#define INSTR_PROF_INDEX_VERSION 3 698*40cf9698Sjoerg#define INSTR_PROF_COVMAP_VERSION 0 699*40cf9698Sjoerg 700*40cf9698Sjoerg/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the 701*40cf9698Sjoerg * version for other variants of profile. We set the lowest bit of the upper 8 702*40cf9698Sjoerg * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton 703*40cf9698Sjoerg * generated profile, and 0 if this is a Clang FE generated profile. 704*40cf9698Sjoerg*/ 705*40cf9698Sjoerg#define VARIANT_MASKS_ALL 0xff00000000000000ULL 706*40cf9698Sjoerg#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL) 707*40cf9698Sjoerg 708*40cf9698Sjoerg/* Runtime section names and name strings. */ 709*40cf9698Sjoerg#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data 710*40cf9698Sjoerg#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names 711*40cf9698Sjoerg#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts 712*40cf9698Sjoerg#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap 713*40cf9698Sjoerg 714*40cf9698Sjoerg#define INSTR_PROF_DATA_SECT_NAME_STR \ 715*40cf9698Sjoerg INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME) 716*40cf9698Sjoerg#define INSTR_PROF_NAME_SECT_NAME_STR \ 717*40cf9698Sjoerg INSTR_PROF_QUOTE(INSTR_PROF_NAME_SECT_NAME) 718*40cf9698Sjoerg#define INSTR_PROF_CNTS_SECT_NAME_STR \ 719*40cf9698Sjoerg INSTR_PROF_QUOTE(INSTR_PROF_CNTS_SECT_NAME) 720*40cf9698Sjoerg#define INSTR_PROF_COVMAP_SECT_NAME_STR \ 721*40cf9698Sjoerg INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_SECT_NAME) 722*40cf9698Sjoerg 723*40cf9698Sjoerg/* Macros to define start/stop section symbol for a given 724*40cf9698Sjoerg * section on Linux. For instance 725*40cf9698Sjoerg * INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME) will 726*40cf9698Sjoerg * expand to __start___llvm_prof_data 727*40cf9698Sjoerg */ 728*40cf9698Sjoerg#define INSTR_PROF_SECT_START(Sect) \ 729*40cf9698Sjoerg INSTR_PROF_CONCAT(__start_,Sect) 730*40cf9698Sjoerg#define INSTR_PROF_SECT_STOP(Sect) \ 731*40cf9698Sjoerg INSTR_PROF_CONCAT(__stop_,Sect) 732*40cf9698Sjoerg 733*40cf9698Sjoerg/* Value Profiling API linkage name. */ 734*40cf9698Sjoerg#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target 735*40cf9698Sjoerg#define INSTR_PROF_VALUE_PROF_FUNC_STR \ 736*40cf9698Sjoerg INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC) 737*40cf9698Sjoerg 738*40cf9698Sjoerg/* InstrProfile per-function control data alignment. */ 739*40cf9698Sjoerg#define INSTR_PROF_DATA_ALIGNMENT 8 740*40cf9698Sjoerg 741*40cf9698Sjoerg/* The data structure that represents a tracked value by the 742*40cf9698Sjoerg * value profiler. 743*40cf9698Sjoerg */ 744*40cf9698Sjoergtypedef struct InstrProfValueData { 745*40cf9698Sjoerg /* Profiled value. */ 746*40cf9698Sjoerg uint64_t Value; 747*40cf9698Sjoerg /* Number of times the value appears in the training run. */ 748*40cf9698Sjoerg uint64_t Count; 749*40cf9698Sjoerg} InstrProfValueData; 750*40cf9698Sjoerg 751*40cf9698Sjoerg/* This is an internal data structure used by value profiler. It 752*40cf9698Sjoerg * is defined here to allow serialization code sharing by LLVM 753*40cf9698Sjoerg * to be used in unit test. 754*40cf9698Sjoerg */ 755*40cf9698Sjoergtypedef struct ValueProfNode { 756*40cf9698Sjoerg InstrProfValueData VData; 757*40cf9698Sjoerg struct ValueProfNode *Next; 758*40cf9698Sjoerg} ValueProfNode; 759*40cf9698Sjoerg 760*40cf9698Sjoerg#endif /* INSTR_PROF_DATA_INC */ 761*40cf9698Sjoerg 762*40cf9698Sjoerg#else 763*40cf9698Sjoerg#undef INSTR_PROF_DATA_DEFINED 764*40cf9698Sjoerg#endif 765