1*0b57cec5SDimitry Andric /*===- InstrProfiling.c - 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 #include <limits.h> 10*0b57cec5SDimitry Andric #include <stdio.h> 11*0b57cec5SDimitry Andric #include <stdlib.h> 12*0b57cec5SDimitry Andric #include <string.h> 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "InstrProfiling.h" 15*0b57cec5SDimitry Andric #include "InstrProfilingInternal.h" 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #define INSTR_PROF_VALUE_PROF_DATA 18*0b57cec5SDimitry Andric #include "InstrProfData.inc" 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric COMPILER_RT_WEAK uint64_t INSTR_PROF_RAW_VERSION_VAR = INSTR_PROF_RAW_VERSION; 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) { 24*0b57cec5SDimitry Andric return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64) 25*0b57cec5SDimitry Andric : (INSTR_PROF_RAW_MAGIC_32); 26*0b57cec5SDimitry Andric } 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric static unsigned ProfileDumped = 0; 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY unsigned lprofProfileDumped() { 31*0b57cec5SDimitry Andric return ProfileDumped; 32*0b57cec5SDimitry Andric } 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY void lprofSetProfileDumped() { 35*0b57cec5SDimitry Andric ProfileDumped = 1; 36*0b57cec5SDimitry Andric } 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY void __llvm_profile_set_dumped() { 39*0b57cec5SDimitry Andric lprofSetProfileDumped(); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric /* Return the number of bytes needed to add to SizeInBytes to make it 43*0b57cec5SDimitry Andric * the result a multiple of 8. 44*0b57cec5SDimitry Andric */ 45*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY uint8_t 46*0b57cec5SDimitry Andric __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) { 47*0b57cec5SDimitry Andric return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t)); 48*0b57cec5SDimitry Andric } 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) { 51*0b57cec5SDimitry Andric return __llvm_profile_raw_version; 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) { 55*0b57cec5SDimitry Andric uint64_t *I = __llvm_profile_begin_counters(); 56*0b57cec5SDimitry Andric uint64_t *E = __llvm_profile_end_counters(); 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric memset(I, 0, sizeof(uint64_t) * (E - I)); 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); 61*0b57cec5SDimitry Andric const __llvm_profile_data *DataEnd = __llvm_profile_end_data(); 62*0b57cec5SDimitry Andric const __llvm_profile_data *DI; 63*0b57cec5SDimitry Andric for (DI = DataBegin; DI < DataEnd; ++DI) { 64*0b57cec5SDimitry Andric uint64_t CurrentVSiteCount = 0; 65*0b57cec5SDimitry Andric uint32_t VKI, i; 66*0b57cec5SDimitry Andric if (!DI->Values) 67*0b57cec5SDimitry Andric continue; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric ValueProfNode **ValueCounters = (ValueProfNode **)DI->Values; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI) 72*0b57cec5SDimitry Andric CurrentVSiteCount += DI->NumValueSites[VKI]; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric for (i = 0; i < CurrentVSiteCount; ++i) { 75*0b57cec5SDimitry Andric ValueProfNode *CurrentVNode = ValueCounters[i]; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric while (CurrentVNode) { 78*0b57cec5SDimitry Andric CurrentVNode->Count = 0; 79*0b57cec5SDimitry Andric CurrentVNode = CurrentVNode->Next; 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric } 82*0b57cec5SDimitry Andric } 83*0b57cec5SDimitry Andric ProfileDumped = 0; 84*0b57cec5SDimitry Andric } 85