xref: /minix3/sys/external/bsd/compiler_rt/dist/lib/profile/PGOProfiling.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*===- PGOProfiling.c - Support library for PGO instrumentation -----------===*\
2*0a6a1f1dSLionel Sambuc |*
3*0a6a1f1dSLionel Sambuc |*                     The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc |*
5*0a6a1f1dSLionel Sambuc |* This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc |* License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc |*
8*0a6a1f1dSLionel Sambuc \*===----------------------------------------------------------------------===*/
9*0a6a1f1dSLionel Sambuc 
10*0a6a1f1dSLionel Sambuc #include <inttypes.h>
11*0a6a1f1dSLionel Sambuc #include <stdio.h>
12*0a6a1f1dSLionel Sambuc #include <stdlib.h>
13*0a6a1f1dSLionel Sambuc 
14*0a6a1f1dSLionel Sambuc #ifndef _MSC_VER
15*0a6a1f1dSLionel Sambuc #include <stdint.h>
16*0a6a1f1dSLionel Sambuc #else
17*0a6a1f1dSLionel Sambuc typedef unsigned int uint32_t;
18*0a6a1f1dSLionel Sambuc typedef unsigned int uint64_t;
19*0a6a1f1dSLionel Sambuc #endif
20*0a6a1f1dSLionel Sambuc 
21*0a6a1f1dSLionel Sambuc static FILE *OutputFile = NULL;
22*0a6a1f1dSLionel Sambuc 
23*0a6a1f1dSLionel Sambuc /*
24*0a6a1f1dSLionel Sambuc  * A list of functions to write out the data.
25*0a6a1f1dSLionel Sambuc  */
26*0a6a1f1dSLionel Sambuc typedef void (*writeout_fn)();
27*0a6a1f1dSLionel Sambuc 
28*0a6a1f1dSLionel Sambuc struct writeout_fn_node {
29*0a6a1f1dSLionel Sambuc   writeout_fn fn;
30*0a6a1f1dSLionel Sambuc   struct writeout_fn_node *next;
31*0a6a1f1dSLionel Sambuc };
32*0a6a1f1dSLionel Sambuc 
33*0a6a1f1dSLionel Sambuc static struct writeout_fn_node *writeout_fn_head = NULL;
34*0a6a1f1dSLionel Sambuc static struct writeout_fn_node *writeout_fn_tail = NULL;
35*0a6a1f1dSLionel Sambuc 
llvm_pgo_emit(const char * MangledName,uint32_t NumCounters,uint64_t * Counters)36*0a6a1f1dSLionel Sambuc void llvm_pgo_emit(const char *MangledName, uint32_t NumCounters,
37*0a6a1f1dSLionel Sambuc                    uint64_t *Counters) {
38*0a6a1f1dSLionel Sambuc   uint32_t i;
39*0a6a1f1dSLionel Sambuc   fprintf(OutputFile, "%s %u\n", MangledName, NumCounters);
40*0a6a1f1dSLionel Sambuc   for (i = 0; i < NumCounters; ++i)
41*0a6a1f1dSLionel Sambuc     fprintf(OutputFile, "%" PRIu64 "\n", Counters[i]);
42*0a6a1f1dSLionel Sambuc   fprintf(OutputFile, "\n");
43*0a6a1f1dSLionel Sambuc }
44*0a6a1f1dSLionel Sambuc 
llvm_pgo_register_writeout_function(writeout_fn fn)45*0a6a1f1dSLionel Sambuc void llvm_pgo_register_writeout_function(writeout_fn fn) {
46*0a6a1f1dSLionel Sambuc   struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node));
47*0a6a1f1dSLionel Sambuc   new_node->fn = fn;
48*0a6a1f1dSLionel Sambuc   new_node->next = NULL;
49*0a6a1f1dSLionel Sambuc 
50*0a6a1f1dSLionel Sambuc   if (!writeout_fn_head) {
51*0a6a1f1dSLionel Sambuc     writeout_fn_head = writeout_fn_tail = new_node;
52*0a6a1f1dSLionel Sambuc   } else {
53*0a6a1f1dSLionel Sambuc     writeout_fn_tail->next = new_node;
54*0a6a1f1dSLionel Sambuc     writeout_fn_tail = new_node;
55*0a6a1f1dSLionel Sambuc   }
56*0a6a1f1dSLionel Sambuc }
57*0a6a1f1dSLionel Sambuc 
llvm_pgo_writeout_files()58*0a6a1f1dSLionel Sambuc void llvm_pgo_writeout_files() {
59*0a6a1f1dSLionel Sambuc   const char *OutputName = getenv("LLVM_PROFILE_FILE");
60*0a6a1f1dSLionel Sambuc   if (OutputName == NULL || OutputName[0] == '\0')
61*0a6a1f1dSLionel Sambuc     OutputName = "default.profdata";
62*0a6a1f1dSLionel Sambuc   OutputFile = fopen(OutputName, "w");
63*0a6a1f1dSLionel Sambuc   if (!OutputFile) return;
64*0a6a1f1dSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc   while (writeout_fn_head) {
66*0a6a1f1dSLionel Sambuc     struct writeout_fn_node *node = writeout_fn_head;
67*0a6a1f1dSLionel Sambuc     writeout_fn_head = writeout_fn_head->next;
68*0a6a1f1dSLionel Sambuc     node->fn();
69*0a6a1f1dSLionel Sambuc     free(node);
70*0a6a1f1dSLionel Sambuc   }
71*0a6a1f1dSLionel Sambuc 
72*0a6a1f1dSLionel Sambuc   fclose(OutputFile);
73*0a6a1f1dSLionel Sambuc }
74*0a6a1f1dSLionel Sambuc 
llvm_pgo_init(writeout_fn wfn)75*0a6a1f1dSLionel Sambuc void llvm_pgo_init(writeout_fn wfn) {
76*0a6a1f1dSLionel Sambuc   static int atexit_ran = 0;
77*0a6a1f1dSLionel Sambuc 
78*0a6a1f1dSLionel Sambuc   if (wfn)
79*0a6a1f1dSLionel Sambuc     llvm_pgo_register_writeout_function(wfn);
80*0a6a1f1dSLionel Sambuc 
81*0a6a1f1dSLionel Sambuc   if (atexit_ran == 0) {
82*0a6a1f1dSLionel Sambuc     atexit_ran = 1;
83*0a6a1f1dSLionel Sambuc     atexit(llvm_pgo_writeout_files);
84*0a6a1f1dSLionel Sambuc   }
85*0a6a1f1dSLionel Sambuc }
86