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