summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-03-17 23:28:41 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-03-17 23:28:41 +0000
commitede3c3836ba6803968a00fd966d2af11bb4e2cfc (patch)
treee8f2247c53ccf931602c52966b25e5b11f2c9eb3 /lib
parent11d768d949ad791b680f9f5a2b3ef368caf330e9 (diff)
Revert r204079, r204083 and r204084 "PGO: Statically generate data structures"
Buildbots are having trouble finding fputc(), and I can't figure out why. Reverting to investigate. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@204088 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/profile/PGOProfiling.c128
1 files changed, 48 insertions, 80 deletions
diff --git a/lib/profile/PGOProfiling.c b/lib/profile/PGOProfiling.c
index 1a17243c9..986fd8459 100644
--- a/lib/profile/PGOProfiling.c
+++ b/lib/profile/PGOProfiling.c
@@ -32,100 +32,68 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#endif
-typedef struct __llvm_pgo_data {
- const uint32_t NameSize;
- const uint32_t NumCounters;
- const char *const Name;
- const uint64_t *const Counters;
-} __llvm_pgo_data;
-
-/* 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;
-}
+static FILE *OutputFile = NULL;
-/*! \brief Get the first instrumentation record. */
-static __llvm_pgo_data *getFirst() {
- /* TODO: Use extern + linker magic instead of a static variable. */
- return First;
+/*
+ * 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, "%" PRIu64 "\n", Counters[i]);
+ fprintf(OutputFile, "\n");
}
-/*! \brief Get the last instrumentation record. */
-static __llvm_pgo_data *getLast() {
- /* TODO: Use extern + linker magic instead of a static variable. */
- return Final + 1;
-}
+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;
-/* TODO: void __llvm_pgo_get_size_for_buffer(void); */
-/* TODO: void __llvm_pgo_write_buffer(char *Buffer); */
-
-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)
- putc(Data->Name[I], OutputFile);
- fprintf(OutputFile, " %u\n", Data->NumCounters);
- for (I = 0; I < Data->NumCounters; ++I)
- fprintf(OutputFile, "%" PRIu64 "\n", Data->Counters[I]);
- fprintf(OutputFile, "\n");
+ if (!writeout_fn_head) {
+ writeout_fn_head = writeout_fn_tail = new_node;
+ } else {
+ writeout_fn_tail->next = new_node;
+ writeout_fn_tail = new_node;
+ }
}
-/*! \brief Write instrumentation data to the given file. */
-void __llvm_pgo_write_file(const char *OutputName) {
- /* TODO: Requires libc: move to separate translation unit. */
- __llvm_pgo_data *I, *E;
- FILE *OutputFile;
- if (!OutputName || !OutputName[0])
- return;
+void llvm_pgo_writeout_files() {
+ const char *OutputName = getenv("LLVM_PROFILE_FILE");
+ if (OutputName == NULL || OutputName[0] == '\0')
+ OutputName = "default.profdata";
OutputFile = fopen(OutputName, "w");
if (!OutputFile) return;
- /* TODO: mmap file to buffer of size __llvm_pgo_get_size_for_buffer() and
- * call __llvm_pgo_write_buffer().
- */
- for (I = getFirst(), E = getLast(); I != E; ++I)
- writeFunction(OutputFile, I);
+ 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);
}
-/*! \brief Write instrumentation data to the default file. */
-void __llvm_pgo_write_default_file() {
- /* TODO: Requires libc: move to separate translation unit. */
- const char *OutputName = getenv("LLVM_PROFILE_FILE");
- if (OutputName == NULL || OutputName[0] == '\0')
- OutputName = "default.profdata";
- __llvm_pgo_write_file(OutputName);
-}
+void llvm_pgo_init(writeout_fn wfn) {
+ static int atexit_ran = 0;
-/*!
- * \brief Register to write instrumentation data to the default file at exit.
- */
-void __llvm_pgo_register_write_atexit() {
- /* TODO: Requires libc: move to separate translation unit. */
- static int HasBeenRegistered = 0;
+ if (wfn)
+ llvm_pgo_register_writeout_function(wfn);
- if (!HasBeenRegistered) {
- HasBeenRegistered = 1;
- atexit(__llvm_pgo_write_default_file);
+ if (atexit_ran == 0) {
+ atexit_ran = 1;
+ atexit(llvm_pgo_writeout_files);
}
}
-