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-exception |
6 | |* |
7 | \*===----------------------------------------------------------------------===*/ |
8 | |
9 | // Note: This is linked into the Darwin kernel, and must remain compatible |
10 | // 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_DATA |
21 | #include "profile/InstrProfData.inc" |
22 | |
23 | static uint32_t __llvm_profile_global_timestamp = 1; |
24 | |
25 | COMPILER_RT_VISIBILITY |
26 | void INSTR_PROF_PROFILE_SET_TIMESTAMP(uint64_t *Probe) { |
27 | if (*Probe == 0 || *Probe == (uint64_t)-1) |
28 | *Probe = __llvm_profile_global_timestamp++; |
29 | } |
30 | |
31 | COMPILER_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 | |
36 | COMPILER_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 it |
41 | * the result a multiple of 8. |
42 | */ |
43 | COMPILER_RT_VISIBILITY uint8_t |
44 | __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) { |
45 | return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t)); |
46 | } |
47 | |
48 | COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) { |
49 | return INSTR_PROF_RAW_VERSION_VAR; |
50 | } |
51 | |
52 | COMPILER_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(s: I, c: ResetValue, n: E - I); |
62 | |
63 | I = __llvm_profile_begin_bitmap(); |
64 | E = __llvm_profile_end_bitmap(); |
65 | memset(s: I, c: 0x0, n: 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 |