[compiler-rt] r204079 - PGO: Statically generate data structures

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Mar 17 15:28:06 PDT 2014


I see

#include <stdio.h>
#include <stdlib.h>

at the top of the file.  Also, it compiles without warnings for me (and it works for me).

Maybe fputc isn’t portable?  r204084 switches to putc.  Maybe it’s more portable?

On Mar 17, 2014, at 3:22 PM, Kevin Enderby <enderby at apple.com> wrote:

> Hi Duncan,
> 
> Could you please take a look at your change.  David thinks you may have for an include.
> 
> Thanks, your current build czar,
> Kev
> 
> On Mar 17, 2014, at 3:17 PM, David Dean <david_dean at apple.com> wrote:
> 
>> Hi Kevin,
>> 	It looks like Duncan forgot an include to me:
>> 
>> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/Sources/clang/src/projects/compiler-rt/lib/profile/PGOProfiling.c:84:5: error: implicit declaration of function 'fputc' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
>>   fputc(Data->Name[I], OutputFile);
>>   ^
>> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/BuildRecords/clang-9999.99_install/Objects/x86_64/Release/bin/clang -fPIC -I/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/Sources/clang/src/projects/compiler-rt/lib -I/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/Sources/clang/src/projects/compiler-rt/include -arch armv7m -Wall -Oz -fomit-frame-pointer -ffreestanding -static -mfloat-abi=soft -c -o /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/BuildRecords/clang-9999.99_install/Objects/x86_64/tools/clang/runtime/compiler-rt/clang_macho_embedded/soft_static/armv7m/SubDir.lib__builtins/addsf3.o /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.apple-clang-nobootstrap-R_master/clang.roots/Sources/clang/src/projects/compiler-rt/lib/builtins/addsf3.c
>> 1 error generated.
> 
> On Mar 17, 2014, at 2:18 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> 
>> Author: dexonsmith
>> Date: Mon Mar 17 16:18:24 2014
>> New Revision: 204079
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=204079&view=rev
>> Log:
>> PGO: Statically generate data structures
>> 
>> In instrumentation-based profiling, we need a set of data structures to
>> represent the counters.  Previously, these were built up during static
>> initialization.  Now, they're shoved into a specially-named section so
>> that they show up as an array.
>> 
>> As a consequence of the reorganizing symbols, instrumentation data
>> structures for linkonce functions are now correctly coalesced.
>> 
>> This is the first step in a larger project to minimize runtime overhead
>> and dependencies in instrumentation-based profilng.  The larger picture
>> includes removing all initialization overhead and making the dependency
>> on libc optional.
>> 
>> <rdar://problem/15943240>
>> 
>> Modified:
>>   compiler-rt/trunk/lib/profile/PGOProfiling.c
>> 
>> Modified: compiler-rt/trunk/lib/profile/PGOProfiling.c
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/PGOProfiling.c?rev=204079&r1=204078&r2=204079&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/profile/PGOProfiling.c (original)
>> +++ compiler-rt/trunk/lib/profile/PGOProfiling.c Mon Mar 17 16:18:24 2014
>> @@ -32,68 +32,100 @@ typedef unsigned int uint32_t;
>> typedef unsigned long long uint64_t;
>> #endif
>> 
>> -static FILE *OutputFile = NULL;
>> -
>> -/*
>> - * A list of functions to write out the data.
>> +typedef struct __ProfileData {
>> +  const uint32_t NameSize;
>> +  const uint32_t NumCounters;
>> +  const char *const Name;
>> +  const uint64_t *const Counters;
>> +} __ProfileData;
>> +
>> +/* TODO: Calculate these with linker magic. */
>> +static __ProfileData *First = NULL;
>> +static __ProfileData *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.
>> */
>> -typedef void (*writeout_fn)();
>> +void __llvm_pgo_register_function(void *Data_) {
>> +  /* TODO: Only emit this function if we can't use linker magic. */
>> +  __ProfileData *Data = (__ProfileData*)Data_;
>> +  if (!First || Data < First)
>> +    First = Data;
>> +  if (!Final || Data > Final)
>> +    Final = Data;
>> +}
>> 
>> -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 first instrumentation record. */
>> +static __ProfileData *getFirst() {
>> +  /* TODO: Use extern + linker magic instead of a static variable. */
>> +  return First;
>> }
>> 
>> -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;
>> -  }
>> +/*! \brief Get the last instrumentation record. */
>> +static __ProfileData *getLast() {
>> +  /* TODO: Use extern + linker magic instead of a static variable. */
>> +  return Final + 1;
>> }
>> 
>> -void llvm_pgo_writeout_files() {
>> -  const char *OutputName = getenv("LLVM_PROFILE_FILE");
>> -  if (OutputName == NULL || OutputName[0] == '\0')
>> -    OutputName = "default.profdata";
>> +/* TODO: void __llvm_pgo_get_size_for_buffer(void);  */
>> +/* TODO: void __llvm_pgo_write_buffer(char *Buffer); */
>> +
>> +static void writeFunction(FILE *OutputFile, const __ProfileData *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, " %u\n", Data->NumCounters);
>> +  for (I = 0; I < Data->NumCounters; ++I)
>> +    fprintf(OutputFile, "%" PRIu64 "\n", Data->Counters[I]);
>> +  fprintf(OutputFile, "\n");
>> +}
>> +
>> +/*! \brief Write instrumentation data to the given file. */
>> +void __llvm_pgo_write_file(const char *OutputName) {
>> +  /* TODO: Requires libc: move to separate translation unit. */
>> +  __ProfileData *I, *E;
>> +  FILE *OutputFile;
>> +  if (!OutputName || !OutputName[0])
>> +    return;
>>  OutputFile = fopen(OutputName, "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);
>> -  }
>> +  /* 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);
>> 
>>  fclose(OutputFile);
>> }
>> 
>> -void llvm_pgo_init(writeout_fn wfn) {
>> -  static int atexit_ran = 0;
>> -
>> -  if (wfn)
>> -    llvm_pgo_register_writeout_function(wfn);
>> +/*! \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);
>> +}
>> 
>> -  if (atexit_ran == 0) {
>> -    atexit_ran = 1;
>> -    atexit(llvm_pgo_writeout_files);
>> +/*!
>> + * \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 (!HasBeenRegistered) {
>> +    HasBeenRegistered = 1;
>> +    atexit(__llvm_pgo_write_default_file);
>>  }
>> }
>> +
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 





More information about the llvm-commits mailing list