1276789Sdim/*===- InstrProfiling.c - Support library for PGO instrumentation ---------===*\
2276789Sdim|*
3353358Sdim|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim|* See https://llvm.org/LICENSE.txt for license information.
5353358Sdim|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6276789Sdim|*
7276789Sdim\*===----------------------------------------------------------------------===*/
8276789Sdim
9296417Sdim#include <limits.h>
10296417Sdim#include <stdio.h>
11296417Sdim#include <stdlib.h>
12276789Sdim#include <string.h>
13327952Sdim
14327952Sdim#include "InstrProfiling.h"
15327952Sdim#include "InstrProfilingInternal.h"
16327952Sdim
17296417Sdim#define INSTR_PROF_VALUE_PROF_DATA
18360784Sdim#include "profile/InstrProfData.inc"
19276789Sdim
20296417Sdim
21314564SdimCOMPILER_RT_WEAK uint64_t INSTR_PROF_RAW_VERSION_VAR = INSTR_PROF_RAW_VERSION;
22296417Sdim
23296417SdimCOMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) {
24296417Sdim  return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64)
25296417Sdim                                            : (INSTR_PROF_RAW_MAGIC_32);
26276789Sdim}
27276789Sdim
28314564Sdimstatic unsigned ProfileDumped = 0;
29314564Sdim
30314564SdimCOMPILER_RT_VISIBILITY unsigned lprofProfileDumped() {
31314564Sdim  return ProfileDumped;
32314564Sdim}
33314564Sdim
34314564SdimCOMPILER_RT_VISIBILITY void lprofSetProfileDumped() {
35314564Sdim  ProfileDumped = 1;
36314564Sdim}
37314564Sdim
38353358SdimCOMPILER_RT_VISIBILITY void __llvm_profile_set_dumped() {
39353358Sdim  lprofSetProfileDumped();
40353358Sdim}
41353358Sdim
42296417Sdim/* Return the number of bytes needed to add to SizeInBytes to make it
43296417Sdim *   the result a multiple of 8.
44296417Sdim */
45296417SdimCOMPILER_RT_VISIBILITY uint8_t
46296417Sdim__llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) {
47296417Sdim  return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
48276789Sdim}
49276789Sdim
50296417SdimCOMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) {
51296417Sdim  return __llvm_profile_raw_version;
52296417Sdim}
53296417Sdim
54296417SdimCOMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {
55276789Sdim  uint64_t *I = __llvm_profile_begin_counters();
56276789Sdim  uint64_t *E = __llvm_profile_end_counters();
57276789Sdim
58296417Sdim  memset(I, 0, sizeof(uint64_t) * (E - I));
59296417Sdim
60296417Sdim  const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
61296417Sdim  const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
62296417Sdim  const __llvm_profile_data *DI;
63309124Sdim  for (DI = DataBegin; DI < DataEnd; ++DI) {
64296417Sdim    uint64_t CurrentVSiteCount = 0;
65296417Sdim    uint32_t VKI, i;
66296417Sdim    if (!DI->Values)
67296417Sdim      continue;
68296417Sdim
69296417Sdim    ValueProfNode **ValueCounters = (ValueProfNode **)DI->Values;
70296417Sdim
71296417Sdim    for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)
72296417Sdim      CurrentVSiteCount += DI->NumValueSites[VKI];
73296417Sdim
74296417Sdim    for (i = 0; i < CurrentVSiteCount; ++i) {
75296417Sdim      ValueProfNode *CurrentVNode = ValueCounters[i];
76296417Sdim
77296417Sdim      while (CurrentVNode) {
78309124Sdim        CurrentVNode->Count = 0;
79296417Sdim        CurrentVNode = CurrentVNode->Next;
80296417Sdim      }
81296417Sdim    }
82296417Sdim  }
83314564Sdim  ProfileDumped = 0;
84276789Sdim}
85