<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/58598>58598</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Freestanding profiling APIs do not support IR-based instrumentation
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
justincady
</td>
</tr>
</table>
<pre>
The profiling runtime APIs for freestanding environments do not consider value profiling data. Specifically, after a bit of investigation, I believe that:
- `__llvm_profile_get_size_for_buffer` does not consider the size of the value data
- `__llvm_profile_write_buffer` does not gather and write the value data into the given buffer
Here is a reproducer, adapted from `compiler-rt/test/profile/Inputs/instrprof-value-prof-real.c`:
```
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int __llvm_profile_runtime = 0;
uint64_t __llvm_profile_get_size_for_buffer(void);
int __llvm_profile_write_buffer(char *);
#define DEF_FUNC(x) \
void x() {}
#define DEF_2_FUNCS(x) DEF_FUNC(x##_1) DEF_FUNC(x##_2)
#define DEF_4_FUNCS(x) DEF_2_FUNCS(x##_1) DEF_2_FUNCS(x##_2)
#define DEF_8_FUNCS(x) DEF_4_FUNCS(x##_1) DEF_4_FUNCS(x##_2)
#define DEF_16_FUNCS(x) DEF_8_FUNCS(x##_1) DEF_8_FUNCS(x##_2)
#define DEF_32_FUNCS(x) DEF_16_FUNCS(x##_1) DEF_16_FUNCS(x##_2)
#define DEF_64_FUNCS(x) DEF_32_FUNCS(x##_1) DEF_32_FUNCS(x##_2)
#define DEF_128_FUNCS(x) DEF_64_FUNCS(x##_1) DEF_64_FUNCS(x##_2)
#define DEF_256_FUNCS(x) DEF_128_FUNCS(x##_1) DEF_128_FUNCS(x##_2)
#define DEF_512_FUNCS(x) DEF_256_FUNCS(x##_1) DEF_256_FUNCS(x##_2)
#define FUNC_ADDR(x) &x,
#define FUNC_2_ADDRS(x) FUNC_ADDR(x##_1) FUNC_ADDR(x##_2)
#define FUNC_4_ADDRS(x) FUNC_2_ADDRS(x##_1) FUNC_2_ADDRS(x##_2)
#define FUNC_8_ADDRS(x) FUNC_4_ADDRS(x##_1) FUNC_4_ADDRS(x##_2)
#define FUNC_16_ADDRS(x) FUNC_8_ADDRS(x##_1) FUNC_8_ADDRS(x##_2)
#define FUNC_32_ADDRS(x) FUNC_16_ADDRS(x##_1) FUNC_16_ADDRS(x##_2)
#define FUNC_64_ADDRS(x) FUNC_32_ADDRS(x##_1) FUNC_32_ADDRS(x##_2)
#define FUNC_128_ADDRS(x) FUNC_64_ADDRS(x##_1) FUNC_64_ADDRS(x##_2)
#define FUNC_256_ADDRS(x) FUNC_128_ADDRS(x##_1) FUNC_128_ADDRS(x##_2)
#define FUNC_512_ADDRS(x) FUNC_256_ADDRS(x##_1) FUNC_256_ADDRS(x##_2)
DEF_512_FUNCS(foo)
void *CalleeAddrs[] = {FUNC_512_ADDRS(foo)};
typedef void (*FPT)(void);
FPT getFunc(int I) { return CalleeAddrs[I]; }
int dumpBuffer(const char *FileN, const char *Buffer, uint64_t Size) {
FILE *File = fopen(FileN, "w");
if (!File)
return 1;
if (fwrite(Buffer, 1, Size, File) != Size)
return 1;
return fclose(File);
}
#define MaxSize 50000
int main(int argc, const char *argv[]) {
static __attribute__((aligned(sizeof(uint64_t)))) char Buffer[MaxSize];
uint64_t Size = __llvm_profile_get_size_for_buffer();
if (Size > MaxSize)
return 1;
int I;
for (I = 0; I < 512; I++) {
FPT Fp = getFunc(I);
int J;
for (J = 0; J < 1000 - I; J++)
Fp();
Fp = getFunc(511 - I);
for (J = 0; J < 2000 - I; J++)
Fp();
}
if (__llvm_profile_write_buffer(Buffer))
return 1;
return dumpBuffer(argv[1], Buffer, Size);
}
```
Using front-end instrumentation with the buffer-based APIs works correctly:
```
$ clang -fuse-ld=lld -fprofile-instr-generate instrprof-value-prof-real.c
$ ./a.out out.profraw
$ llvm-profdata show out.profraw
Instrumentation level: Front-end
Total functions: 515
Maximum function count: 2489
Maximum internal block count: 893184
$
```
But IR instrumentation does not:
```
$ clang -fuse-ld=lld -fprofile-generate instrprof-value-prof-real.c
$ ./a.out out.profraw
$ llvm-profdata show out.profraw
error: out.profraw: truncated profile data
$
```
I don't know if the solution is a second set of APIs that _do_ incorporate the additional data correctly or another approach would be preferred.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9WFuvmzgQ_jXkxUoUbgl5yMNJcqJNtVtVvTwjAyZxSzCyTU7P_vodm1sAw3ZVaY8oAWb8zfibcT3jiCXv-683ggrOUprR_Ip4mUt6J-jl00WglHGUckKExHmipCR_UM7yO8mlQAlDOZMoZrmgCeHogbPyGSrBEq_Ql4LENKUxzrJ3yzkinErQxSiiErEU0fwB8PSKJWW5kl9QRDJKHgTJG5aW-2KtT9a6vi-RtVmHYZY97mFliIRXIkNB_yYheBtGZZoSDkrgHRF9_yRMVCkqs-q58ld5OQ3-xqkkJlRw-KbmkSdI6wwQYV6S6W9X-iA5qhGepvIH4QRRAUxwAtaSMga54ifBhSQJ8M7uyqGY3QvwhC-5tJyzBLLgp3YPni55UUoBDzQXkqvvS-3FUj9ygrNVDCgDHtWX6qpeHZfmcVYmBFnuUUiItVzdLPd1SszmpBmNnsX6DoBoQG2TaZZ7QuDfoVIsQXPjhSNtU5Sd4MFoYjm7drTBTC-CThDfMEeW8_I8qp1HQlKaE3R6PYfnbx-PoP4T9NBv_Fn-sUJHSPmKAC9QkNb2YG1PJsOONv2lsd33xYUrtCe-O2pOBkRvjNgz0gcdi6ZwgzGuN407Fk3h2psxcDANPBZNAbsGbvvG-sgG2RT0xkCyO8OyQTZJh2MgejPDtEE2he34Bq4HBgecGIRT6L5tIHxgcpB8BuET-sCG0gxfTqfPDb7lbOD3aNRztGbrymBs54ZJYJqg1vMMoD1DA9yxbBI6MEB7M9Bj2SQ05PUYO5jBHssmsV0Tz32DA3CDcBJ9YyLcnWPcIJzmxTGRvplj3SCchFfJbeDGmWPeJJ00oNabIR_9OfZN0uGKG67llLFWQ-9qsJ8eob4j5CVJuLD8g-Wf9L4O29zIs3o07H79_Ve-FwRmg2pE2CZfzp--KtXxPl_dQYygLjiXeQw6au-_1Hsr1FSy5Dnqe3UBtwACdTtvWzQk5b04tDUCVIxQN9aVwhmqiI-qMut_brSPqC1ZvkB90mzu9aZ_vvz52oBoRlJWEKhzgxbVcpw3-Pc8O4RoWjFgn3WVt2u-o2Zi9kg51YUOPHSO2epWOXVENRKo2sqP2tdZ4PpTGmdMkNrnXhT6PHbZ-Bf-qfCRv4a_juQ7pnkdKMyv8ZhT-PqosmdAIzQgksZQ2mEpOY1KqOhCTVCAM3rNCSRHoKpDlsJDEw-dOvVVmaip8Q-1g1U-PM8B9aOpQ_ZLlagpfjXCa8PHPN_tWJ3HHZZqwgDs0hbKSD0eEawp_WI5B331CIPMg8VxLvSgbo1c-m5Wxj70vtTmPnTmPmhzNoQSLbVnMKKx2Y0Di8WAhydnho74tq3BBu5MGXf-u3E0XOZNVOb7g2b17H4tWLWg999HncW2TuMj6tZjkwPj9TNox_T9m1BNNLSBuVwSaDN1g1eq1lv3yuiNypvuMCvflxEW0Dbqvv2N8R8C1hbnJJbQdv9L8-ehOMNga5mWgiyzBMjPsgRea46W2vTySnLCMbS6c61mC7mCnhSvWAldfilXSoXjt06sYqAH6m5Z3NjbWO8ymHFGHiSDyaBzQ0ql95VJnKEUMkupCaXh234lg6VH7-W9lQIr0HcqFccLdn0dWAyE5wAVZSz-0WkGO9cOvNb3mZgdYLqXz6NQNacGvx2I_z0EhHPGFQfPEniF6eUxVucUtWtP5yjzFF2ADdgFthL9yMEirc5iBMtKTZU-EREE9oUEfvQRkU5pdRiEwoSFMHVI7IJpGtRQnCRUDYW46Ym0aY-YOp9h1TlNAX7i-AZLowRGI3VORWDVcJKsFmRvbzab7doPbHuR7N1k5-7wQlKZkf35-firO9vSPtUHYKIswB0V-HoNDsK_KHm2v0lZqMyEkMB1hbVbRquY3eFFxaH-UeH4Ds6r8xwhSqIOdvzA3wWL234dpKntb0nkRhviblMv9RK83aXRduN7O8dZZDgimdirDdRxcgLcKghVW_inBd07a8ex145vu7At71Y-9pM09gigeHiXbCxvTWCDzlbKjxXj1wXfa5ei8ipAmFEhRSfEQqiNl-yr_XqBS3ljfP-9FBIChJP3hba-197_A0cp0S4">