[profile] Support hostname expansion in LLVM_PROFILE_FILE
authorVedant Kumar <vsk@apple.com>
Fri, 29 Jan 2016 23:52:11 +0000 (23:52 +0000)
committerVedant Kumar <vsk@apple.com>
Fri, 29 Jan 2016 23:52:11 +0000 (23:52 +0000)
This patch adds support for expanding "%h" out to the machine hostname
in the LLVM_PROFILE_FILE environment variable.

Patch by Daniel Waters!

Differential Revision: http://reviews.llvm.org/D16371

llvm-svn: 259272

compiler-rt/lib/profile/InstrProfilingFile.c
compiler-rt/lib/profile/InstrProfilingPort.h
compiler-rt/test/profile/instrprof-hostname.c [new file with mode: 0644]

index 1d6dda4..ad8c3a0 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef COMPILER_RT_HAS_UNAME
+#include <sys/utsname.h>
+#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 @@ int getpid(void);
 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 @@ static int setFilenamePossiblyWithPid(const char *Filename) {
 
   /* 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 @@ static int setFilenamePossiblyWithPid(const char *Filename) {
         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 2906071..2efe809 100644 (file)
 
 #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 <windows.h>
diff --git a/compiler-rt/test/profile/instrprof-hostname.c b/compiler-rt/test/profile/instrprof-hostname.c
new file mode 100644 (file)
index 0000000..cb141c9
--- /dev/null
@@ -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}