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