[compiler-rt] r355701 - Reland compiler-rt support for order file instrumentation.

Manman Ren via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 8 07:30:56 PST 2019


Author: mren
Date: Fri Mar  8 07:30:56 2019
New Revision: 355701

URL: http://llvm.org/viewvc/llvm-project?rev=355701&view=rev
Log:
Reland compiler-rt support for order file instrumentation.

r355343 was landed and was reverted in r355363 due to build breakage.
This patch adds Linux/Windows support on top of r355343.

In this patch, Darwin should be working with testing case. Linux should be working,
I will enable the testing case in a follwup diff. Windows/Other should be building.
Correct implementation for Other platforms will be added.

Thanks David for reviewing the original diff, helping me with issues on Linux, and
giving suggestions for adding support for Other platforms.


Added:
    compiler-rt/trunk/test/profile/Inputs/instrprof-order-file-2.c
    compiler-rt/trunk/test/profile/Inputs/instrprof-order-file.c
    compiler-rt/trunk/test/profile/instrprof-order-file.test
Modified:
    compiler-rt/trunk/lib/profile/InstrProfData.inc
    compiler-rt/trunk/lib/profile/InstrProfiling.h
    compiler-rt/trunk/lib/profile/InstrProfilingFile.c
    compiler-rt/trunk/lib/profile/InstrProfilingPlatformDarwin.c
    compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c
    compiler-rt/trunk/lib/profile/InstrProfilingPlatformOther.c
    compiler-rt/trunk/lib/profile/InstrProfilingPlatformWindows.c

Modified: compiler-rt/trunk/lib/profile/InstrProfData.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfData.inc?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfData.inc (original)
+++ compiler-rt/trunk/lib/profile/InstrProfData.inc Fri Mar  8 07:30:56 2019
@@ -265,6 +265,9 @@ INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \
 INSTR_PROF_SECT_ENTRY(IPSK_covmap, \
                       INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \
                       INSTR_PROF_COVMAP_COFF, "__LLVM_COV,")
+INSTR_PROF_SECT_ENTRY(IPSK_orderfile, \
+                      INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON), \
+                      INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COFF), "__DATA,")
 
 #undef INSTR_PROF_SECT_ENTRY
 #endif
@@ -656,6 +659,7 @@ serializeValueProfDataFrom(ValueProfReco
 #define INSTR_PROF_VALS_COMMON __llvm_prf_vals
 #define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
 #define INSTR_PROF_COVMAP_COMMON __llvm_covmap
+#define INSTR_PROF_ORDERFILE_COMMON __llvm_orderfile
 /* Windows section names. Because these section names contain dollar characters,
  * they must be quoted.
  */
@@ -665,6 +669,7 @@ serializeValueProfDataFrom(ValueProfReco
 #define INSTR_PROF_VALS_COFF ".lprfv$M"
 #define INSTR_PROF_VNODES_COFF ".lprfnd$M"
 #define INSTR_PROF_COVMAP_COFF ".lcovmap$M"
+#define INSTR_PROF_ORDERFILE_COFF ".lorderfile$M"
 
 #ifdef _WIN32
 /* Runtime section names and name strings.  */
@@ -678,6 +683,7 @@ serializeValueProfDataFrom(ValueProfReco
 /* Value profile nodes section. */
 #define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
 #define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
+#define INSTR_PROF_ORDERFILE_SECT_NAME INSTR_PROF_ORDERFILE_COFF
 #else
 /* Runtime section names and name strings.  */
 #define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON)
@@ -690,8 +696,18 @@ serializeValueProfDataFrom(ValueProfReco
 /* Value profile nodes section. */
 #define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON)
 #define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON)
+/* Order file instrumentation. */
+#define INSTR_PROF_ORDERFILE_SECT_NAME                                         \
+  INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON)
 #endif
 
+#define INSTR_PROF_ORDERFILE_BUFFER_NAME _llvm_order_file_buffer
+#define INSTR_PROF_ORDERFILE_BUFFER_NAME_STR                                   \
+  INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_BUFFER_NAME)
+#define INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME _llvm_order_file_buffer_idx
+#define INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME_STR                               \
+  INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_BUFFER_IDX_NAME)
+
 /* Macros to define start/stop section symbol for a given
  * section on Linux. For instance
  * INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME) will
@@ -725,6 +741,12 @@ typedef struct InstrProfValueData {
 
 #endif /* INSTR_PROF_DATA_INC */
 
+#ifndef INSTR_ORDER_FILE_INC
+// The maximal # of functions: 128*1024 (the buffer size will be 128*4 KB).
+#define INSTR_ORDER_FILE_BUFFER_SIZE 131072
+#define INSTR_ORDER_FILE_BUFFER_BITS 17
+#define INSTR_ORDER_FILE_BUFFER_MASK 0x1ffff
+#endif /* INSTR_ORDER_FILE_INC */
 #else
 #undef INSTR_PROF_DATA_DEFINED
 #endif

Modified: compiler-rt/trunk/lib/profile/InstrProfiling.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfiling.h?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfiling.h (original)
+++ compiler-rt/trunk/lib/profile/InstrProfiling.h Fri Mar  8 07:30:56 2019
@@ -64,6 +64,7 @@ uint64_t *__llvm_profile_begin_counters(
 uint64_t *__llvm_profile_end_counters(void);
 ValueProfNode *__llvm_profile_begin_vnodes();
 ValueProfNode *__llvm_profile_end_vnodes();
+uint32_t *__llvm_profile_begin_orderfile();
 
 /*!
  * \brief Clear profile counters to zero.
@@ -120,6 +121,7 @@ void __llvm_profile_instrument_target_va
  */
 int __llvm_profile_write_file(void);
 
+int __llvm_orderfile_write_file(void);
 /*!
  * \brief this is a wrapper interface to \c __llvm_profile_write_file.
  * After this interface is invoked, a arleady dumped flag will be set
@@ -142,6 +144,8 @@ int __llvm_profile_write_file(void);
  */
 int __llvm_profile_dump(void);
 
+int __llvm_orderfile_dump(void);
+
 /*!
  * \brief Set the filename for writing instrumentation data.
  *

Modified: compiler-rt/trunk/lib/profile/InstrProfilingFile.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingFile.c?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingFile.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c Fri Mar  8 07:30:56 2019
@@ -111,6 +111,15 @@ static uint32_t fileWriter(ProfDataWrite
   return 0;
 }
 
+/* TODO: make buffer size controllable by an internal option, and compiler can pass the size
+   to runtime via a variable. */
+static uint32_t orderFileWriter(FILE *File, const uint32_t *DataStart) {
+  if (fwrite(DataStart, sizeof(uint32_t), INSTR_ORDER_FILE_BUFFER_SIZE, File) !=
+      INSTR_ORDER_FILE_BUFFER_SIZE)
+    return 1;
+  return 0;
+}
+
 static void initFileWriter(ProfDataWriter *This, FILE *File) {
   This->Write = fileWriter;
   This->WriterCtx = File;
@@ -260,6 +269,27 @@ static int writeFile(const char *OutputN
   return RetVal;
 }
 
+/* Write order data to file \c OutputName.  */
+static int writeOrderFile(const char *OutputName) {
+  int RetVal;
+  FILE *OutputFile;
+
+  OutputFile = fopen(OutputName, "w");
+
+  if (!OutputFile) {
+    PROF_WARN("can't open file with mode ab: %s\n", OutputName);
+    return -1;
+  }
+
+  FreeHook = &free;
+  setupIOBuffer();
+  const uint32_t *DataBegin = __llvm_profile_begin_orderfile();
+  RetVal = orderFileWriter(OutputFile, DataBegin);
+
+  fclose(OutputFile);
+  return RetVal;
+}
+
 static void truncateCurrentFile(void) {
   const char *Filename;
   char *FilenameBuf;
@@ -648,6 +678,62 @@ int __llvm_profile_dump(void) {
   return rc;
 }
 
+/* Order file data will be saved in a file with suffx .order. */
+static const char *OrderFileSuffix = ".order";
+
+COMPILER_RT_VISIBILITY
+int __llvm_orderfile_write_file(void) {
+  int rc, Length, LengthBeforeAppend, SuffixLength;
+  const char *Filename;
+  char *FilenameBuf;
+  int PDeathSig = 0;
+
+  SuffixLength = strlen(OrderFileSuffix);
+  Length = getCurFilenameLength() + SuffixLength;
+  FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
+  Filename = getCurFilename(FilenameBuf, 1);
+
+  /* Check the filename. */
+  if (!Filename) {
+    PROF_ERR("Failed to write file : %s\n", "Filename not set");
+    return -1;
+  }
+
+  /* Append order file suffix */
+  LengthBeforeAppend = strlen(Filename);
+  memcpy(FilenameBuf + LengthBeforeAppend, OrderFileSuffix, SuffixLength);
+  FilenameBuf[LengthBeforeAppend + SuffixLength] = '\0';
+
+  /* Check if there is llvm/runtime version mismatch.  */
+  if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) {
+    PROF_ERR("Runtime and instrumentation version mismatch : "
+             "expected %d, but get %d\n",
+             INSTR_PROF_RAW_VERSION,
+             (int)GET_VERSION(__llvm_profile_get_version()));
+    return -1;
+  }
+
+  // Temporarily suspend getting SIGKILL when the parent exits.
+  PDeathSig = lprofSuspendSigKill();
+
+  /* Write order data to the file. */
+  rc = writeOrderFile(Filename);
+  if (rc)
+    PROF_ERR("Failed to write file \"%s\": %s\n", Filename, strerror(errno));
+
+  // Restore SIGKILL.
+  if (PDeathSig == 1)
+    lprofRestoreSigKill();
+
+  return rc;
+}
+
+COMPILER_RT_VISIBILITY
+int __llvm_orderfile_dump(void) {
+  int rc = __llvm_orderfile_write_file();
+  return rc;
+}
+
 static void writeFileWithoutReturn(void) { __llvm_profile_write_file(); }
 
 COMPILER_RT_VISIBILITY

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPlatformDarwin.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPlatformDarwin.c?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPlatformDarwin.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPlatformDarwin.c Fri Mar  8 07:30:56 2019
@@ -27,6 +27,9 @@ extern uint64_t
 COMPILER_RT_VISIBILITY
 extern uint64_t
     CountersEnd __asm("section$end$__DATA$" INSTR_PROF_CNTS_SECT_NAME);
+COMPILER_RT_VISIBILITY
+extern uint32_t
+    OrderFileStart __asm("section$start$__DATA$" INSTR_PROF_ORDERFILE_SECT_NAME);
 
 COMPILER_RT_VISIBILITY
 extern ValueProfNode
@@ -49,6 +52,8 @@ COMPILER_RT_VISIBILITY
 uint64_t *__llvm_profile_begin_counters(void) { return &CountersStart; }
 COMPILER_RT_VISIBILITY
 uint64_t *__llvm_profile_end_counters(void) { return &CountersEnd; }
+COMPILER_RT_VISIBILITY
+uint32_t *__llvm_profile_begin_orderfile(void) { return &OrderFileStart; }
 
 COMPILER_RT_VISIBILITY
 ValueProfNode *__llvm_profile_begin_vnodes(void) {

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPlatformLinux.c Fri Mar  8 07:30:56 2019
@@ -19,6 +19,7 @@
 #define PROF_NAME_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_NAME_COMMON)
 #define PROF_CNTS_START INSTR_PROF_SECT_START(INSTR_PROF_CNTS_COMMON)
 #define PROF_CNTS_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_CNTS_COMMON)
+#define PROF_ORDERFILE_START INSTR_PROF_SECT_START(INSTR_PROF_ORDERFILE_COMMON)
 #define PROF_VNODES_START INSTR_PROF_SECT_START(INSTR_PROF_VNODES_COMMON)
 #define PROF_VNODES_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_VNODES_COMMON)
 
@@ -29,6 +30,7 @@ extern __llvm_profile_data PROF_DATA_STA
 extern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY;
 extern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY;
 extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY;
+extern uint32_t PROF_ORDERFILE_START COMPILER_RT_VISIBILITY;
 extern char PROF_NAME_START COMPILER_RT_VISIBILITY;
 extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY;
 extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY;
@@ -39,6 +41,8 @@ __llvm_profile_data
     __prof_data_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_DATA_SECT_NAME);
 uint64_t
     __prof_cnts_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_CNTS_SECT_NAME);
+uint32_t
+    __prof_orderfile_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_ORDERFILE_SECT_NAME);
 char __prof_nms_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_NAME_SECT_NAME);
 ValueProfNode __prof_vnodes_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_VNODES_SECT_NAME);
 
@@ -62,6 +66,9 @@ COMPILER_RT_VISIBILITY uint64_t *__llvm_
 COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_end_counters(void) {
   return &PROF_CNTS_STOP;
 }
+COMPILER_RT_VISIBILITY uint32_t *__llvm_profile_begin_orderfile(void) {
+  return &PROF_ORDERFILE_START;
+}
 
 COMPILER_RT_VISIBILITY ValueProfNode *
 __llvm_profile_begin_vnodes(void) {

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPlatformOther.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPlatformOther.c?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPlatformOther.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPlatformOther.c Fri Mar  8 07:30:56 2019
@@ -21,6 +21,7 @@ static const char *NamesFirst = NULL;
 static const char *NamesLast = NULL;
 static uint64_t *CountersFirst = NULL;
 static uint64_t *CountersLast = NULL;
+static uint32_t *OrderFileFirst = NULL;
 
 static const void *getMinAddr(const void *A1, const void *A2) {
   return A1 < A2 ? A1 : A2;
@@ -82,6 +83,9 @@ COMPILER_RT_VISIBILITY
 uint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; }
 COMPILER_RT_VISIBILITY
 uint64_t *__llvm_profile_end_counters(void) { return CountersLast; }
+/* TODO: correctly set up OrderFileFirst. */
+COMPILER_RT_VISIBILITY
+uint32_t *__llvm_profile_begin_orderfile(void) { return OrderFileFirst; }
 
 COMPILER_RT_VISIBILITY
 ValueProfNode *__llvm_profile_begin_vnodes(void) {

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPlatformWindows.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPlatformWindows.c?rev=355701&r1=355700&r2=355701&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPlatformWindows.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPlatformWindows.c Fri Mar  8 07:30:56 2019
@@ -29,6 +29,7 @@
 #pragma section(".lprfd$Z", read, write)
 #pragma section(".lprfc$A", read, write)
 #pragma section(".lprfc$Z", read, write)
+#pragma section(".lorderfile$A", read, write)
 #pragma section(".lprfnd$A", read, write)
 #pragma section(".lprfnd$Z", read, write)
 #endif
@@ -41,6 +42,7 @@ const char COMPILER_RT_SECTION(".lprfn$Z
 
 uint64_t COMPILER_RT_SECTION(".lprfc$A") CountersStart;
 uint64_t COMPILER_RT_SECTION(".lprfc$Z") CountersEnd;
+uint32_t COMPILER_RT_SECTION(".lorderfile$A") OrderFileStart;
 
 ValueProfNode COMPILER_RT_SECTION(".lprfnd$A") VNodesStart;
 ValueProfNode COMPILER_RT_SECTION(".lprfnd$Z") VNodesEnd;
@@ -55,6 +57,7 @@ const char *__llvm_profile_end_names(voi
 
 uint64_t *__llvm_profile_begin_counters(void) { return &CountersStart + 1; }
 uint64_t *__llvm_profile_end_counters(void) { return &CountersEnd; }
+uint32_t *__llvm_profile_begin_orderfile(void) { return &OrderFileStart; }
 
 ValueProfNode *__llvm_profile_begin_vnodes(void) { return &VNodesStart + 1; }
 ValueProfNode *__llvm_profile_end_vnodes(void) { return &VNodesEnd; }

Added: compiler-rt/trunk/test/profile/Inputs/instrprof-order-file-2.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/Inputs/instrprof-order-file-2.c?rev=355701&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/Inputs/instrprof-order-file-2.c (added)
+++ compiler-rt/trunk/test/profile/Inputs/instrprof-order-file-2.c Fri Mar  8 07:30:56 2019
@@ -0,0 +1,7 @@
+__attribute__((noinline)) int f(int a) {
+  return a + 1;
+}
+
+__attribute__((noinline)) int g(int a) {
+  return a + 2;
+}

Added: compiler-rt/trunk/test/profile/Inputs/instrprof-order-file.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/Inputs/instrprof-order-file.c?rev=355701&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/Inputs/instrprof-order-file.c (added)
+++ compiler-rt/trunk/test/profile/Inputs/instrprof-order-file.c Fri Mar  8 07:30:56 2019
@@ -0,0 +1,17 @@
+void __llvm_profile_initialize_file(void);
+int __llvm_orderfile_dump(void);
+
+__attribute__((noinline)) int f(int a);
+
+__attribute__((noinline)) int g(int a);
+
+int main(int argc, const char *argv[]) {
+  int a = f(argc);
+  int t = 0;
+  for (int i = 0; i < argc; i++)
+    t += g(a);
+  f(t);
+  __llvm_profile_initialize_file();
+  __llvm_orderfile_dump();
+  return 0;
+}

Added: compiler-rt/trunk/test/profile/instrprof-order-file.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/instrprof-order-file.test?rev=355701&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/instrprof-order-file.test (added)
+++ compiler-rt/trunk/test/profile/instrprof-order-file.test Fri Mar  8 07:30:56 2019
@@ -0,0 +1,17 @@
+// UNSUPPORTED: windows
+// REQUIRES: darwin
+// RUN: rm -rf %t.dir && mkdir -p %t.dir
+// RUN: cd %t.dir
+//
+// RUN: %clang -forder-file-instrumentation -O1 -o %t.2 %S/Inputs/instrprof-order-file-2.c %S/Inputs/instrprof-order-file.c -mllvm -orderfile-write-mapping="mapping.txt"
+// RUN: %run %t.2 ANY
+// RUN: od -h default.profraw.order | FileCheck %s
+// RUN: cat mapping.txt | FileCheck %s --check-prefix=MAPPING
+
+// Make sure we have MD5 for main, then f, then g.
+// CHECK: 0000000      d5fa    e78d    6436    db95    a18f    dd4c    4f75    cc91
+// CHECK: 0000020      f5b2    47ff    6643    b671    0000    0000    0000    0000
+
+// MAPPING: MD5 cc914f75dd4ca18f f
+// MAPPING: MD5 b671664347fff5b2 g
+// MAPPING: MD5 db956436e78dd5fa main




More information about the llvm-commits mailing list