summaryrefslogtreecommitdiff
path: root/lib/profile/InstrProfiling.c
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-03-19 22:10:27 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-03-19 22:10:27 +0000
commitc88e530b0591224669d6d2760448b5dbf4e5d7a2 (patch)
treea82e5cedd08de60406afbc8699757eb072923947 /lib/profile/InstrProfiling.c
parent1520c1f8caaa1e7ee2febad549025db123031311 (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.c70
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);
+}
+