Index: compiler-rt/trunk/lib/profile/InstrProfilingFile.c =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingFile.c +++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c @@ -14,9 +14,22 @@ #include #include #include +#ifdef COMPILER_RT_HAS_UNAME +#include +#endif #define UNCONST(ptr) ((void *)(uintptr_t)(ptr)) +#ifdef COMPILER_RT_HAS_UNAME +int GetHostName(char *Name, int Len) { + struct utsname N; + int R; + if (!(R = uname(&N))) + strncpy(Name, N.nodename, Len); + return R; +} +#endif + /* Return 1 if there is an error, otherwise return 0. */ static uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, void **WriterCtx) { @@ -114,9 +127,10 @@ static int setFilenamePossiblyWithPid(const char *Filename) { #define MAX_PID_SIZE 16 char PidChars[MAX_PID_SIZE] = {0}; - int NumPids = 0, PidLength = 0; + int NumPids = 0, PidLength = 0, NumHosts = 0, HostNameLength = 0; char *Allocated; int I, J; + char Hostname[COMPILER_RT_MAX_HOSTLEN]; /* Reset filename on NULL, except with env var which is checked by caller. */ if (!Filename) { @@ -126,19 +140,29 @@ /* Check the filename for "%p", which indicates a pid-substitution. */ for (I = 0; Filename[I]; ++I) - if (Filename[I] == '%' && Filename[++I] == 'p') - if (!NumPids++) { - PidLength = snprintf(PidChars, MAX_PID_SIZE, "%d", getpid()); - if (PidLength <= 0) - return -1; + if (Filename[I] == '%') { + if (Filename[++I] == 'p') { + if (!NumPids++) { + PidLength = snprintf(PidChars, MAX_PID_SIZE, "%d", getpid()); + if (PidLength <= 0) + return -1; + } + } else if (Filename[I] == 'h') { + if (!NumHosts++) + if (COMPILER_RT_GETHOSTNAME(Hostname, COMPILER_RT_MAX_HOSTLEN)) + return -1; + HostNameLength = strlen(Hostname); } - if (!NumPids) { + } + + if (!(NumPids || NumHosts)) { setFilename(Filename, 0); return 0; } /* Allocate enough space for the substituted filename. */ - Allocated = malloc(I + NumPids*(PidLength - 2) + 1); + Allocated = malloc(I + NumPids*(PidLength - 2) + + NumHosts*(HostNameLength - 2) + 1); if (!Allocated) return -1; @@ -149,6 +173,10 @@ memcpy(Allocated + J, PidChars, PidLength); J += PidLength; } + else if (Filename[I] == 'h') { + memcpy(Allocated + J, Hostname, HostNameLength); + J += HostNameLength; + } /* Drop any unknown substitutions. */ } else Allocated[J++] = Filename[I]; Index: compiler-rt/trunk/lib/profile/InstrProfilingPort.h =================================================================== --- compiler-rt/trunk/lib/profile/InstrProfilingPort.h +++ compiler-rt/trunk/lib/profile/InstrProfilingPort.h @@ -22,6 +22,14 @@ #define COMPILER_RT_SECTION(Sect) __attribute__((section(Sect))) +#define COMPILER_RT_MAX_HOSTLEN 128 +#ifdef _MSC_VER +#define COMPILER_RT_GETHOSTNAME(Name, Len) gethostname(Name, Len) +#else +#define COMPILER_RT_GETHOSTNAME(Name, Len) GetHostName(Name, Len) +#define COMPILER_RT_HAS_UNAME 1 +#endif + #if COMPILER_RT_HAS_ATOMICS == 1 #ifdef _MSC_VER #include Index: compiler-rt/trunk/test/profile/instrprof-hostname.c =================================================================== --- compiler-rt/trunk/test/profile/instrprof-hostname.c +++ compiler-rt/trunk/test/profile/instrprof-hostname.c @@ -0,0 +1,13 @@ +// RUN: %clang_profgen -o %t -O3 %s +// RUN: env LLVM_PROFILE_FILE=%h.%t-%h.profraw_%h %run %t +// RUN: llvm-profdata merge -o %t.profdata `uname -n`.%t-`uname -n`.profraw_`uname -n` +// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s +// REQUIRES: shell + +int main(int argc, const char *argv[]) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (argc > 2) + return 1; + return 0; +} +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}