blob: 505d748f77c57174c7cea1b1cdb04e09a4d109f3 [file] [log] [blame]
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +00001/*===- InstrProfilingFile.c - Write instrumentation to a file -------------===*\
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +00002|*
3|* The LLVM Compiler Infrastructure
4|*
5|* This file is distributed under the University of Illinois Open Source
6|* License. See LICENSE.TXT for details.
7|*
8\*===----------------------------------------------------------------------===*/
9
10#include "InstrProfiling.h"
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000011#include <stdio.h>
12#include <stdlib.h>
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000013#include <string.h>
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000014
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000015static int writeFileWithName(const char *OutputName) {
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000016 int RetVal;
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000017 FILE *OutputFile;
18 if (!OutputName || !OutputName[0])
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000019 return -1;
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000020 OutputFile = fopen(OutputName, "w");
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000021 if (!OutputFile)
22 return -1;
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000023
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000024 RetVal = __llvm_profile_write_buffer(OutputFile);
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000025
26 fclose(OutputFile);
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000027 return RetVal;
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000028}
29
Duncan P. N. Exon Smith54cc0e22014-03-20 19:23:55 +000030static const char *CurrentFilename = NULL;
Duncan P. N. Exon Smith9edbae02014-03-20 20:00:44 +000031void __llvm_profile_set_filename(const char *Filename) {
Duncan P. N. Exon Smith54cc0e22014-03-20 19:23:55 +000032 CurrentFilename = Filename;
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000033}
34
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000035int getpid(void);
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000036int __llvm_profile_write_file(void) {
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000037 char *AllocatedFilename = NULL;
38 int I, J;
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000039 int RetVal;
Duncan P. N. Exon Smith54cc0e22014-03-20 19:23:55 +000040
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000041#define MAX_PID_SIZE 16
42 char PidChars[MAX_PID_SIZE] = { 0 };
43 int PidLength = 0;
44 int NumPids = 0;
45
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000046 /* Get the filename. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000047 const char *Filename = CurrentFilename;
Duncan P. N. Exon Smith54cc0e22014-03-20 19:23:55 +000048#define UPDATE_FILENAME(NextFilename) \
49 if (!Filename || !Filename[0]) Filename = NextFilename
50 UPDATE_FILENAME(getenv("LLVM_PROFILE_FILE"));
51 UPDATE_FILENAME("default.profdata");
52#undef UPDATE_FILENAME
53
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000054 /* Check the filename for "%p", which indicates a pid-substitution. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000055 for (I = 0; Filename[I]; ++I)
56 if (Filename[I] == '%' && Filename[++I] == 'p')
57 if (!NumPids++) {
58 PidLength = snprintf(PidChars, MAX_PID_SIZE, "%d", getpid());
59 if (PidLength <= 0)
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000060 return -1;
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000061 }
62 if (NumPids) {
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000063 /* Allocate enough space for the substituted filename. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000064 AllocatedFilename = (char*)malloc(I + NumPids*(PidLength - 2) + 1);
65 if (!AllocatedFilename)
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000066 return -1;
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000067
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000068 /* Construct the new filename. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000069 for (I = 0, J = 0; Filename[I]; ++I)
70 if (Filename[I] == '%') {
71 if (Filename[++I] == 'p') {
72 memcpy(AllocatedFilename + J, PidChars, PidLength);
73 J += PidLength;
74 }
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000075 /* Drop any unknown substitutions. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000076 } else
77 AllocatedFilename[J++] = Filename[I];
78 AllocatedFilename[J] = 0;
79
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000080 /* Actually use the computed name. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000081 Filename = AllocatedFilename;
82 }
83
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000084 /* Write the file. */
85 RetVal = writeFileWithName(Filename);
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000086
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000087 /* Free the filename. */
Duncan P. N. Exon Smithe5edc882014-03-21 00:27:48 +000088 if (AllocatedFilename)
89 free(AllocatedFilename);
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000090
91 return RetVal;
Duncan P. N. Exon Smith54cc0e22014-03-20 19:23:55 +000092}
93
Duncan P. N. Exon Smith4543aac2014-03-21 00:27:50 +000094static void writeFileWithoutReturn(void) {
95 __llvm_profile_write_file();
96}
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +000097
98int __llvm_profile_register_write_file_atexit(void) {
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +000099 static int HasBeenRegistered = 0;
100
Duncan P. N. Exon Smithbe0a5e12014-03-21 18:29:15 +0000101 if (HasBeenRegistered)
102 return 0;
103
104 HasBeenRegistered = 1;
105 return atexit(writeFileWithoutReturn);
Duncan P. N. Exon Smith8353a262014-03-19 22:10:27 +0000106}