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