92 lines · c
1/*===- InstrProfiling.c - Support library for PGO instrumentation ---------===*\2|*3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4|* See https://llvm.org/LICENSE.txt for license information.5|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6|*7\*===----------------------------------------------------------------------===*/8 9// Note: This is linked into the Darwin kernel, and must remain compatible10// with freestanding compilation. See `darwin_add_builtin_libraries`.11 12#include <limits.h>13#include <stdio.h>14#include <stdlib.h>15#include <string.h>16 17#include "InstrProfiling.h"18#include "InstrProfilingInternal.h"19 20#define INSTR_PROF_VALUE_PROF_DATA21#include "profile/InstrProfData.inc"22 23static uint32_t __llvm_profile_global_timestamp = 1;24 25COMPILER_RT_VISIBILITY26void INSTR_PROF_PROFILE_SET_TIMESTAMP(uint64_t *Probe) {27 if (*Probe == 0 || *Probe == (uint64_t)-1)28 *Probe = __llvm_profile_global_timestamp++;29}30 31COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) {32 return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64)33 : (INSTR_PROF_RAW_MAGIC_32);34}35 36COMPILER_RT_VISIBILITY void __llvm_profile_set_dumped(void) {37 lprofSetProfileDumped(1);38}39 40/* Return the number of bytes needed to add to SizeInBytes to make it41 * the result a multiple of 8.42 */43COMPILER_RT_VISIBILITY uint8_t44__llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) {45 return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));46}47 48COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) {49 return INSTR_PROF_RAW_VERSION_VAR;50}51 52COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {53 if (__llvm_profile_get_version() & VARIANT_MASK_TEMPORAL_PROF)54 __llvm_profile_global_timestamp = 1;55 56 char *I = __llvm_profile_begin_counters();57 char *E = __llvm_profile_end_counters();58 59 char ResetValue =60 (__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) ? 0xFF : 0;61 memset(I, ResetValue, E - I);62 63 I = __llvm_profile_begin_bitmap();64 E = __llvm_profile_end_bitmap();65 memset(I, 0x0, E - I);66 67 const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();68 const __llvm_profile_data *DataEnd = __llvm_profile_end_data();69 const __llvm_profile_data *DI;70 for (DI = DataBegin; DI < DataEnd; ++DI) {71 uint64_t CurrentVSiteCount = 0;72 uint32_t VKI, i;73 if (!DI->Values)74 continue;75 76 ValueProfNode **ValueCounters = (ValueProfNode **)DI->Values;77 78 for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)79 CurrentVSiteCount += DI->NumValueSites[VKI];80 81 for (i = 0; i < CurrentVSiteCount; ++i) {82 ValueProfNode *CurrVNode = ValueCounters[i];83 84 while (CurrVNode) {85 CurrVNode->Count = 0;86 CurrVNode = CurrVNode->Next;87 }88 }89 }90 lprofSetProfileDumped(0);91}92