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