]>
git.proxmox.com Git - rustc.git/blob - src/compiler-rt/lib/profile/InstrProfilingMerge.c
1 /*===- InstrProfilingMerge.c - Profile in-process Merging ---------------===*\
3 |* The LLVM Compiler Infrastructure
5 |* This file is distributed under the University of Illinois Open Source
6 |* License. See LICENSE.TXT for details.
8 |*===----------------------------------------------------------------------===*
9 |* This file defines the API needed for in-process merging of profile data
10 |* stored in memory buffer.
11 \*===---------------------------------------------------------------------===*/
13 #include "InstrProfiling.h"
14 #include "InstrProfilingInternal.h"
15 #include "InstrProfilingUtil.h"
17 #define INSTR_PROF_VALUE_PROF_DATA
18 #include "InstrProfData.inc"
20 COMPILER_RT_WEAK
void (*VPMergeHook
)(ValueProfData
*,
21 __llvm_profile_data
*) = NULL
;
22 COMPILER_RT_VISIBILITY
23 uint64_t lprofGetLoadModuleSignature() {
24 /* A very fast way to compute a module signature. */
25 uint64_t CounterSize
= (uint64_t)(__llvm_profile_end_counters() -
26 __llvm_profile_begin_counters());
27 uint64_t DataSize
= __llvm_profile_get_data_size(__llvm_profile_begin_data(),
28 __llvm_profile_end_data());
30 (uint64_t)(__llvm_profile_end_names() - __llvm_profile_begin_names());
32 (uint64_t)(__llvm_profile_end_vnodes() - __llvm_profile_begin_vnodes());
33 const __llvm_profile_data
*FirstD
= __llvm_profile_begin_data();
35 return (NamesSize
<< 40) + (CounterSize
<< 30) + (DataSize
<< 20) +
36 (NumVnodes
<< 10) + (DataSize
> 0 ? FirstD
->NameRef
: 0);
39 /* Returns 1 if profile is not structurally compatible. */
40 COMPILER_RT_VISIBILITY
41 int __llvm_profile_check_compatibility(const char *ProfileData
,
42 uint64_t ProfileSize
) {
43 /* Check profile header only for now */
44 __llvm_profile_header
*Header
= (__llvm_profile_header
*)ProfileData
;
45 __llvm_profile_data
*SrcDataStart
, *SrcDataEnd
, *SrcData
, *DstData
;
47 (__llvm_profile_data
*)(ProfileData
+ sizeof(__llvm_profile_header
));
48 SrcDataEnd
= SrcDataStart
+ Header
->DataSize
;
50 if (ProfileSize
< sizeof(__llvm_profile_header
))
53 /* Check the header first. */
54 if (Header
->Magic
!= __llvm_profile_get_magic() ||
55 Header
->Version
!= __llvm_profile_get_version() ||
57 __llvm_profile_get_data_size(__llvm_profile_begin_data(),
58 __llvm_profile_end_data()) ||
59 Header
->CountersSize
!= (uint64_t)(__llvm_profile_end_counters() -
60 __llvm_profile_begin_counters()) ||
61 Header
->NamesSize
!= (uint64_t)(__llvm_profile_end_names() -
62 __llvm_profile_begin_names()) ||
63 Header
->ValueKindLast
!= IPVK_Last
)
66 if (ProfileSize
< sizeof(__llvm_profile_header
) +
67 Header
->DataSize
* sizeof(__llvm_profile_data
) +
68 Header
->NamesSize
+ Header
->CountersSize
)
71 for (SrcData
= SrcDataStart
,
72 DstData
= (__llvm_profile_data
*)__llvm_profile_begin_data();
73 SrcData
< SrcDataEnd
; ++SrcData
, ++DstData
) {
74 if (SrcData
->NameRef
!= DstData
->NameRef
||
75 SrcData
->FuncHash
!= DstData
->FuncHash
||
76 SrcData
->NumCounters
!= DstData
->NumCounters
)
84 COMPILER_RT_VISIBILITY
85 void __llvm_profile_merge_from_buffer(const char *ProfileData
,
86 uint64_t ProfileSize
) {
87 __llvm_profile_data
*SrcDataStart
, *SrcDataEnd
, *SrcData
, *DstData
;
88 __llvm_profile_header
*Header
= (__llvm_profile_header
*)ProfileData
;
89 uint64_t *SrcCountersStart
;
90 const char *SrcNameStart
;
91 ValueProfData
*SrcValueProfDataStart
, *SrcValueProfData
;
94 (__llvm_profile_data
*)(ProfileData
+ sizeof(__llvm_profile_header
));
95 SrcDataEnd
= SrcDataStart
+ Header
->DataSize
;
96 SrcCountersStart
= (uint64_t *)SrcDataEnd
;
97 SrcNameStart
= (const char *)(SrcCountersStart
+ Header
->CountersSize
);
98 SrcValueProfDataStart
=
99 (ValueProfData
*)(SrcNameStart
+ Header
->NamesSize
+
100 __llvm_profile_get_num_padding_bytes(
103 for (SrcData
= SrcDataStart
,
104 DstData
= (__llvm_profile_data
*)__llvm_profile_begin_data(),
105 SrcValueProfData
= SrcValueProfDataStart
;
106 SrcData
< SrcDataEnd
; ++SrcData
, ++DstData
) {
107 uint64_t *SrcCounters
;
108 uint64_t *DstCounters
= (uint64_t *)DstData
->CounterPtr
;
109 unsigned I
, NC
, NVK
= 0;
111 NC
= SrcData
->NumCounters
;
112 SrcCounters
= SrcCountersStart
+
113 ((size_t)SrcData
->CounterPtr
- Header
->CountersDelta
) /
115 for (I
= 0; I
< NC
; I
++)
116 DstCounters
[I
] += SrcCounters
[I
];
118 /* Now merge value profile data. */
122 for (I
= 0; I
<= IPVK_Last
; I
++)
123 NVK
+= (SrcData
->NumValueSites
[I
] != 0);
128 VPMergeHook(SrcValueProfData
, DstData
);
129 SrcValueProfData
= (ValueProfData
*)((char *)SrcValueProfData
+
130 SrcValueProfData
->TotalSize
);