18c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/*===- GCDAProfiling.c - Support library for GCDA file emission -----------===*\
28c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
38c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*                     The LLVM Compiler Infrastructure
48c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
58c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* This file is distributed under the University of Illinois Open Source
68c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* License. See LICENSE.TXT for details.
78c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
88c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*===----------------------------------------------------------------------===*|
98c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
108c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* This file implements the call back routines for the gcov profiling
118c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* instrumentation pass. Link against this library when running code through
128c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* the -insert-gcov-profiling LLVM pass.
138c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
148c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* We emit files in a corrupt version of GCOV's "gcda" file format. These files
158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* are only close enough that LCOV will happily parse them. Anything that lcov
168c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* ignores is missing.
178c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* TODO: gcov is multi-process safe by having each exit open the existing file
198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* and append to it. We'd like to achieve that and be thread-safe too.
208c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*
218c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar\*===----------------------------------------------------------------------===*/
228c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
238c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdio.h>
248c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdlib.h>
258c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <string.h>
268c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <sys/stat.h>
278c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <sys/types.h>
288c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef _WIN32
298c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <direct.h>
308c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
318c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
328c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifndef _MSC_VER
338c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdint.h>
348c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#else
358c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbartypedef unsigned int uint32_t;
368c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbartypedef unsigned int uint64_t;
378c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
388c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
398c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* #define DEBUG_GCDAPROFILING */
408c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
418c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/*
428c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * --- GCOV file format I/O primitives ---
438c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */
448c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
458c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic FILE *output_file = NULL;
468c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
478c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic void write_int32(uint32_t i) {
488c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite(&i, 4, 1, output_file);
498c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
508c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
518c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic void write_int64(uint64_t i) {
525a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  uint32_t lo = i >>  0;
535a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  uint32_t hi = i >> 32;
548c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(lo);
558c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(hi);
568c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
578c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
588c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic uint32_t length_of_string(const char *s) {
598c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  return (strlen(s) / 4) + 1;
608c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
618c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
628c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic void write_string(const char *s) {
638c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  uint32_t len = length_of_string(s);
648c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(len);
658c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite(s, strlen(s), 1, output_file);
668c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("\0\0\0\0", 4 - (strlen(s) % 4), 1, output_file);
678c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
688c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
698c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic char *mangle_filename(const char *orig_filename) {
708c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  char *filename = 0;
71906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  int prefix_len = 0;
72ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  int prefix_strip = 0;
73ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  int level = 0;
74ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  const char *fname = orig_filename, *ptr = NULL;
75906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  const char *prefix = getenv("GCOV_PREFIX");
76ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  const char *tmp = getenv("GCOV_PREFIX_STRIP");
778c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
78ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  if (!prefix)
798c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar    return strdup(orig_filename);
808c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
81ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  if (tmp) {
82ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    prefix_strip = atoi(tmp);
83ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling
84ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    /* Negative GCOV_PREFIX_STRIP values are ignored */
85ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    if (prefix_strip < 0)
86ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling      prefix_strip = 0;
87ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  }
88ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling
89906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  prefix_len = strlen(prefix);
90906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  filename = malloc(prefix_len + 1 + strlen(orig_filename) + 1);
918c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  strcpy(filename, prefix);
92ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling
93906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  if (prefix[prefix_len - 1] != '/')
94906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    strcat(filename, "/");
95ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling
96ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  for (ptr = fname + 1; *ptr != '\0' && level < prefix_strip; ++ptr) {
97ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    if (*ptr != '/') continue;
98ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    fname = ptr;
99ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling    ++level;
100ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  }
101ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling
102ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling  strcat(filename, fname);
1038c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1048c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  return filename;
1058c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
1068c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
107906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendlingstatic void recursive_mkdir(char *filename) {
108906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  int i;
1098c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
110906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  for (i = 1; filename[i] != '\0'; ++i) {
1115a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling    if (filename[i] != '/') continue;
112906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    filename[i] = '\0';
1138c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef _WIN32
114906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    _mkdir(filename);
1158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#else
116906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    mkdir(filename, 0755);  /* Some of these will fail, ignore it. */
1178c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
118906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    filename[i] = '/';
1198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  }
1208c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
1218c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1228c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/*
1238c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * --- LLVM line counter API ---
1248c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */
1258c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1268c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* A file in this case is a translation unit. Each .o file built with line
1278c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * profiling enabled will emit to a different file. Only one file may be
1288c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * started at a time.
1298c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */
1308c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_start_file(const char *orig_filename) {
131906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling  char *filename = mangle_filename(orig_filename);
1325a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  output_file = fopen(filename, "w+b");
1335a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling
1345a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  if (!output_file) {
135906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling    recursive_mkdir(filename);
136015b7e06622b7538419d8c158c4c84b781310096Bill Wendling    output_file = fopen(filename, "w+b");
1375a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling    if (!output_file) {
138015b7e06622b7538419d8c158c4c84b781310096Bill Wendling      fprintf(stderr, "profiling:%s: cannot open\n", filename);
139666772c9934fac81d457c74d3eeca381652d0873Bill Wendling      free(filename);
1405a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling      return;
1415a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling    }
1425a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  }
1438c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1448c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  /* gcda file, version 404*, stamp LLVM. */
1458c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef __APPLE__
1468c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("adcg*204MVLL", 12, 1, output_file);
1478c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#else
1488c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("adcg*404MVLL", 12, 1, output_file);
1498c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
1508c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1518c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING
1528c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  printf("llvmgcda: [%s]\n", orig_filename);
1538c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
1548c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1558c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  free(filename);
1568c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
1578c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1588c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* Given an array of pointers to counters (counters), increment the n-th one,
1598c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * where we're also given a pointer to n (predecessor).
1608c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */
1618c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
1628c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar                                          uint64_t **counters) {
1638c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  uint64_t *counter;
1648c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  uint32_t pred;
1658c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1668c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  pred = *predecessor;
1678c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  if (pred == 0xffffffff)
1688c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar    return;
1698c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  counter = counters[pred];
1708c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1718c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  /* Don't crash if the pred# is out of sync. This can happen due to threads,
1728c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar     or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */
1738c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  if (counter)
1748c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar    ++*counter;
1758c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING
1768c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  else
177de47cb8f12474c7c528a84de0ea73c743c33f015Bill Wendling    fprintf(stderr,
178de47cb8f12474c7c528a84de0ea73c743c33f015Bill Wendling            "llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
179de47cb8f12474c7c528a84de0ea73c743c33f015Bill Wendling            state_table_row, *predecessor);
1808c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
1818c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
1828c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1838c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
1848c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING
1858c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  printf("llvmgcda: function id=%x\n", ident);
1868c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
1875a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  if (!output_file) return;
1888c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1898c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  /* function tag */
1908c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("\0\0\0\1", 4, 1, output_file);
1918c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(3 + 1 + length_of_string(function_name));
1928c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(ident);
1938c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(0);
1948c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(0);
1958c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_string(function_name);
1968c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
1978c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
1988c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
1998c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  uint32_t i;
2005a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling
2015a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  /* Counter #1 (arcs) tag */
2025a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  if (!output_file) return;
2038c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("\0\0\xa1\1", 4, 1, output_file);
2048c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  write_int32(num_counters * 2);
2055a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  for (i = 0; i < num_counters; ++i)
2068c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar    write_int64(counters[i]);
2078c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
2088c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING
2098c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  printf("llvmgcda:   %u arcs\n", num_counters);
2105a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  for (i = 0; i < num_counters; ++i)
2118c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar    printf("llvmgcda:   %llu\n", (unsigned long long)counters[i]);
2128c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
2138c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
2148c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
2158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_end_file() {
2168c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  /* Write out EOF record. */
2175a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling  if (!output_file) return;
2188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fwrite("\0\0\0\0\0\0\0\0", 8, 1, output_file);
2198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  fclose(output_file);
2208c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  output_file = NULL;
2218c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar
2228c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING
2238c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar  printf("llvmgcda: -----\n");
2248c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif
2258c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar}
226