[llvm-commits] [compiler-rt] r144865 - in /compiler-rt/trunk/lib: Makefile.mk profile/ profile/GCDAProfiling.c profile/Makefile.mk

Daniel Dunbar daniel at zuster.org
Wed Nov 16 16:12:10 PST 2011


Author: ddunbar
Date: Wed Nov 16 18:12:10 2011
New Revision: 144865

URL: http://llvm.org/viewvc/llvm-project?rev=144865&view=rev
Log:
lib: Import GCDA profiling support from LLVM.
 - I'm in the process of moving this here but it will live in both places until
   the ancilliary support is ready.
 - Currently unused.

Added:
    compiler-rt/trunk/lib/profile/
    compiler-rt/trunk/lib/profile/GCDAProfiling.c
    compiler-rt/trunk/lib/profile/Makefile.mk
      - copied, changed from r144845, compiler-rt/trunk/lib/Makefile.mk
Modified:
    compiler-rt/trunk/lib/Makefile.mk

Modified: compiler-rt/trunk/lib/Makefile.mk
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/Makefile.mk?rev=144865&r1=144864&r2=144865&view=diff
==============================================================================
--- compiler-rt/trunk/lib/Makefile.mk (original)
+++ compiler-rt/trunk/lib/Makefile.mk Wed Nov 16 18:12:10 2011
@@ -7,8 +7,15 @@
 #
 #===------------------------------------------------------------------------===#
 
-SubDirs := i386 ppc x86_64 arm
+SubDirs :=
 
+# Add arch specific optimized implementations.
+SubDirs += i386 ppc x86_64 arm
+
+# Add other submodules.
+SubDirs += profile
+
+# Define the variables for this specific directory.
 Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
 ObjNames := $(Sources:%.c=%.o)
 Implementation := Generic

Added: compiler-rt/trunk/lib/profile/GCDAProfiling.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/GCDAProfiling.c?rev=144865&view=auto
==============================================================================
--- compiler-rt/trunk/lib/profile/GCDAProfiling.c (added)
+++ compiler-rt/trunk/lib/profile/GCDAProfiling.c Wed Nov 16 18:12:10 2011
@@ -0,0 +1,200 @@
+/*===- GCDAProfiling.c - Support library for GCDA file emission -----------===*\
+|*
+|*                     The LLVM Compiler Infrastructure
+|*
+|* This file is distributed under the University of Illinois Open Source
+|* License. See LICENSE.TXT for details.
+|* 
+|*===----------------------------------------------------------------------===*|
+|* 
+|* This file implements the call back routines for the gcov profiling
+|* instrumentation pass. Link against this library when running code through
+|* the -insert-gcov-profiling LLVM pass.
+|*
+|* We emit files in a corrupt version of GCOV's "gcda" file format. These files
+|* are only close enough that LCOV will happily parse them. Anything that lcov
+|* ignores is missing.
+|*
+|* TODO: gcov is multi-process safe by having each exit open the existing file
+|* and append to it. We'd like to achieve that and be thread-safe too.
+|*
+\*===----------------------------------------------------------------------===*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef _WIN32
+#include <direct.h>
+#endif
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned int uint64_t;
+#endif
+
+/* #define DEBUG_GCDAPROFILING */
+
+/*
+ * --- GCOV file format I/O primitives ---
+ */
+
+static FILE *output_file = NULL;
+
+static void write_int32(uint32_t i) {
+  fwrite(&i, 4, 1, output_file);
+}
+
+static void write_int64(uint64_t i) {
+  uint32_t lo, hi;
+  lo = i >>  0;
+  hi = i >> 32;
+
+  write_int32(lo);
+  write_int32(hi);
+}
+
+static uint32_t length_of_string(const char *s) {
+  return (strlen(s) / 4) + 1;
+}
+
+static void write_string(const char *s) {
+  uint32_t len = length_of_string(s);
+  write_int32(len);
+  fwrite(s, strlen(s), 1, output_file);
+  fwrite("\0\0\0\0", 4 - (strlen(s) % 4), 1, output_file);
+}
+
+static char *mangle_filename(const char *orig_filename) {
+  /* TODO: handle GCOV_PREFIX_STRIP */
+  const char *prefix;
+  char *filename = 0;
+
+  prefix = getenv("GCOV_PREFIX");
+
+  if (!prefix)
+    return strdup(orig_filename);
+
+  filename = malloc(strlen(prefix) + 1 + strlen(orig_filename) + 1);
+  strcpy(filename, prefix);
+  strcat(filename, "/");
+  strcat(filename, orig_filename);
+
+  return filename;
+}
+
+static void recursive_mkdir(const char *filename) {
+  char *pathname;
+  int i, e;
+
+  for (i = 1, e = strlen(filename); i != e; ++i) {
+    if (filename[i] == '/') {
+      pathname = malloc(i + 1);
+      strncpy(pathname, filename, i);
+      pathname[i] = '\0';
+#ifdef _WIN32
+      _mkdir(pathname);
+#else
+      mkdir(pathname, 0750);  /* some of these will fail, ignore it. */
+#endif
+      free(pathname);
+    }
+  }
+}
+
+/*
+ * --- LLVM line counter API ---
+ */
+
+/* A file in this case is a translation unit. Each .o file built with line
+ * profiling enabled will emit to a different file. Only one file may be
+ * started at a time.
+ */
+void llvm_gcda_start_file(const char *orig_filename) {
+  char *filename;
+  filename = mangle_filename(orig_filename);
+  recursive_mkdir(filename);
+  output_file = fopen(filename, "wb");
+
+  /* gcda file, version 404*, stamp LLVM. */
+#ifdef __APPLE__
+  fwrite("adcg*204MVLL", 12, 1, output_file);
+#else
+  fwrite("adcg*404MVLL", 12, 1, output_file);
+#endif
+
+#ifdef DEBUG_GCDAPROFILING
+  printf("llvmgcda: [%s]\n", orig_filename);
+#endif
+
+  free(filename);
+}
+
+/* Given an array of pointers to counters (counters), increment the n-th one,
+ * where we're also given a pointer to n (predecessor).
+ */
+void llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
+                                          uint64_t **counters) {
+  uint64_t *counter;
+  uint32_t pred;
+
+  pred = *predecessor;
+  if (pred == 0xffffffff)
+    return;
+  counter = counters[pred];
+
+  /* Don't crash if the pred# is out of sync. This can happen due to threads,
+     or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */
+  if (counter)
+    ++*counter;
+#ifdef DEBUG_GCDAPROFILING
+  else
+    printf("llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
+           state_table_row, *predecessor);
+#endif
+}
+
+void llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
+#ifdef DEBUG_GCDAPROFILING
+  printf("llvmgcda: function id=%x\n", ident);
+#endif
+
+  /* function tag */  
+  fwrite("\0\0\0\1", 4, 1, output_file);
+  write_int32(3 + 1 + length_of_string(function_name));
+  write_int32(ident);
+  write_int32(0);
+  write_int32(0);
+  write_string(function_name);
+}
+
+void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
+  uint32_t i;
+  /* counter #1 (arcs) tag */
+  fwrite("\0\0\xa1\1", 4, 1, output_file);
+  write_int32(num_counters * 2);
+  for (i = 0; i < num_counters; ++i) {
+    write_int64(counters[i]);
+  }
+
+#ifdef DEBUG_GCDAPROFILING
+  printf("llvmgcda:   %u arcs\n", num_counters);
+  for (i = 0; i < num_counters; ++i) {
+    printf("llvmgcda:   %llu\n", (unsigned long long)counters[i]);
+  }
+#endif
+}
+
+void llvm_gcda_end_file() {
+  /* Write out EOF record. */
+  fwrite("\0\0\0\0\0\0\0\0", 8, 1, output_file);
+  fclose(output_file);
+  output_file = NULL;
+
+#ifdef DEBUG_GCDAPROFILING
+  printf("llvmgcda: -----\n");
+#endif
+}

Copied: compiler-rt/trunk/lib/profile/Makefile.mk (from r144845, compiler-rt/trunk/lib/Makefile.mk)
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/Makefile.mk?p2=compiler-rt/trunk/lib/profile/Makefile.mk&p1=compiler-rt/trunk/lib/Makefile.mk&r1=144845&r2=144865&rev=144865&view=diff
==============================================================================
--- compiler-rt/trunk/lib/Makefile.mk (original)
+++ compiler-rt/trunk/lib/profile/Makefile.mk Wed Nov 16 18:12:10 2011
@@ -1,4 +1,4 @@
-#===- lib/Makefile.mk --------------------------------------*- Makefile -*--===#
+#===- lib/profile/Makefile.mk ------------------------------*- Makefile -*--===#
 #
 #                     The LLVM Compiler Infrastructure
 #
@@ -7,7 +7,7 @@
 #
 #===------------------------------------------------------------------------===#
 
-SubDirs := i386 ppc x86_64 arm
+SubDirs :=
 
 Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file)))
 ObjNames := $(Sources:%.c=%.o)





More information about the llvm-commits mailing list