[compiler-rt] r328987 - [profile] Fix value profile runtime merging issues

Rong Xu via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 2 09:57:00 PDT 2018


Author: xur
Date: Mon Apr  2 09:57:00 2018
New Revision: 328987

URL: http://llvm.org/viewvc/llvm-project?rev=328987&view=rev
Log:
[profile] Fix value profile runtime merging issues

This patch fixes the following issues:
(1) The strong definition of the merge hook function was not working which
breaks the online value profile merging. This patch removes the weak
attribute of VPMergeHook and assigns the value dynamically.
(2) Truncate the proifle file so that we don't have garbage data at the end of
the file.
(3) Add new __llvm_profile_instrument_target_value() interface to do the value
profile update in batch. This is needed as the original incremental by 1
in __llvm_profile_instrument_target() is too slow for online merge.

Differential Revision: https://reviews.llvm.org/D44847

Added:
    compiler-rt/trunk/test/profile/instrprof-value-merge.c
Modified:
    compiler-rt/trunk/lib/profile/InstrProfiling.h
    compiler-rt/trunk/lib/profile/InstrProfilingFile.c
    compiler-rt/trunk/lib/profile/InstrProfilingMerge.c
    compiler-rt/trunk/lib/profile/InstrProfilingMergeFile.c
    compiler-rt/trunk/lib/profile/InstrProfilingPort.h
    compiler-rt/trunk/lib/profile/InstrProfilingValue.c

Modified: compiler-rt/trunk/lib/profile/InstrProfiling.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfiling.h?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfiling.h (original)
+++ compiler-rt/trunk/lib/profile/InstrProfiling.h Mon Apr  2 09:57:00 2018
@@ -106,6 +106,10 @@ void INSTR_PROF_VALUE_PROF_FUNC(
 #include "InstrProfData.inc"
     );
 
+void __llvm_profile_instrument_target_value(uint64_t TargetValue, void *Data,
+                                            uint32_t CounterIndex,
+                                            uint64_t CounterValue);
+
 /*!
  * \brief Write instrumentation data to the current file.
  *

Modified: compiler-rt/trunk/lib/profile/InstrProfilingFile.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingFile.c?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingFile.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c Mon Apr  2 09:57:00 2018
@@ -183,8 +183,12 @@ static int doProfileMerging(FILE *Profil
 
   /* Now start merging */
   __llvm_profile_merge_from_buffer(ProfileBuffer, ProfileFileSize);
-  (void)munmap(ProfileBuffer, ProfileFileSize);
 
+  // Truncate the file in case merging of value profile did not happend to
+  // prevent from leaving garbage data at the end of the profile file.
+  ftruncate(fileno(ProfileFile), __llvm_profile_get_size_for_buffer());
+
+  (void)munmap(ProfileBuffer, ProfileFileSize);
   *MergeDone = 1;
 
   return 0;
@@ -234,6 +238,7 @@ static int writeFile(const char *OutputN
   FILE *OutputFile;
 
   int MergeDone = 0;
+  VPMergeHook = &lprofMergeValueProfData;
   if (!doMerging())
     OutputFile = fopen(OutputName, "ab");
   else

Modified: compiler-rt/trunk/lib/profile/InstrProfilingMerge.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingMerge.c?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingMerge.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingMerge.c Mon Apr  2 09:57:00 2018
@@ -17,8 +17,9 @@
 #define INSTR_PROF_VALUE_PROF_DATA
 #include "InstrProfData.inc"
 
-COMPILER_RT_WEAK void (*VPMergeHook)(ValueProfData *,
-                                     __llvm_profile_data *) = NULL;
+COMPILER_RT_VISIBILITY
+void (*VPMergeHook)(ValueProfData *, __llvm_profile_data *);
+
 COMPILER_RT_VISIBILITY
 uint64_t lprofGetLoadModuleSignature() {
   /* A very fast way to compute a module signature.  */

Modified: compiler-rt/trunk/lib/profile/InstrProfilingMergeFile.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingMergeFile.c?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingMergeFile.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingMergeFile.c Mon Apr  2 09:57:00 2018
@@ -17,24 +17,24 @@
 #define INSTR_PROF_VALUE_PROF_DATA
 #include "InstrProfData.inc"
 
-void (*VPMergeHook)(ValueProfData *,
-                    __llvm_profile_data *) = &lprofMergeValueProfData;
-
 /* Merge value profile data pointed to by SrcValueProfData into
  * in-memory profile counters pointed by to DstData.  */
 void lprofMergeValueProfData(ValueProfData *SrcValueProfData,
                              __llvm_profile_data *DstData) {
-  unsigned I, S, V, C;
+  unsigned I, S, V, DstIndex = 0;
   InstrProfValueData *VData;
   ValueProfRecord *VR = getFirstValueProfRecord(SrcValueProfData);
   for (I = 0; I < SrcValueProfData->NumValueKinds; I++) {
     VData = getValueProfRecordValueData(VR);
+    unsigned SrcIndex = 0;
     for (S = 0; S < VR->NumValueSites; S++) {
       uint8_t NV = VR->SiteCountArray[S];
       for (V = 0; V < NV; V++) {
-        for (C = 0; C < VData[V].Count; C++)
-          __llvm_profile_instrument_target(VData[V].Value, DstData, S);
+        __llvm_profile_instrument_target_value(VData[SrcIndex].Value, DstData,
+                                               DstIndex, VData[SrcIndex].Count);
+        ++SrcIndex;
       }
+      ++DstIndex;
     }
     VR = getValueProfRecordNext(VR);
   }

Modified: compiler-rt/trunk/lib/profile/InstrProfilingPort.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPort.h?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPort.h (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPort.h Mon Apr  2 09:57:00 2018
@@ -22,12 +22,14 @@
 #define COMPILER_RT_ALLOCA _alloca
 /* Need to include <stdio.h> and <io.h> */
 #define COMPILER_RT_FTRUNCATE(f,l) _chsize(_fileno(f),l)
+#define COMPILER_RT_ALWAYS_INLINE __forceinline
 #elif __GNUC__
 #define COMPILER_RT_ALIGNAS(x) __attribute__((aligned(x)))
 #define COMPILER_RT_VISIBILITY __attribute__((visibility("hidden")))
 #define COMPILER_RT_WEAK __attribute__((weak))
 #define COMPILER_RT_ALLOCA __builtin_alloca
 #define COMPILER_RT_FTRUNCATE(f,l) ftruncate(fileno(f),l)
+#define COMPILER_RT_ALWAYS_INLINE inline __attribute((always_inline))
 #endif
 
 #if defined(__APPLE__)

Modified: compiler-rt/trunk/lib/profile/InstrProfilingValue.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingValue.c?rev=328987&r1=328986&r2=328987&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingValue.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingValue.c Mon Apr  2 09:57:00 2018
@@ -132,13 +132,14 @@ static ValueProfNode *allocateOneNode(__
   return Node;
 }
 
-COMPILER_RT_VISIBILITY void
-__llvm_profile_instrument_target(uint64_t TargetValue, void *Data,
-                                 uint32_t CounterIndex) {
+static COMPILER_RT_ALWAYS_INLINE void
+instrumentTargetValueImpl(uint64_t TargetValue, void *Data,
+                          uint32_t CounterIndex, uint64_t CountValue) {
   __llvm_profile_data *PData = (__llvm_profile_data *)Data;
   if (!PData)
     return;
-
+  if (!CountValue)
+    return;
   if (!PData->Values) {
     if (!allocateValueProfileCounters(PData))
       return;
@@ -153,7 +154,7 @@ __llvm_profile_instrument_target(uint64_
   uint8_t VDataCount = 0;
   while (CurVNode) {
     if (TargetValue == CurVNode->Value) {
-      CurVNode->Count++;
+      CurVNode->Count += CountValue;
       return;
     }
     if (CurVNode->Count < MinCount) {
@@ -194,11 +195,13 @@ __llvm_profile_instrument_target(uint64_
      * the runtime can wipe out more than one lowest count entries
      * to give space for hot targets.
      */
-    if (!MinCountVNode->Count || !(--MinCountVNode->Count)) {
+    if (MinCountVNode->Count <= CountValue) {
       CurVNode = MinCountVNode;
       CurVNode->Value = TargetValue;
-      CurVNode->Count++;
-    }
+      CurVNode->Count = CountValue;
+    } else
+      MinCountVNode->Count -= CountValue;
+
     return;
   }
 
@@ -206,7 +209,7 @@ __llvm_profile_instrument_target(uint64_
   if (!CurVNode)
     return;
   CurVNode->Value = TargetValue;
-  CurVNode->Count++;
+  CurVNode->Count += CountValue;
 
   uint32_t Success = 0;
   if (!ValueCounters[CounterIndex])
@@ -221,6 +224,18 @@ __llvm_profile_instrument_target(uint64_
   }
 }
 
+COMPILER_RT_VISIBILITY void
+__llvm_profile_instrument_target(uint64_t TargetValue, void *Data,
+                                 uint32_t CounterIndex) {
+  instrumentTargetValueImpl(TargetValue, Data, CounterIndex, 1);
+}
+COMPILER_RT_VISIBILITY void
+__llvm_profile_instrument_target_value(uint64_t TargetValue, void *Data,
+                                       uint32_t CounterIndex,
+                                       uint64_t CountValue) {
+  instrumentTargetValueImpl(TargetValue, Data, CounterIndex, CountValue);
+}
+
 /*
  * The target values are partitioned into multiple regions/ranges. There is one
  * contiguous region which is precise -- every value in the range is tracked

Added: compiler-rt/trunk/test/profile/instrprof-value-merge.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/profile/instrprof-value-merge.c?rev=328987&view=auto
==============================================================================
--- compiler-rt/trunk/test/profile/instrprof-value-merge.c (added)
+++ compiler-rt/trunk/test/profile/instrprof-value-merge.c Mon Apr  2 09:57:00 2018
@@ -0,0 +1,79 @@
+// RUN: %clang_pgogen -o %t -O3 %s
+// RUN: rm -rf %t.profdir
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1
+// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1
+// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %s
+
+#include <string.h>
+
+void (*f0)();
+void (*f1)();
+void (*f2)();
+
+char dst[200];
+char src[200];
+volatile int n;
+
+__attribute__((noinline)) void foo() {}
+
+__attribute__((noinline)) void bar() {
+  f0 = foo;
+  f1 = foo;
+  f2 = foo;
+  n = 4;
+}
+int main(int argc, char *argv[]) {
+  int i;
+  bar();
+  if (argc == 1) {
+    f0();
+    for (i = 0; i < 9; i++)
+      f1();
+    for (i = 0; i < 99; i++)
+      f2();
+  } else {
+    memcpy((void *)dst, (void *)src, n);
+    for (i = 0; i < 6; i++)
+      memcpy((void *)(dst + 2), (void *)src, n + 1);
+    for (i = 0; i < 66; i++)
+      memcpy((void *)(dst + 9), (void *)src, n + 2);
+  }
+}
+
+// CHECK: Counters:
+// CHECK:   main:
+// CHECK:     Hash: 0x00030012a7ab6e87
+// CHECK:     Counters: 6
+// CHECK:     Indirect Call Site Count: 3
+// CHECK:     Number of Memory Intrinsics Calls: 3
+// CHECK:     Block counts: [27, 297, 12, 132, 3, 2]
+// CHECK:     Indirect Target Results:
+// CHECK:         [ 0, foo, 3 ]
+// CHECK:         [ 1, foo, 27 ]
+// CHECK:         [ 2, foo, 297 ]
+// CHECK:     Memory Intrinsic Size Results:
+// CHECK:         [ 0, 4, 2 ]
+// CHECK:         [ 1, 5, 12 ]
+// CHECK:         [ 2, 6, 132 ]
+// CHECK: Instrumentation level: IR
+// CHECK: Functions shown: 1
+// CHECK: Total functions: 3
+// CHECK: Maximum function count: 327
+// CHECK: Maximum internal block count: 297
+// CHECK: Statistics for indirect call sites profile:
+// CHECK:   Total number of sites: 3
+// CHECK:   Total number of sites with values: 3
+// CHECK:   Total number of profiled values: 3
+// CHECK:   Value sites histogram:
+// CHECK:         NumTargets, SiteCount
+// CHECK:         1, 3
+// CHECK: Statistics for memory intrinsic calls sizes profile:
+// CHECK:   Total number of sites: 3
+// CHECK:   Total number of sites with values: 3
+// CHECK:   Total number of profiled values: 3
+// CHECK:   Value sites histogram:
+// CHECK:         NumTargets, SiteCount
+// CHECK:         1, 3




More information about the llvm-commits mailing list