1*0b57cec5SDimitry Andric /*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\ 2*0b57cec5SDimitry Andric |* 3*0b57cec5SDimitry Andric |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric |* See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric |* 7*0b57cec5SDimitry Andric \*===----------------------------------------------------------------------===*/ 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef PROFILE_INSTRPROFILING_H_ 10*0b57cec5SDimitry Andric #define PROFILE_INSTRPROFILING_H_ 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "InstrProfilingPort.h" 13*0b57cec5SDimitry Andric #include <stdio.h> 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #define INSTR_PROF_VISIBILITY COMPILER_RT_VISIBILITY 16*0b57cec5SDimitry Andric #include "InstrProfData.inc" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric enum ValueKind { 19*0b57cec5SDimitry Andric #define VALUE_PROF_KIND(Enumerator, Value, Descr) Enumerator = Value, 20*0b57cec5SDimitry Andric #include "InstrProfData.inc" 21*0b57cec5SDimitry Andric }; 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric typedef void *IntPtrT; 24*0b57cec5SDimitry Andric typedef struct COMPILER_RT_ALIGNAS(INSTR_PROF_DATA_ALIGNMENT) 25*0b57cec5SDimitry Andric __llvm_profile_data { 26*0b57cec5SDimitry Andric #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) Type Name; 27*0b57cec5SDimitry Andric #include "InstrProfData.inc" 28*0b57cec5SDimitry Andric } __llvm_profile_data; 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric typedef struct __llvm_profile_header { 31*0b57cec5SDimitry Andric #define INSTR_PROF_RAW_HEADER(Type, Name, Initializer) Type Name; 32*0b57cec5SDimitry Andric #include "InstrProfData.inc" 33*0b57cec5SDimitry Andric } __llvm_profile_header; 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric typedef struct ValueProfNode * PtrToNodeT; 36*0b57cec5SDimitry Andric typedef struct ValueProfNode { 37*0b57cec5SDimitry Andric #define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Initializer) Type Name; 38*0b57cec5SDimitry Andric #include "InstrProfData.inc" 39*0b57cec5SDimitry Andric } ValueProfNode; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric /*! 42*0b57cec5SDimitry Andric * \brief Get number of bytes necessary to pad the argument to eight 43*0b57cec5SDimitry Andric * byte boundary. 44*0b57cec5SDimitry Andric */ 45*0b57cec5SDimitry Andric uint8_t __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric /*! 48*0b57cec5SDimitry Andric * \brief Get required size for profile buffer. 49*0b57cec5SDimitry Andric */ 50*0b57cec5SDimitry Andric uint64_t __llvm_profile_get_size_for_buffer(void); 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric /*! 53*0b57cec5SDimitry Andric * \brief Write instrumentation data to the given buffer. 54*0b57cec5SDimitry Andric * 55*0b57cec5SDimitry Andric * \pre \c Buffer is the start of a buffer at least as big as \a 56*0b57cec5SDimitry Andric * __llvm_profile_get_size_for_buffer(). 57*0b57cec5SDimitry Andric */ 58*0b57cec5SDimitry Andric int __llvm_profile_write_buffer(char *Buffer); 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric const __llvm_profile_data *__llvm_profile_begin_data(void); 61*0b57cec5SDimitry Andric const __llvm_profile_data *__llvm_profile_end_data(void); 62*0b57cec5SDimitry Andric const char *__llvm_profile_begin_names(void); 63*0b57cec5SDimitry Andric const char *__llvm_profile_end_names(void); 64*0b57cec5SDimitry Andric uint64_t *__llvm_profile_begin_counters(void); 65*0b57cec5SDimitry Andric uint64_t *__llvm_profile_end_counters(void); 66*0b57cec5SDimitry Andric ValueProfNode *__llvm_profile_begin_vnodes(); 67*0b57cec5SDimitry Andric ValueProfNode *__llvm_profile_end_vnodes(); 68*0b57cec5SDimitry Andric uint32_t *__llvm_profile_begin_orderfile(); 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric /*! 71*0b57cec5SDimitry Andric * \brief Clear profile counters to zero. 72*0b57cec5SDimitry Andric * 73*0b57cec5SDimitry Andric */ 74*0b57cec5SDimitry Andric void __llvm_profile_reset_counters(void); 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric /*! 77*0b57cec5SDimitry Andric * \brief Merge profile data from buffer. 78*0b57cec5SDimitry Andric * 79*0b57cec5SDimitry Andric * Read profile data form buffer \p Profile and merge with 80*0b57cec5SDimitry Andric * in-process profile counters. The client is expected to 81*0b57cec5SDimitry Andric * have checked or already knows the profile data in the 82*0b57cec5SDimitry Andric * buffer matches the in-process counter structure before 83*0b57cec5SDimitry Andric * calling it. 84*0b57cec5SDimitry Andric */ 85*0b57cec5SDimitry Andric void __llvm_profile_merge_from_buffer(const char *Profile, uint64_t Size); 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric /*! \brief Check if profile in buffer matches the current binary. 88*0b57cec5SDimitry Andric * 89*0b57cec5SDimitry Andric * Returns 0 (success) if the profile data in buffer \p Profile with size 90*0b57cec5SDimitry Andric * \p Size was generated by the same binary and therefore matches 91*0b57cec5SDimitry Andric * structurally the in-process counters. If the profile data in buffer is 92*0b57cec5SDimitry Andric * not compatible, the interface returns 1 (failure). 93*0b57cec5SDimitry Andric */ 94*0b57cec5SDimitry Andric int __llvm_profile_check_compatibility(const char *Profile, 95*0b57cec5SDimitry Andric uint64_t Size); 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric /*! 98*0b57cec5SDimitry Andric * \brief Counts the number of times a target value is seen. 99*0b57cec5SDimitry Andric * 100*0b57cec5SDimitry Andric * Records the target value for the CounterIndex if not seen before. Otherwise, 101*0b57cec5SDimitry Andric * increments the counter associated w/ the target value. 102*0b57cec5SDimitry Andric * void __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, 103*0b57cec5SDimitry Andric * uint32_t CounterIndex); 104*0b57cec5SDimitry Andric */ 105*0b57cec5SDimitry Andric void INSTR_PROF_VALUE_PROF_FUNC( 106*0b57cec5SDimitry Andric #define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType) ArgType ArgName 107*0b57cec5SDimitry Andric #include "InstrProfData.inc" 108*0b57cec5SDimitry Andric ); 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric void __llvm_profile_instrument_target_value(uint64_t TargetValue, void *Data, 111*0b57cec5SDimitry Andric uint32_t CounterIndex, 112*0b57cec5SDimitry Andric uint64_t CounterValue); 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric /*! 115*0b57cec5SDimitry Andric * \brief Write instrumentation data to the current file. 116*0b57cec5SDimitry Andric * 117*0b57cec5SDimitry Andric * Writes to the file with the last name given to \a * 118*0b57cec5SDimitry Andric * __llvm_profile_set_filename(), 119*0b57cec5SDimitry Andric * or if it hasn't been called, the \c LLVM_PROFILE_FILE environment variable, 120*0b57cec5SDimitry Andric * or if that's not set, the last name set to INSTR_PROF_PROFILE_NAME_VAR, 121*0b57cec5SDimitry Andric * or if that's not set, \c "default.profraw". 122*0b57cec5SDimitry Andric */ 123*0b57cec5SDimitry Andric int __llvm_profile_write_file(void); 124*0b57cec5SDimitry Andric 125*0b57cec5SDimitry Andric int __llvm_orderfile_write_file(void); 126*0b57cec5SDimitry Andric /*! 127*0b57cec5SDimitry Andric * \brief this is a wrapper interface to \c __llvm_profile_write_file. 128*0b57cec5SDimitry Andric * After this interface is invoked, a arleady dumped flag will be set 129*0b57cec5SDimitry Andric * so that profile won't be dumped again during program exit. 130*0b57cec5SDimitry Andric * Invocation of interface __llvm_profile_reset_counters will clear 131*0b57cec5SDimitry Andric * the flag. This interface is designed to be used to collect profile 132*0b57cec5SDimitry Andric * data from user selected hot regions. The use model is 133*0b57cec5SDimitry Andric * __llvm_profile_reset_counters(); 134*0b57cec5SDimitry Andric * ... hot region 1 135*0b57cec5SDimitry Andric * __llvm_profile_dump(); 136*0b57cec5SDimitry Andric * .. some other code 137*0b57cec5SDimitry Andric * __llvm_profile_reset_counters(); 138*0b57cec5SDimitry Andric * ... hot region 2 139*0b57cec5SDimitry Andric * __llvm_profile_dump(); 140*0b57cec5SDimitry Andric * 141*0b57cec5SDimitry Andric * It is expected that on-line profile merging is on with \c %m specifier 142*0b57cec5SDimitry Andric * used in profile filename . If merging is not turned on, user is expected 143*0b57cec5SDimitry Andric * to invoke __llvm_profile_set_filename to specify different profile names 144*0b57cec5SDimitry Andric * for different regions before dumping to avoid profile write clobbering. 145*0b57cec5SDimitry Andric */ 146*0b57cec5SDimitry Andric int __llvm_profile_dump(void); 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric int __llvm_orderfile_dump(void); 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric /*! 151*0b57cec5SDimitry Andric * \brief Set the filename for writing instrumentation data. 152*0b57cec5SDimitry Andric * 153*0b57cec5SDimitry Andric * Sets the filename to be used for subsequent calls to 154*0b57cec5SDimitry Andric * \a __llvm_profile_write_file(). 155*0b57cec5SDimitry Andric * 156*0b57cec5SDimitry Andric * \c Name is not copied, so it must remain valid. Passing NULL resets the 157*0b57cec5SDimitry Andric * filename logic to the default behaviour. 158*0b57cec5SDimitry Andric */ 159*0b57cec5SDimitry Andric void __llvm_profile_set_filename(const char *Name); 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric /*! 162*0b57cec5SDimitry Andric * \brief Set the FILE object for writing instrumentation data. 163*0b57cec5SDimitry Andric * 164*0b57cec5SDimitry Andric * Sets the FILE object to be used for subsequent calls to 165*0b57cec5SDimitry Andric * \a __llvm_profile_write_file(). The profile file name set by environment 166*0b57cec5SDimitry Andric * variable, command-line option, or calls to \a __llvm_profile_set_filename 167*0b57cec5SDimitry Andric * will be ignored. 168*0b57cec5SDimitry Andric * 169*0b57cec5SDimitry Andric * \c File will not be closed after a call to \a __llvm_profile_write_file() but 170*0b57cec5SDimitry Andric * it may be flushed. Passing NULL restores default behavior. 171*0b57cec5SDimitry Andric * 172*0b57cec5SDimitry Andric * If \c EnableMerge is nonzero, the runtime will always merge profiling data 173*0b57cec5SDimitry Andric * with the contents of the profiling file. If EnableMerge is zero, the runtime 174*0b57cec5SDimitry Andric * may still merge the data if it would have merged for another reason (for 175*0b57cec5SDimitry Andric * example, because of a %m specifier in the file name). 176*0b57cec5SDimitry Andric */ 177*0b57cec5SDimitry Andric void __llvm_profile_set_file_object(FILE *File, int EnableMerge); 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric /*! \brief Register to write instrumentation data to file at exit. */ 180*0b57cec5SDimitry Andric int __llvm_profile_register_write_file_atexit(void); 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric /*! \brief Initialize file handling. */ 183*0b57cec5SDimitry Andric void __llvm_profile_initialize_file(void); 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric /*! 186*0b57cec5SDimitry Andric * \brief Return path prefix (excluding the base filename) of the profile data. 187*0b57cec5SDimitry Andric * This is useful for users using \c -fprofile-generate=./path_prefix who do 188*0b57cec5SDimitry Andric * not care about the default raw profile name. It is also useful to collect 189*0b57cec5SDimitry Andric * more than more profile data files dumped in the same directory (Online 190*0b57cec5SDimitry Andric * merge mode is turned on for instrumented programs with shared libs). 191*0b57cec5SDimitry Andric * Side-effect: this API call will invoke malloc with dynamic memory allocation. 192*0b57cec5SDimitry Andric */ 193*0b57cec5SDimitry Andric const char *__llvm_profile_get_path_prefix(); 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric /*! 196*0b57cec5SDimitry Andric * \brief Return filename (including path) of the profile data. Note that if the 197*0b57cec5SDimitry Andric * user calls __llvm_profile_set_filename later after invoking this interface, 198*0b57cec5SDimitry Andric * the actual file name may differ from what is returned here. 199*0b57cec5SDimitry Andric * Side-effect: this API call will invoke malloc with dynamic memory allocation. 200*0b57cec5SDimitry Andric */ 201*0b57cec5SDimitry Andric const char *__llvm_profile_get_filename(); 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric /*! \brief Get the magic token for the file format. */ 204*0b57cec5SDimitry Andric uint64_t __llvm_profile_get_magic(void); 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric /*! \brief Get the version of the file format. */ 207*0b57cec5SDimitry Andric uint64_t __llvm_profile_get_version(void); 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric /*! \brief Get the number of entries in the profile data section. */ 210*0b57cec5SDimitry Andric uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, 211*0b57cec5SDimitry Andric const __llvm_profile_data *End); 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric /*! 214*0b57cec5SDimitry Andric * \brief Set the flag that profile data has been dumped to the file. 215*0b57cec5SDimitry Andric * This is useful for users to disable dumping profile data to the file for 216*0b57cec5SDimitry Andric * certain processes in case the processes don't have permission to write to 217*0b57cec5SDimitry Andric * the disks, and trying to do so would result in side effects such as crashes. 218*0b57cec5SDimitry Andric */ 219*0b57cec5SDimitry Andric void __llvm_profile_set_dumped(); 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric /*! 222*0b57cec5SDimitry Andric * This variable is defined in InstrProfilingRuntime.cc as a hidden 223*0b57cec5SDimitry Andric * symbol. Its main purpose is to enable profile runtime user to 224*0b57cec5SDimitry Andric * bypass runtime initialization code -- if the client code explicitly 225*0b57cec5SDimitry Andric * define this variable, then InstProfileRuntime.o won't be linked in. 226*0b57cec5SDimitry Andric * Note that this variable's visibility needs to be hidden so that the 227*0b57cec5SDimitry Andric * definition of this variable in an instrumented shared library won't 228*0b57cec5SDimitry Andric * affect runtime initialization decision of the main program. 229*0b57cec5SDimitry Andric * __llvm_profile_profile_runtime. */ 230*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY extern int INSTR_PROF_PROFILE_RUNTIME_VAR; 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric /*! 233*0b57cec5SDimitry Andric * This variable is defined in InstrProfiling.c. Its main purpose is to 234*0b57cec5SDimitry Andric * encode the raw profile version value and other format related information 235*0b57cec5SDimitry Andric * such as whether the profile is from IR based instrumentation. The variable 236*0b57cec5SDimitry Andric * is defined as weak so that compiler can emit an overriding definition 237*0b57cec5SDimitry Andric * depending on user option. Since we don't support mixing FE and IR based 238*0b57cec5SDimitry Andric * data in the same raw profile data file (in other words, shared libs and 239*0b57cec5SDimitry Andric * main program are expected to be instrumented in the same way), there is 240*0b57cec5SDimitry Andric * no need for this variable to be hidden. 241*0b57cec5SDimitry Andric */ 242*0b57cec5SDimitry Andric extern uint64_t INSTR_PROF_RAW_VERSION_VAR; /* __llvm_profile_raw_version */ 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric /*! 245*0b57cec5SDimitry Andric * This variable is a weak symbol defined in InstrProfiling.c. It allows 246*0b57cec5SDimitry Andric * compiler instrumentation to provide overriding definition with value 247*0b57cec5SDimitry Andric * from compiler command line. This variable has default visibility. 248*0b57cec5SDimitry Andric */ 249*0b57cec5SDimitry Andric extern char INSTR_PROF_PROFILE_NAME_VAR[1]; /* __llvm_profile_filename. */ 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric #endif /* PROFILE_INSTRPROFILING_H_ */ 252