From 65bb804f053208958e882bfaa2c8dcf53e6a18e0 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Mon, 6 Jan 2014 22:27:03 +0000 Subject: [PATCH] profile: Rudimentary suppport for PGO instrumentation This is fairly minimal support for instrumentation based PGO. The data format is inefficient, and the output file name is hardcoded to pgo-data. llvm-svn: 198638 --- compiler-rt/lib/profile/CMakeLists.txt | 3 +- compiler-rt/lib/profile/PGOProfiling.c | 81 +++++++++++++++++++++++++++++++ compiler-rt/make/platform/clang_darwin.mk | 4 +- 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 compiler-rt/lib/profile/PGOProfiling.c diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt index bb4fd9e..c8d004d 100644 --- a/compiler-rt/lib/profile/CMakeLists.txt +++ b/compiler-rt/lib/profile/CMakeLists.txt @@ -1,5 +1,6 @@ set(PROFILE_SOURCES - GCDAProfiling.c) + GCDAProfiling.c + PGOProfiling.c) filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386) diff --git a/compiler-rt/lib/profile/PGOProfiling.c b/compiler-rt/lib/profile/PGOProfiling.c new file mode 100644 index 0000000..5bb216a --- /dev/null +++ b/compiler-rt/lib/profile/PGOProfiling.c @@ -0,0 +1,81 @@ +/*===- PGOProfiling.c - Support library for PGO instrumentation -----------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file is distributed under the University of Illinois Open Source +|* License. See LICENSE.TXT for details. +|* +\*===----------------------------------------------------------------------===*/ + +#include +#include + +#ifndef _MSC_VER +#include +#else +typedef unsigned int uint32_t; +typedef unsigned int uint64_t; +#endif + +static FILE *OutputFile = NULL; + +/* + * A list of functions to write out the data. + */ +typedef void (*writeout_fn)(); + +struct writeout_fn_node { + writeout_fn fn; + struct writeout_fn_node *next; +}; + +static struct writeout_fn_node *writeout_fn_head = NULL; +static struct writeout_fn_node *writeout_fn_tail = NULL; + +void llvm_pgo_emit(const char *MangledName, uint32_t NumCounters, + uint64_t *Counters) { + uint32_t i; + fprintf(OutputFile, "%s %u\n", MangledName, NumCounters); + for (i = 0; i < NumCounters; ++i) + fprintf(OutputFile, "%llu\n", Counters[i]); + fprintf(OutputFile, "\n"); +} + +void llvm_pgo_register_writeout_function(writeout_fn fn) { + struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node)); + new_node->fn = fn; + new_node->next = NULL; + + if (!writeout_fn_head) { + writeout_fn_head = writeout_fn_tail = new_node; + } else { + writeout_fn_tail->next = new_node; + writeout_fn_tail = new_node; + } +} + +void llvm_pgo_writeout_files() { + OutputFile = fopen("pgo-data", "w"); + if (!OutputFile) return; + + while (writeout_fn_head) { + struct writeout_fn_node *node = writeout_fn_head; + writeout_fn_head = writeout_fn_head->next; + node->fn(); + free(node); + } + + fclose(OutputFile); +} + +void llvm_pgo_init(writeout_fn wfn) { + static int atexit_ran = 0; + + if (wfn) + llvm_pgo_register_writeout_function(wfn); + + if (atexit_ran == 0) { + atexit_ran = 1; + atexit(llvm_pgo_writeout_files); + } +} diff --git a/compiler-rt/make/platform/clang_darwin.mk b/compiler-rt/make/platform/clang_darwin.mk index ddb7029..b17edee 100644 --- a/compiler-rt/make/platform/clang_darwin.mk +++ b/compiler-rt/make/platform/clang_darwin.mk @@ -214,8 +214,8 @@ FUNCTIONS.ios.x86_64 := $(FUNCTIONS.ios) \ FUNCTIONS.osx := mulosi4 mulodi4 muloti4 -FUNCTIONS.profile_osx := GCDAProfiling -FUNCTIONS.profile_ios := GCDAProfiling +FUNCTIONS.profile_osx := GCDAProfiling PGOProfiling +FUNCTIONS.profile_ios := GCDAProfiling PGOProfiling FUNCTIONS.asan_osx_dynamic := $(AsanFunctions) $(InterceptionFunctions) \ $(SanitizerCommonFunctions) \ -- 2.7.4