diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-03-19 22:10:27 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-03-19 22:10:27 +0000 |
commit | c88e530b0591224669d6d2760448b5dbf4e5d7a2 (patch) | |
tree | a82e5cedd08de60406afbc8699757eb072923947 /lib/profile/InstrProfiling.c | |
parent | 1520c1f8caaa1e7ee2febad549025db123031311 (diff) |
PGO: Splitting implementation files; no functionality change
Split implementation files along a uses-libc/shouldn't-use-libc
boundary.
- InstrProfiling.h is a shared header.
- InstrProfiling.c provides an API to extract profiling data from the
runtime, but avoids the use of libc. Currently this is a lie:
__llvm_pgo_write_buffer() uses `FILE*` and related functions. It
will be updated soon to write to a `char*` buffer instead.
- InstrProfilingExtras.c provides a more convenient API for
interfacing with the profiling runtime, but has logic that does (and
will continue to) use libc.
<rdar://problem/15943240>
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@204268 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile/InstrProfiling.c')
-rw-r--r-- | lib/profile/InstrProfiling.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/profile/InstrProfiling.c b/lib/profile/InstrProfiling.c new file mode 100644 index 000000000..4c9bb7e2b --- /dev/null +++ b/lib/profile/InstrProfiling.c @@ -0,0 +1,70 @@ +/*===- InstrProfiling.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 "InstrProfiling.h" + +/* TODO: Calculate these with linker magic. */ +static __llvm_pgo_data *First = NULL; +static __llvm_pgo_data *Final = NULL; + +/*! + * \brief Register an instrumented function. + * + * Calls to this are emitted by clang with -fprofile-instr-generate. Such + * calls are only required (and only emitted) on targets where we haven't + * implemented linker magic to find the bounds of the section. + * + * For now, that's all targets. + */ +void __llvm_pgo_register_function(void *Data_) { + /* TODO: Only emit this function if we can't use linker magic. */ + __llvm_pgo_data *Data = (__llvm_pgo_data*)Data_; + if (!First || Data < First) + First = Data; + if (!Final || Data > Final) + Final = Data; +} + +/*! \brief Get the first instrumentation record. */ +static __llvm_pgo_data *getFirst() { + /* TODO: Use extern + linker magic instead of a static variable. */ + return First; +} + +/*! \brief Get the last instrumentation record. */ +static __llvm_pgo_data *getLast() { + /* TODO: Use extern + linker magic instead of a static variable. */ + return Final + 1; +} + +/* TODO: void __llvm_pgo_get_size_for_buffer(void); */ + +static void writeFunction(FILE *OutputFile, const __llvm_pgo_data *Data) { + /* TODO: Requires libc: break requirement by writing directly to a buffer + * instead of a FILE stream. + */ + uint32_t I; + for (I = 0; I < Data->NameSize; ++I) + fputc(Data->Name[I], OutputFile); + fprintf(OutputFile, "\n%" PRIu64 "\n%u\n", Data->FuncHash, Data->NumCounters); + for (I = 0; I < Data->NumCounters; ++I) + fprintf(OutputFile, "%" PRIu64 "\n", Data->Counters[I]); + fprintf(OutputFile, "\n"); +} + +void __llvm_pgo_write_buffer(FILE *OutputFile) { + /* TODO: Requires libc: break requirement by taking a char* buffer instead of + * a FILE stream. + */ + __llvm_pgo_data *I, *E; + + for (I = getFirst(), E = getLast(); I != E; ++I) + writeFunction(OutputFile, I); +} + |